{"id":47310417,"url":"https://github.com/Altor-lab/altor-vec","last_synced_at":"2026-03-31T15:00:32.642Z","repository":{"id":343474599,"uuid":"1177899651","full_name":"Altor-lab/altor-vec","owner":"Altor-lab","description":"Client-side vector search powered by HNSW. 54KB gzipped WASM. Sub-millisecond latency.","archived":false,"fork":false,"pushed_at":"2026-03-25T12:38:46.000Z","size":756,"stargazers_count":42,"open_issues_count":2,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-26T14:16:55.872Z","etag":null,"topics":["embeddings","hnsw","nearest-neighbor","rust","semantic-search","vector-search","wasm","webassembly"],"latest_commit_sha":null,"homepage":"https://altorlab.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Altor-lab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-10T13:41:12.000Z","updated_at":"2026-03-25T11:39:51.000Z","dependencies_parsed_at":"2026-03-10T20:00:24.635Z","dependency_job_id":null,"html_url":"https://github.com/Altor-lab/altor-vec","commit_stats":null,"previous_names":["altor-lab/altor-vec"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Altor-lab/altor-vec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altor-lab%2Faltor-vec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altor-lab%2Faltor-vec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altor-lab%2Faltor-vec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altor-lab%2Faltor-vec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Altor-lab","download_url":"https://codeload.github.com/Altor-lab/altor-vec/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Altor-lab%2Faltor-vec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31241135,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-31T14:40:16.804Z","status":"ssl_error","status_checked_at":"2026-03-31T14:40:03.690Z","response_time":111,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embeddings","hnsw","nearest-neighbor","rust","semantic-search","vector-search","wasm","webassembly"],"created_at":"2026-03-17T11:00:24.030Z","updated_at":"2026-03-31T15:00:32.636Z","avatar_url":"https://github.com/Altor-lab.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ch1 align=\"center\"\u003ealtor-vec\u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cb\u003eClient-side vector search. Rust + WASM. 54KB. Sub-millisecond.\u003c/b\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.npmjs.com/package/altor-vec\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/altor-vec?color=blue\u0026label=npm\" alt=\"npm version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/altor-vec\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/altor-vec?color=green\" alt=\"npm downloads\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/altor-lab/altor-vec/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/altor-lab/altor-vec/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/altor-lab/altor-vec/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/altor-lab/altor-vec?style=social\" alt=\"GitHub stars\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/altor-lab/altor-vec/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue\" alt=\"License\"\u003e\u003c/a\u003e\n    \u003cimg src=\"https://img.shields.io/badge/WASM-54KB_gzipped-orange\" alt=\"WASM size\"\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://altorlab.dev\"\u003e\u003cimg src=\"https://img.shields.io/badge/%F0%9F%9A%80_Try_Live_Demo-altorlab.dev-blueviolet?style=for-the-badge\" alt=\"Try Live Demo\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n---\n\n**Zero server. Zero API keys. Zero per-query cost. Your users' data never leaves their browser.**\n\naltor-vec is an HNSW vector similarity search engine written in Rust that compiles to 54KB of WebAssembly. Search 10,000 vectors in under 1ms — entirely client-side.\n\n## Why altor-vec?\n\n\u003e You're paying Algolia **$0.50 per 1,000 searches** and sending your users' queries to a third party.\n\u003e\n\u003e With altor-vec, search runs in the browser. **$0 per query. Forever.**\n\n| | altor-vec | Algolia | Voy | Orama |\n|---|-----------|---------|-----|-------|\n| **Runs client-side** | Yes | No | Yes | Yes |\n| **Binary size** | **54KB** gz | N/A | 75KB gz | ~2KB* |\n| **Algorithm** | **HNSW** | BM25 | k-d tree | Brute-force |\n| **p95 latency** | **0.6ms** | ~50ms (network) | ~2ms | ~5ms |\n| **Per-query cost** | **$0** | $0.50/1K | $0 | Free tier |\n\n\u003csub\u003e*Orama's 2KB is keyword search only; vector search adds significant size.\u003c/sub\u003e\n\n## Get started in 30 seconds\n\n```bash\nnpm install altor-vec\n```\n\n```js\nimport init, { WasmSearchEngine } from 'altor-vec';\n\nawait init();\n\n// Load a pre-built index\nconst resp = await fetch('/index.bin');\nconst engine = new WasmSearchEngine(new Uint8Array(await resp.arrayBuffer()));\n\n// Search — returns in \u003c1ms\nconst results = JSON.parse(engine.search(queryEmbedding, 5));\n// =\u003e [[nodeId, distance], ...]\n```\n\nThat's it. No server to deploy. No API key to manage. No billing to worry about.\n\n## Benchmarks\n\n\u003ctable\u003e\n\u003ctr\u003e\u003ctd\u003e\n\n**Latency** (10K vectors, 384d)\n\n| Environment | p95 |\n|-------------|-----|\n| Chrome | **0.60ms** |\n| Node.js | **0.50ms** |\n| Native Rust | **0.26ms** |\n\n\u003c/td\u003e\u003ctd\u003e\n\n**Size**\n\n| Asset | Size |\n|-------|------|\n| `.wasm` gzipped | **54KB** |\n| `.wasm` raw | 117KB |\n| Index (10K/384d) | 17MB |\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n## Use with a Web Worker (recommended for production)\n\nKeep the main thread free — especially important on mobile:\n\n```js\n// worker.js\nimport init, { WasmSearchEngine } from 'altor-vec';\n\nlet engine;\nself.onmessage = async (e) =\u003e {\n  if (e.data.type === 'init') {\n    await init();\n    const resp = await fetch(e.data.indexUrl);\n    engine = new WasmSearchEngine(new Uint8Array(await resp.arrayBuffer()));\n    postMessage({ type: 'ready', count: engine.len() });\n  }\n  if (e.data.type === 'search') {\n    const results = JSON.parse(engine.search(new Float32Array(e.data.query), e.data.topK));\n    postMessage({ type: 'results', results });\n  }\n};\n```\n\n```js\n// main.js — UI stays buttery smooth\nconst worker = new Worker('worker.js', { type: 'module' });\nworker.postMessage({ type: 'init', indexUrl: '/index.bin' });\n```\n\n## API\n\n| Method | Description |\n|--------|-------------|\n| `new WasmSearchEngine(bytes)` | Load a serialized index |\n| `.from_vectors(flat, dims, m, ef_construction, ef_search)` | Build index from vectors |\n| `.search(query, topK)` | Search → JSON `[[id, dist], ...]` |\n| `.add_vectors(flat, dims)` | Add vectors to existing index |\n| `.to_bytes()` | Serialize index |\n| `.len()` | Vector count |\n| `.free()` | Free WASM memory |\n\n**Parameters:**\n\n| Param | Default | What it does |\n|-------|---------|-------------|\n| `m` | 16 | Connections per node. Higher = better recall, more RAM |\n| `ef_construction` | 200 | Build-time beam width. Higher = better index, slower build |\n| `ef_search` | 50 | Search-time beam width. Higher = better recall, slower search |\n\n## Works with any embedding model\n\n| Model | Dims | Where it runs |\n|-------|------|---------------|\n| all-MiniLM-L6-v2 | 384 | Browser ([Transformers.js](https://huggingface.co/docs/transformers.js)) |\n| text-embedding-3-small | 1536 | OpenAI API |\n| embed-english-v3 | 1024 | Cohere API |\n\n**Fully client-side** with Transformers.js — no API calls at all:\n\n```js\nimport { pipeline } from '@huggingface/transformers';\n\nconst embed = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');\nconst output = await embed('your query', { pooling: 'mean', normalize: true });\nconst results = JSON.parse(engine.search(new Float32Array(output.data), 5));\n```\n\n## How it works\n\naltor-vec uses **HNSW (Hierarchical Navigable Small World)** — the same algorithm behind Pinecone, Qdrant, and pgvector. HNSW builds a multi-layer graph where each node is a vector and edges connect nearby neighbors. Upper layers act as express lanes for coarse navigation; the bottom layer contains all vectors for fine-grained search. A query enters at the top and greedily descends to find the nearest neighbors in O(log n) time.\n\nAll vectors are L2-normalized at insert time, so dot product distance equals cosine similarity — no extra computation at search time.\n\n## Architecture\n\n```\nsrc/\n├── lib.rs              # Public API re-exports\n├── distance.rs         # Dot product, normalization (auto-vectorizes with SIMD)\n└── hnsw/\n    ├── mod.rs           # HnswIndex: API + serialization\n    ├── graph.rs         # Layered graph structure\n    ├── search.rs        # Greedy beam search\n    └── construction.rs  # HNSW insert + random layer selection\n\nwasm/\n└── src/lib.rs          # WasmSearchEngine (wasm-bindgen wrapper)\n```\n\n## Build from source\n\n```bash\ncargo test                # run tests\ncargo bench               # run benchmarks\ncd wasm \u0026\u0026 wasm-pack build --target web --release  # build WASM\n```\n\n## Contributing\n\nWe welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for build instructions, code style, and PR process.\n\n## License\n\n[MIT](LICENSE)\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eBuilt by \u003ca href=\"https://github.com/altor-lab\"\u003ealtor-lab\u003c/a\u003e\u003c/b\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\n    \u003ca href=\"https://www.npmjs.com/package/altor-vec\"\u003enpm\u003c/a\u003e ·\n    \u003ca href=\"https://github.com/altor-lab/altor-vec/issues\"\u003eIssues\u003c/a\u003e ·\n    \u003ca href=\"mailto:anshul@altorlab.dev\"\u003eContact\u003c/a\u003e\n  \u003c/sub\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cb\u003eNeed managed semantic search? Embedding pipeline, index building, CDN delivery?\u003c/b\u003e\n  \u003cbr\u003e\n  \u003ca href=\"mailto:anshul@altorlab.dev\"\u003eanshul@altorlab.dev\u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAltor-lab%2Faltor-vec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAltor-lab%2Faltor-vec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAltor-lab%2Faltor-vec/lists"}