npm / Node.js

TypeScript and Node.js local retrieval guide

Install the native Node.js wrapper, build a typed local corpus, run exact or hybrid search, and close native resources.

macOS arm64, Node.js 22.13+ or 24 LTSView the v0.1.0 source guide →
On this page

Install

Choose exactly one native retrieval package. The graph package already includes retrieval. The embedding package is independent.

# Flat corpus
npm install @gungorbasa/retrievalkit@0.1.0

# Graph-only and graph-scoped retrieval
npm install @gungorbasa/retrievalkit-graph@0.1.0

# Optional local embedding provider
npm install @gungorbasa/retrievalkit-embedding@0.1.0

The native v0.1.0 packages target macOS arm64 with Node.js 22.13+ LTS or Node.js 24 LTS. Windows, Linux, and other native architectures are not claimed.

Build a retrieval database

Native work runs through asynchronous N-API calls. Embeddings use Float32Array; exact signed integers use bigint.

import {
  RetrievalDatabaseBuilder,
  timestampMillis,
} from "@gungorbasa/retrievalkit";

const builder = new RetrievalDatabaseBuilder({
  corpusId: "apollo",
  metric: "cosine",
});

await builder.add([{
  id: "decision-swift",
  text: "Apollo chose Swift for native platform integration.",
  embedding: new Float32Array([1, 0, 0]),
  metadata: {
    project: "apollo",
    updatedAt: timestampMillis(1_700_000_000_000n),
  },
}]);

const database = await builder.build();

The first document fixes dimension in Rust. Callers do not configure it separately.

Search and filter

search() is a discriminated family.

try {
  const hits = await database.search({
    mode: "hybrid",
    text: "Why did we choose Swift?",
    embedding: new Float32Array([1, 0, 0]),
    alpha: 0.6,
    where: {
      kind: "equals",
      field: "project",
      value: "apollo",
    },
    limit: 5,
  });

  console.log(hits[0]?.documentId);
} finally {
  await database.close();
}
  • { mode: "vector", embedding } performs exact vector search.
  • { mode: "text", text } performs BM25-only search.
  • { mode: "hybrid", text, embedding, alpha } combines both in Rust.

Scope with a graph

Graph selections are opaque, generation-bound resources. Close selections and databases explicitly.

const selection = await graphRetrievalDatabase.graph.query({
  seed: {
    kind: "equals",
    nodeType: "Decision",
    field: ["project"],
    values: ["apollo"],
  },
});

try {
  const hits = await graphRetrievalDatabase.retrieval.search({
    mode: "hybrid",
    text: "native integration",
    embedding: new Float32Array([1, 0, 0]),
    alpha: 0.6,
    within: selection,
  });
} finally {
  await selection.close();
  await graphRetrievalDatabase.close();
}

Rust owns projection, metadata filtering, stale-selection checks, ordering, complete graph paths, and edge provenance.

Run the source quickstart

cd wrappers/typescript
npm ci
npm run preflight
npm run build
node base/examples/retrieval.mjs

The preflight requires a supported LTS Node.js release and Rust cargo.

Choose the database boundary

Three query paths

Compare the same job in TypeScript. These are separate APIs, not modes hidden behind one query.

01

Hybrid vector + BM25

RetrievalDatabase

Rank the whole corpus with exact vector similarity and BM25.

TypeScript
const hits = await retrievalDatabase.search({
  mode: "hybrid",
  text: "What did we decide about offline sync?",
  embedding: queryEmbedding,
  alpha: 0.6,
  limit: 5
});
02

Graph query alone

GraphDatabase

Select records by relationship. No embedding or retrieval ranker is involved.

TypeScript
const selection = await graphDatabase.graph.query({
  seed: {
    kind: "nodes",
    nodes: [{
      kind: "record",
      nodeType: "Notebook",
      recordId: "product-research"
    }]
  },
  traverse: [{ relationship: "references" }]
});
03

Graph + vector + BM25

GraphRetrievalDatabase

Select candidates with the graph, then rank only that scope with vector + BM25.

TypeScript
const selection = await graphRetrievalDatabase.graph.query({
  seed: {
    kind: "nodes",
    nodes: [{
      kind: "record",
      nodeType: "Project",
      recordId: "mobile-app"
    }]
  },
  traverse: [{ relationship: "contains" }]
});

const hits = await graphRetrievalDatabase.retrieval.search({
  mode: "hybrid",
  text: "Why is cold start slow on Android?",
  embedding: queryEmbedding,
  alpha: 0.6,
  within: selection,
  limit: 5
});