v0.2.0 — MIT — in-browser residency
All compute runs on your device

Your data,
domiciled on
your device.

Domicile is a private AI stack — vector database, RAG, and a local LLM — that runs entirely in the browser. On-prem-grade data custody and privilege protection, without the on-prem infrastructure. Your documents never leave their legal residence.

See it work For law firms & integrators $ npm install @kyrillosishak/domicile
0
Bytes egressing the device — ever
0K+
Documents held in client-side custody
ms
Retrieval p99 at 10K vectors
Privilege protection, no per-seat cloud fees
Scroll
Privilege isn't a policy you configure. It's a boundary you build.
Domicile — data domiciled in-browser, not on-prem, not in the cloud
For whom

On-prem custody,
without the on-prem.

Domicile serves two sides of the same need: the firms that require data residency and privilege protection, and the teams who deploy and maintain that custody for them.
01 — Law firms & legal teams

For those who can't afford on-prem — but can't afford a leak either.

Sensitive matter files, privileged communications, and client data never leave the workstation. Domicile runs RAG and generation locally, so attorney-client privilege isn't routed through a third-party cloud.

  • GDPR-compliant by construction — zero network egress
  • Privilege protection without per-seat SaaS contracts
  • Works offline — airport, courtroom, client site
  • Document Q&A grounded in your own matter files, with citations
02 — Integration & infra teams

The stack your integration practice deploys, not hosts.

Domicile is the custody layer you offer clients who want on-prem guarantees without on-prem capital expense. Ship it inside their app, configure residency, walk away — no servers to run, no data plane to secure.

  • One library to embed — no infrastructure to provision or maintain
  • Configurable residency: device-only, with optional local export
  • MCP integration for the agent stacks you already wire up
  • Export/import for migration and client hand-off
The stack

One library.
The whole custody pipeline.

Storage, indexing, embeddings, generation and an agent protocol — wired together, all in the browser, all swappable. The complete residence for your data, held on the device it belongs to.
01 — custody

Vector database

Persistent client-side storage in IndexedDB with a pure-TypeScript HNSW graph index. Hold and search 100K+ documents with cosine, euclidean or dot metrics — real similarity scores, non-rebuilding deletes — all in residence on the device.

indexeddb · hnsw
02 — embeddings

Local embeddings

Transformers.js with WebGPU acceleration and a WASM fallback. Model weights cached on-device, so repeat queries never reach the network.

transformers.js
03 — generation

Dual LLM runtime

WebLLM for GPU-fast inference, Wllama for CPU portability — automatic fallback so generation works on any workstation your firm issues.

webllm · wllama
04 — rag

RAG with citations

Answers grounded in your matter files, with source citations linking every claim back to the document that grounded it — auditable privilege, not black-box output.

rag · streaming
05 — protocol

MCP, for agents

Expose your custody layer as Model Context Protocol tools — wire Domicile into Claude Desktop and the agent stacks your integration team already builds on.

model context protocol
06 — residency

Resident by design

Data domiciled on the device — no cloud egress, no third-party processors, no residency drift. The boundary is architectural, not a configuration someone can forget to check.

zero egress · gdpr
Developer experience

Five lines to
a custody layer.

A clean, fully-typed TypeScript API. No servers to provision, no data plane to secure. Embed it in the client app, configure residency, hand it off.
Quickstart
Retrieval
RAG pipeline
MCP server
domicile.ts
// npm install @kyrillosishak/domicile
import Domicile from '@kyrillosishak/domicile';

// A private, in-browser custody layer
const db = new Domicile({
  storage:   { dbName: 'matter-files' },
  index:     { dimensions: 384, metric: 'cosine' },
  embedding: { model: 'Xenova/all-MiniLM-L6-v2', device: 'webgpu' },
});

await db.initialize();

await db.insert({
  text: 'Privileged communication — attorney work product',
  metadata: { matter: 'M-204', privilege: 'true' },
});

const results = await db.search({ text: 'summary of work product', k: 5 });
console.log(results);
// Retrieval with privilege-aware metadata filtering
const results = await db.search({
  text: 'indemnification clauses',
  k: 10,
  filter: { field: 'matter', operator: 'eq', value: 'M-204' },
});

for (const r of results) {
  console.log(r.score.toFixed(3), r.metadata);
}

// Inspect custody state
const stats: IndexStats = await db.stats();
console.log(stats.vectorCount, stats.memoryUsage);
import { RAGPipelineManager, WllamaProvider } from '@kyrillosishak/domicile';

const llm = new WllamaProvider({ model: '...' });
const rag = new RAGPipelineManager(db, llm, embedding);

// Ask questions grounded in privileged matter files
const result = await rag.query('Summarize the indemnification position.', {
  topK: 3,
  generateOptions: { maxTokens: 256, temperature: 0.7 },
});

console.log(result.answer);   // generated response
console.log(result.sources);  // cited source documents
import { MCPServer } from '@kyrillosishak/domicile';

// Expose your custody layer as tools for AI agents
const mcp = new MCPServer(db, rag);

const tools: MCPTool[] = mcp.getTools();
// → [search, insert, rag_query, ...]

// Wire into Claude Desktop or any MCP-aware agent
mcp.serve({ transport: 'stdio' });
Under the hood

A layered,
resident-by-design stack.

Each layer is swappable and runs without a server. Data flows down; answers flow up — all on the device. Replace a component and the residency boundary holds.
iInterface
Your application talks to a clean TypeScript API, or to AI agents over MCP — Claude Desktop, ChatGPT, anything that speaks the protocol.
apimcp
iiIntelligence
The RAG pipeline manager orchestrates retrieval and generation, with WebLLM and Wllama runtimes and automatic GPU→CPU fallback.
ragwebllmwllama
iiiRetrieval
Transformers.js produces embeddings; the pure-TS HNSW index returns nearest neighbours with real scores. A BM25 sparse index fuses with dense via reciprocal-rank fusion, and a cross-encoder reranker sharpens the top-k — all filtered by metadata.
embedhnswbm25rerankfilter
ivCustody
IndexedDB storage manager with quota-aware eviction and JSON / binary export-import for migration and client hand-off.
indexeddbexport
vAcceleration
GPU compute when WebGPU is available, WASM SIMD fallback otherwise, with a worker pool for batched parallelism.
webgpuwasmworkers
viReliability
A typed error hierarchy, LRU caches, a memory manager, and a built-in benchmark runner to measure it all.
errorslrubench
Measured

Fast enough
for the matter at hand.

Reproducible from domicile bench — the same suite that gates the build. Measured on a Linux/server CPU (Node); a browser WebGPU run will differ, so run it on your own hardware.
Operation
Latency
Throughput / Quality
Notes
Search10K vectors, 128-dim cosine
p50 2.4ms
p99 7ms
recall@10 = 0.91
Pure-TS HNSW, real scores, warm cache
Search1K vectors, 128-dim cosine
p50 1.4ms
p99 1.8ms
recall@10 = 1.00
Non-rebuilding delete < 0.01ms
Citation accuracylegal known-answer corpus
recall@3 = 0.92
Dense + hybrid + rerank retrieval
RAG queryfull pipeline
retrieval + generate
streaming
Local LLM, browser-bound

Reproduce: npm run build && node dist/cli/index.js bench · node dist/cli/index.js bench --citation

Start building

On-prem custody,
without the on-prem.

Zero infrastructure. Zero egress. Zero third-party processors. Just the device, the data, and a library that keeps the two together.