Relationships are your most valuable asset, but they're also the hardest thing to keep track of. Contacts scattered across Apple, Google, and LinkedIn. Names you recognize but can't quite place. Introductions you meant to follow up on but never did. Contrack fixes that.
Sync your contacts from every source into one unified network with automatic dedupe across platforms. Let AI enrichment research your connections across the web and fill in the context you never had time to enter. Behind the scenes, proactive intelligence keeps watch over your network and nudges you to reconnect before important relationships go quiet.
- Magic Paste β Paste unstructured text, AI extracts a structured contact
- Multi-Provider AI β Gemini (default), OpenAI, or Anthropic via provider-agnostic adapters
- Smart Router β Automatic Gemini model selection (Lite/Flash/Pro) per use case
- Batch Enrichment β AI-powered web research to hydrate contact profiles
- Custom Lists β Unlimited groups with icons, drag-to-reorder, bulk membership
- Doc2Query β Write-time search expansion via AI for better recall
- Ghost Detection β Passive entity extraction from notes creates ghost contacts
- @Mentions β Bi-directional relationship graph via Tiptap rich text
- AI Cache Telemetry β Multi-tiered LRU caching with full transparency dashboard
- Enterprise Virtualization β <20ms page transitions for 100K+ contacts
- Quick Note (
Cmd+Shift+I) β Log interactions from anywhere - Link Unfurling β Zero-Chromium OpenGraph extraction via Cheerio
- Logo Proxy β Heuristic company logo discovery with local caching
Try it locally in under 60 seconds.
The easiest way to run Contrack is via Docker Compose. This ensures all native dependencies (like sqlite-vec) work perfectly.
git clone https://github.com/arvarik/contrack.git
cd contrack
cp .env.example .env
# Add your API key (GEMINI_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY)
docker-compose up -dOpen http://localhost:3210. Data is automatically persisted to ./data.
git clone https://github.com/arvarik/contrack.git
cd contrack
npm install
cp .env.example .env
# Add your API key (GEMINI_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY)
npm run devOpen http://localhost:3210. The server auto-initializes the database, loads embedding models, and starts background tasks.
Seed data: Run
npm run seedto populate with demo contacts.
| Domain | Technology |
|---|---|
| Frontend | React 19, Vite 6, React Query v5, Tailwind CSS v4, Tiptap, Motion |
| Backend | Node.js 22, Express, TypeScript (tsx), Zod validation |
| Database | SQLite3 (WAL mode), Drizzle ORM, FTS5, sqlite-vec |
| AI | Gemini / OpenAI / Anthropic (provider-agnostic adapter pattern) |
| Search | Hybrid RAG: FTS5 keyword + 384-dim local vector KNN (Transformers.js) |
| Mapping | React Leaflet + Leaflet Cluster, Mapbox/Nominatim geocoding |
| Testing | Vitest β 180 tests, <600ms |
Full documentation lives in the docs/ directory:
| Guide | Description |
|---|---|
| Getting Started | Installation, first boot, scripts, keyboard shortcuts |
| Configuration | Environment variables, AI provider setup, tier tuning |
| Architecture | System overview, data flow, schema, caching |
| API Reference | Complete REST API with curl and JavaScript examples |
| Feature | Guide |
|---|---|
| Contact Management | docs/features/contact-management.md |
| Command Palette | docs/features/command-palette.md |
| AI Search | docs/features/ai-search.md |
| Deduplication | docs/features/deduplication.md |
| Pulse Dashboard | docs/features/dashboard-pulse.md |
| Map View | docs/features/map-view.md |
| Lists | docs/features/lists.md |
| Variable | Description | Default |
|---|---|---|
AI_PROVIDER |
LLM provider: gemini, openai, anthropic |
gemini |
GEMINI_API_KEY |
Gemini API key | β |
OPENAI_API_KEY |
OpenAI API key | β |
ANTHROPIC_API_KEY |
Anthropic API key | β |
AI_TIER |
FREE or PAID rate limit profile |
FREE |
PORT |
Express listening port | 3210 |
MAPBOX_API_KEY |
Mapbox geocoding (optional, higher accuracy) | β |
See Configuration Guide for full details.
graph TD
subgraph Frontend ["UI Layer β React 19 / Vite"]
RQ["React Query v5"] --> TW["Tailwind v4 'No-Line' UI"]
TW --> TT["Tiptap Editor + Cheerio Previews"]
TT --> Map["React Leaflet Geospatial"]
end
subgraph Backend ["Node.js Express Server"]
EX["Express Router"] --> SVC["Service Layer"]
SVC --> AI["AI Service + Smart Router"]
SVC --> SRCH["Ask Contrack v3 Spotlight"]
SVC --> DDP["Dedupe Engine"]
SVC --> REL["Relationship Scoring"]
end
subgraph Storage ["Persistence β Local-First"]
SQL[("SQLite3 WAL Mode")]
DZ["Drizzle ORM"] --> SQL
FTS["FTS5 Search Index"] --- SQL
VEC["sqlite-vec Embeddings"] --- SQL
end
subgraph AILayer ["AI Infrastructure"]
SR["Smart Router"] --> Adapters["Gemini / OpenAI / Anthropic"]
SR --> QT["Quota Tracker + Parallel Queue"]
LE["Transformers.js Local"] --> VEC
end
Frontend <===>|"JSON REST + UUID Tracing"| Backend
AI <===>|"Smart Router model selection"| AILayer
Backend <===>|"Drizzle ORM"| Storage
See CONTRIBUTING.md for development standards, code style, and PR process.
This project is licensed under the GNU Affero General Public License v3.0. This means you can use, modify, and distribute the code, but any modified versions β including those offered as a network service (SaaS) β must also be open-sourced under AGPL v3.





