Getting Started
This guide takes the shortest full path:
- install
indexbind - build a native SQLite artifact from a tiny docs folder
- query it from Node
- build a canonical bundle from the same documents
- query that bundle from the web runtime
- see the incremental cache path for repeated local rebuilds
Install
npm install indexbind
Supported prebuilt native targets:
- macOS arm64
- macOS x64
- Linux x64 (glibc)
On Windows, use WSL for install, build, and local Node query flows. Native Windows prebuilds are not published.
If your platform does not have a prebuilt native addon, build the native package locally in a Rust toolchain environment:
npm run build:native:release
Create a Tiny Document Set
Create a minimal folder:
docs/
rust.md
workers.md
Example content:
# Rust Guide
Rust retrieval guide for local search.
# Cloudflare Workers Guide
Workers deployment notes for retrieval.
Build a Native SQLite Artifact
For a local docs folder:
npx indexbind build ./docs
This writes the artifact to ./docs/.indexbind/index.sqlite by default.
Query It from Node
import { openIndex } from 'indexbind';
const index = await openIndex('./docs/.indexbind/index.sqlite');
const hits = await index.search('rust guide', {
topK: 5,
mode: 'hybrid',
reranker: {
kind: 'embedding-v1',
candidatePoolSize: 25,
},
});
console.log(hits[0]);
You should see a hit shaped roughly like:
{
relativePath: 'rust.md',
title: 'Rust Guide',
score: 0.9,
bestMatch: {
excerpt: 'Rust retrieval guide for local search.',
...
},
...
}
Use the native SQLite artifact when your runtime is Node and you want the simplest local setup.
You can also sanity-check the artifact from the CLI:
npx indexbind search ./docs/.indexbind/index.sqlite "rust guide"
npx indexbind search ./docs/.indexbind/index.sqlite "rust guide" --text
CLI commands print JSON by default, which is useful for scripts and agents. Add --text for a shorter terminal summary.
Build a Canonical Bundle
The canonical bundle is the portable artifact for browsers and workers:
npx indexbind build-bundle ./docs
This writes the bundle to ./docs/.indexbind/index.bundle/ by default.
You can also build the same bundle programmatically:
import { buildCanonicalBundle } from 'indexbind/build';
await buildCanonicalBundle('./index.bundle', [
{
relativePath: 'guides/rust.md',
canonicalUrl: '/guides/rust',
title: 'Rust Guide',
summary: 'A minimal retrieval guide.',
content: '# Rust Guide\n\nRust retrieval guide.',
metadata: { lang: 'rust' },
},
], {
embeddingBackend: 'model2vec',
});
model2vec is the default recommended backend when you want the best retrieval quality from indexbind. hashing remains available as a lighter compatibility-oriented backend.
Optional Incremental Build Cache
If you rebuild the same local corpus repeatedly, keep a mutable cache and export fresh artifacts from it:
npx indexbind update-cache ./docs --git-diff
npx indexbind export-artifact ./index.sqlite --cache-file ./docs/.indexbind/build-cache.sqlite
npx indexbind export-bundle ./index.bundle --cache-file ./docs/.indexbind/build-cache.sqlite
Use this path when:
- the corpus is mostly stable
- you are iterating on local content repeatedly
- a host application or script wants to trigger rebuilds incrementally
Optional Index-Scoped Conventions
If one indexed directory needs a small amount of host-specific shaping, place convention files next to its .indexbind/ output:
docs/
indexbind.build.js
indexbind.search.js
.indexbind/
indexbind.build.js can extend the default directory scanner without replacing it:
export function includeDocument(relativePath) {
return relativePath !== 'draft.md';
}
export function transformDocument(document) {
return {
...document,
canonicalUrl: `https://example.com/${document.relativePath.replace(/\.md$/i, '')}`,
metadata: {
...(document.metadata ?? {}),
is_default_searchable: 'true',
directory_weight: 1.0,
},
};
}
indexbind.search.js can define a default search profile and a lightweight query rewrite:
export const profiles = {
default: {
metadata: {
is_default_searchable: 'true',
},
scoreAdjustment: {
metadataNumericMultiplier: 'directory_weight',
},
},
};
export function transformQuery(query) {
return {
query: query.replace(/btc/ig, 'bitcoin'),
};
}
These files are index-scoped:
- if you index
./docs, put them in./docs/ - they affect only that indexed root
- there is no repo-root fallback
Query the Bundle in Web Runtimes
import { openWebIndex } from 'indexbind/web';
const index = await openWebIndex('./docs/.indexbind/index.bundle');
const hits = await index.search('rust guide');
indexbind/web requires wasm initialization to succeed. It does not silently fall back to a separate JS query engine.
Use the canonical bundle when you want the same retrieval data to work in browsers, standard workers, or Cloudflare Workers.
Choose the Artifact
- Use the native SQLite artifact for local Node retrieval.
- Use the canonical bundle for browser and worker runtimes.
- Use the incremental build cache when you want repeated local rebuilds without treating the runtime artifact itself as mutable.
- If your product spans both environments, build both from the same document set.
Inspect and Benchmark
Inspect a native SQLite artifact:
npx indexbind inspect ./docs/.indexbind/index.sqlite
npx indexbind inspect ./docs/.indexbind/index.sqlite --text
Run the bundled regression fixture:
npm run benchmark:basic