API

indexbind has four runtime-facing entrypoints:

Node-side directory and artifact APIs also support optional index-scoped convention files:

These files live beside the indexed root’s .indexbind/ directory and are auto-discovered only from that exact root.

indexbind

Native Node entrypoint for SQLite artifacts:

import { openIndex } from 'indexbind';

const index = await openIndex('./index.sqlite');
const hits = await index.search('rust guide', {
  topK: 5,
  mode: 'hybrid',
  reranker: { kind: 'embedding-v1', candidatePoolSize: 25 },
  relativePathPrefix: 'guides/',
});

openIndex(artifactPath, options?)

Opens a native SQLite artifact and returns an Index.

Open options:

Use modeProfile: 'lexical' when this Index instance should stay lexical-only. In that profile, index.search() defaults to lexical mode and rejects mode: 'hybrid' / mode: 'vector'.

When the artifact sourceRoot contains an indexbind.search.js, openIndex() applies:

index.info()

Returns artifact metadata such as:

index.search(query, options?)

Main options:

On the Node entrypoint, metadata is currently exposed as a string-to-string map in the TypeScript API.

Reranker options:

Score-adjustment options:

The returned hits include:

bestMatch contains:

indexbind/build

Programmatic build and incremental cache API:

import {
  buildCanonicalBundle,
  updateBuildCache,
  exportArtifactFromBuildCache,
  exportCanonicalBundleFromBuildCache,
} from 'indexbind/build';

Main input shape:

Use this entrypoint when your host application already has a normalized document set and wants to build directly from code instead of scanning a directory through the CLI.

For a larger mixed-content example where the host classifies documents and injects metadata before indexing, see Adoption Examples.

Available helpers:

For directory-based helpers, if the input root contains indexbind.build.js, these APIs automatically apply:

This keeps host-specific document shaping attached to the shared directory scanner and incremental cache flow.

updateBuildCache(...) returns:

Typical incremental flow:

import {
  updateBuildCache,
  exportArtifactFromBuildCache,
  exportCanonicalBundleFromBuildCache,
} from 'indexbind/build';

await updateBuildCache(
  './.indexbind-cache.sqlite',
  [
    {
      relativePath: 'guides/rust.md',
      title: 'Rust Guide',
      content: '# Rust Guide\n\nRust retrieval guide.',
      metadata: { lang: 'rust' },
    },
  ],
  { embeddingBackend: 'hashing' },
  ['guides/old.md'],
);

await exportArtifactFromBuildCache('./.indexbind-cache.sqlite', './index.sqlite');
await exportCanonicalBundleFromBuildCache('./.indexbind-cache.sqlite', './index.bundle');

indexbind/web

Browser and worker entrypoint for canonical bundles:

import { openWebIndex } from 'indexbind/web';

This path uses wasm for the default hybrid/vector-capable runtime. If you open with modeProfile: 'lexical', it can stay on the lighter lexical-only path without loading vectors or model files.

openWebIndex(base, options?) returns a WebIndex.

Open options:

modeProfile: 'lexical' skips vector/model loading for this WebIndex instance and makes lexical mode the default for search().

WebIndex.info() returns canonical bundle metadata such as:

WebIndex.search(query, options?) accepts the same search options as the Node entrypoint, except metadata values can use the broader JSON value shape.

indexbind/cloudflare

Cloudflare Worker entrypoint:

import { openWebIndex } from 'indexbind/cloudflare';

Use this instead of indexbind/web inside Workers so wasm can be loaded through the Worker-compatible static module path.

It accepts the same optional fetch override as indexbind/web, which is useful when the host wants to read bundle files through ASSETS.fetch(...) instead of public URLs.

Search Defaults and Patterns

Reasonable starting point:

const hits = await index.search(query, {
  topK: 10,
  mode: 'hybrid',
  reranker: {
    kind: 'embedding-v1',
    candidatePoolSize: 25,
  },
});

Use metadata filtering when your host application has clear product boundaries:

const hits = await index.search(query, {
  metadata: {
    lang: 'rust',
    visibility: 'public',
  },
});

Use metadata-based score adjustment when your application wants a host-defined ranking prior:

const hits = await index.search(query, {
  scoreAdjustment: {
    metadataNumericMultiplier: 'directory_weight',
  },
});

Use minScore when your product wants to cut weak tail matches and allow fewer than topK hits:

const hits = await index.search(query, {
  topK: 10,
  minScore: 0.05,
});

For a fuller explanation of how these knobs interact, see Search Quality Controls.