Getting Started

This guide takes the shortest full path:

  1. install indexbind
  2. build a native SQLite artifact from a tiny docs folder
  3. query it from Node
  4. build a canonical bundle from the same documents
  5. query that bundle from the web runtime
  6. see the incremental cache path for repeated local rebuilds

Install

npm install indexbind

Supported prebuilt native targets:

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:

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:

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

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