01. Product and System Overview¶
What the product does¶
Browser RAG is a private, fully local RAG workbench in the browser. Users create projects, upload documents, index them with a local embedding model, and ask questions answered by a local LLM with citations. Document bytes and vectors stay on the device; the only expected network use is downloading model weights.
Evidence: README.md, AGENTS.md (“must be able to be run on browser client side entirely”).
Primary users and workflows¶
| User | Workflow |
|---|---|
| Privacy-conscious knowledge worker | Index personal PDFs/notes; ask questions without a cloud RAG API |
| ML/web engineer | Experiment with local embeddings, hybrid search, and small on-device LLMs |
| Demo / portfolio visitor | Use the GitHub Pages build at /browser-rag/ |
Core workflows¶
- Create project — choose embedding model, chunk size/overlap, hybrid/top-K (
src/routes/projects.tsx,src/lib/projects.ts) - Upload & index — extract → chunk → embed → store (
src/routes/documents.tsx→indexDocument) - Load models — embedding + LLM into memory (
SystemInitProvider, chat page) - Ask — rewrite (if multi-turn) → hybrid retrieve → stream answer + citations (
generateRAGAnswer) - Inspect — retrieval debug panel, chunk explorer, history, settings diagnostics
- Backup — export/import PGlite data dir as
.tar.gz
Major subsystems¶
| Subsystem | Responsibility | Entry |
|---|---|---|
| UI shell | Navigation, theme, project switcher | src/components/layout/* |
| System init | Prefs, active project, LLM/embedding load | src/context/system-init-context.tsx |
| RAG | Index, retrieve, orchestrate answers | src/rag/* |
| LLM | Multi-engine load/stream/parse | src/llm/*, src/hooks/use-* |
| Persistence | PGlite schema + file IDB | src/db/*, src/lib/document-files.ts |
| Workers | Off-thread extract/chunk/embed | src/workers/* |
High-level architecture¶
graph TD
classDef default fill:#1e293b,stroke:#38bdf8,stroke-width:2px,color:#f8fafc
classDef highlight fill:#065f46,stroke:#34d399,stroke-width:2px,color:#f0fdf4
classDef warning fill:#78350f,stroke:#fbbf24,stroke-width:2px,color:#fffbeb
Browser["Browser SPA<br/>Vite + React 19"]:::highlight
Pages["GitHub Pages<br/>static dist/"]
IDB1["IndexedDB<br/>PGlite data dir"]
IDB2["IndexedDB<br/>browser-rag-files"]
LS["localStorage<br/>preferences"]
CDN["Weight CDNs<br/>HF / MLC"]:::warning
Pages --> Browser
Browser --> IDB1
Browser --> IDB2
Browser --> LS
Browser -.-> CDN
linkStyle default stroke:#64748b,stroke-width:2px
There is no application backend. Deployment is a static asset host. Persistence is browser storage; model weights may be fetched and cached by the ML libraries.
Primary ask-flow sequence¶
%%{init: {
"theme": "base",
"themeVariables": {
"primaryColor": "#1e293b",
"primaryTextColor": "#f8fafc",
"primaryBorderColor": "#38bdf8",
"lineColor": "#64748b",
"actorBackground": "#1e293b",
"actorBorder": "#38bdf8",
"actorTextColor": "#f8fafc",
"labelBoxBorderColor": "#38bdf8",
"labelBoxBkgColor": "#1e293b",
"labelTextColor": "#f8fafc",
"noteBorderColor": "#fbbf24",
"noteBkgColor": "#78350f",
"noteTextColor": "#fffbeb"
}
}}%%
sequenceDiagram
actor User
participant Chat as Chat Route
participant Orch as generateRAGAnswer
participant LLM as LLM Runtime
participant Ret as retrieveChunks
participant Emb as Embedding Worker
participant DB as PGlite
User->>Chat: Submit question
Chat->>Orch: query + history + handles
alt history present
Orch->>LLM: rewriteQueryForRetrieval
LLM-->>Orch: standalone search query
end
Orch->>Ret: retrievalQuery
Ret->>Emb: embedQuery
Emb-->>Ret: query vector
Ret->>DB: vector <=> + keyword tsquery
Ret-->>Orch: fused citations + debug
Orch->>LLM: stream answer with context
LLM-->>Chat: text_delta / thinking_delta
Chat-->>User: Markdown answer + citations
Key technical bets and tradeoffs¶
| Bet | Upside | Tradeoff |
|---|---|---|
| Everything in-browser | Privacy, no server cost, offline-capable after weights cached | Device memory/GPU limits; large downloads |
| Real Postgres (PGlite) + SQL hybrid search | Familiar SQL, GIN FTS, pgvector ops | WASM DB size; no ANN index yet → scan cost grows |
| Multi-engine LLM adapter | Portability across WebLLM / Transformers / custom kernels | Complexity; uneven feature support |
| Soft project embedding lock | Consistency for vectors | Can still change model via update path; mixed dims risk if misused |
| Static Pages deploy | Simple CI | Harder to set COOP/COEP / caching policy |
Interview soundbite — “What did you build?”¶
Browser RAG is a fully client-side RAG system: PGlite with pgvector in IndexedDB, Transformers.js embeddings in a Web Worker, hybrid vector+keyword search fused with RRF, and a multi-engine local LLM runtime that streams answers with citations and a retrieval debug panel — all without an application server.