Stashly: A Link Memory System That Searches by Meaning, Not Just Title
A browser-extension-first monorepo that scrapes pages, builds embeddings in the background, and uses PostgreSQL plus pgvector to turn saved links into retrievable knowledge.
- Stashly reframes bookmarks as a retrieval problem, so the real product is recall by meaning instead of storage by title.
- Its extension-first capture flow matters because semantic search only feels useful when saving is nearly frictionless.
- The backend pairs asynchronous embedding work with PostgreSQL and pgvector, which keeps the system practical instead of experimental.
- The hybrid search model is the point: vectors help with meaning, but keywords and expansion keep the results grounded.
Saving a link is easy. Finding it three days later is the part that hurts. Stashly is built around that gap, and it treats the problem like memory, not filing.
That is the useful twist. It is not trying to be a prettier bookmark shelf. It is trying to make “I know I saved that somewhere” stop being a dead end.
The bookmark problem Stashly is really solving
Traditional bookmark tools optimize for placement. Put the link in a folder, add a tag, maybe remember the title. Stashly optimizes for recovery. It wants to get you back to a page when your memory is partial, fuzzy, or wrong.
I love working at the intersection of backend engineering and AI — from designing REST APIs to experimenting with RAG pipelines and vector databases.
That framing fits the codebase. The repo is organized as a monorepo with a backend, a web app, and a browser extension, which is exactly what you would build if capture and recall were the whole product.
Why extension-first is the right capture model
The browser extension is not a garnish here. It is the front door. If capture has friction, the semantic layer never gets enough material to become useful.
That matters because memory systems fail when saving becomes a chore. Stashly’s extension-first design keeps the action close to the moment of discovery, which is when people are willing to save the page at all.
The interesting product move is that the extension does not need to solve retrieval in the moment. It only needs to make capture painless. Everything else can happen later.
What happens after you click save
The core pipeline is simple to describe and more interesting to implement. A URL comes in, the backend scrapes it, cleans the text, and sends the content into an embedding job that runs in the background.
The implementation detail that matters is the asynchronous boundary. The API can respond before embedding finishes, so the user gets speed up front and retrieval quality later. That is the right trade-off for a consumer tool.
Why pgvector matters here
Stashly is not using Postgres as passive storage. It uses Postgres as the retrieval engine. That is a subtle but important difference, because it keeps the app data and vector data in the same operational model.
In the schema, embeddings are stored as a 768-dimensional vector, which matches the model output and makes similarity search native to the database. The result is less infrastructure sprawl and fewer moving parts to reason about.
That choice also keeps the stack legible. You do not need a separate vector service just to ask, “Which saved page feels most like this query?”
| Approach | Strength | Weakness | What Stashly does differently |
|---|---|---|---|
| Traditional bookmark manager | Fast to save and easy to organize by folder | Hard to recover when you forget the title or tag | Adds semantic retrieval on top of capture |
| Keyword-only search | Simple and predictable | Breaks on fuzzy memory and technical jargon | Blends keywords with extracted text and vectors |
| Pure vector search | Good at concept matching | Can feel opaque and sometimes overmatch | Keeps semantic search grounded with metadata and query expansion |
The search trick: embeddings plus expansion
This is the heart of the system. Stashly does not rely on vectors alone. It also stores extracted text and keywords, then expands certain search terms so technical shorthand does not disappear into the noise.
That hybrid approach is what makes the product feel practical. Pure vector search can be elegant, but if a user types a niche abbreviation or a memory fragment, keyword signals still matter.
The result is less glamorous than a demo of embeddings and more useful in day-to-day use. The system can match intent without pretending the exact words no longer matter.
What the backend is doing under the hood
The scraper uses Cheerio to strip scripts and styles, then extracts page metadata and body text. That gives the embedding model cleaner input and avoids teaching the system from junk.
The embedding layer is also defensive. It validates dimensions and falls back to alternate models when the primary one is unavailable, which turns an external dependency into something the app can survive.
The monorepo is doing product work, not just code organization
The structure tells you the product shape. `apps/extension` captures. `apps/backend` processes and searches. `apps/web` makes the saved graph visible. That is a user journey, not just a folder tree.
The repo’s layout also says something about ambition. This is not a weekend script glued to a UI. It is an attempt to make capture, enrichment, and retrieval behave like one system.
| Layer | Role in the product | Why it exists |
|---|---|---|
| Extension | Capture at the point of discovery | Reduces friction to nearly zero |
| Backend | Scrape, enrich, index, and search | Turns raw links into retrievable memory |
| Web app | Review and search the library | Makes the saved material usable |
| Database | Store relational data and vectors | Keeps structure and semantic recall together |
What Stashly is really competing with
The obvious comparison is a bookmark manager. The better comparison is a tool that improves recall. Stashly is competing on whether a user can get back to the right page with half a memory and a vague prompt.
That puts it in a different category from simple link storage. The benchmark is not “Can I save this?” The benchmark is “Can I find it when my memory is bad?”
That is a harder problem, and a more interesting one. If Stashly works, the user stops thinking about folders altogether.
Why this design is credible
The strongest thing about the repo is restraint. It uses AI where AI is useful, and conventional software where conventional software is better. Scraping, storage, auth, and search all stay close to standard backend practice.
That is what makes the project feel real. It is not chasing novelty for its own sake. It is using a modern stack to solve an old problem more intelligently.
In the end, Stashly is interesting because it turns link saving into a memory system with a serious retrieval model behind it. That is a small idea with a lot of product surface area.





