npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vectordb-client

v1.1.0

Published

TypeScript/JavaScript SDK for the VectorDB REST API

Readme

vectordb-client

TypeScript/JavaScript SDK for the VectorDB REST API.

Fully typed, works in Node.js 18+, Deno, and edge runtimes (Cloudflare Workers, Vercel Edge).

Installation

npm install vectordb-client
# or
yarn add vectordb-client
# or
pnpm add vectordb-client

Quick Start

import { VectorDBClient } from "vectordb-client";

const client = new VectorDBClient({
  baseUrl: "https://your-vectordb.onrender.com",
  apiKey: "your-api-key",
});

// Create a collection
await client.collections.create("articles", 384, "cosine");

// Store a vector
await client.vectors.upsert("articles", "doc-1", [0.1, 0.2, 0.9 /* ...384 dims */], {
  title: "Hello World",
  author: "Alice",
});

// Search
const results = await client.search.search("articles", queryVector, { k: 5 });
for (const r of results.results) {
  console.log(r.external_id, r.score, r.metadata);
}

Auth

// Register a new user
const { user, api_key } = await client.auth.register("[email protected]", "password123");
console.log(api_key.key); // save this

// Login
const { user, api_key } = await client.auth.login("[email protected]", "password123");

Collections

// Create
// distance_metric: "cosine" (default) | "l2" | "ip"
const col = await client.collections.create("articles", 384, "cosine");

// List
const cols = await client.collections.list();
for (const c of cols) {
  console.log(c.name, c.dim, c.vector_count);
}

// Get
const col = await client.collections.get("articles");
console.log(col.name, col.dim, col.vector_count);

// Update description
await client.collections.update("articles", "News articles corpus");

// Export all vectors
const exported = await client.collections.export("articles", 10000);
for (const v of exported.vectors) {
  console.log(v.external_id, v.vector.slice(0, 3));
}

// Delete
await client.collections.delete("articles");

Vectors

// Upsert (insert or update)
const result = await client.vectors.upsert(
  "articles",
  "doc-1",
  [0.1, 0.2, 0.9 /* ...384 dims */],
  { title: "Hello", tags: ["ml", "nlp"] }
);
console.log(result.status); // "inserted" | "updated"

// Upsert with auto-embedding (server-side, if embedding provider configured)
await client.vectors.upsert("articles", "doc-1", undefined, undefined, undefined, {
  text: "Hello world",
});

// Bulk upsert
const bulk = await client.vectors.bulkUpsert("articles", [
  { external_id: "doc-1", vector: [...], metadata: { title: "A" } },
  { external_id: "doc-2", vector: [...], metadata: { title: "B" } },
  { external_id: "doc-3", text: "auto-embed this" },
]);
console.log(bulk.results.length);

// Fetch a single vector by ID
const vec = await client.vectors.getVector("articles", "doc-1");

// Fetch multiple vectors by ID
const vecs = await client.vectors.batchFetch("articles", ["doc-1", "doc-2", "doc-3"]);

// Scroll through all vectors (cursor-based pagination)
let page = await client.vectors.scroll("articles", { limit: 100 });
while (page.has_more) {
  for (const v of page.vectors) {
    console.log(v.external_id);
  }
  page = await client.vectors.scroll("articles", { limit: 100, cursor: page.next_cursor });
}

// Scroll with metadata filter
const page = await client.vectors.scroll("articles", {
  limit: 50,
  filters: { author: "Alice" },
});

// Delete one
await client.vectors.delete("articles", "doc-1");

// Batch delete
await client.vectors.deleteBatch("articles", ["doc-1", "doc-2", "doc-3"]);

Search

// KNN search
const results = await client.search.search("articles", queryVector, { k: 10 });
for (const r of results.results) {
  console.log(r.external_id, r.score, r.metadata);
}

// Search with metadata filters
const results = await client.search.search("articles", queryVector, {
  k: 10,
  filters: { author: "Alice", year: 2024 },
});

// Search with pagination
const results = await client.search.search("articles", queryVector, {
  k: 10,
  offset: 20,
});

// Search by text (server-side embedding)
const results = await client.search.search("articles", undefined, {
  text: "machine learning",
  k: 5,
});

// Recommendations — similar to a stored vector, excludes itself
const recs = await client.search.recommend("articles", "doc-1", { k: 5 });

// Cosine similarity between two stored vectors
const score = await client.search.similarity("articles", "doc-1", "doc-2");
console.log(`Similarity: ${score.toFixed(4)}`);

// Rerank candidates against a query vector
const reranked = await client.search.rerank(
  "articles",
  queryVector,
  ["doc-1", "doc-2", "doc-3", "doc-4"]
);
for (const r of reranked) {
  console.log(r.external_id, r.score);
}

// Hybrid search — vector + keyword via Reciprocal Rank Fusion
const hybrid = await client.search.hybridSearch(
  "articles",
  "transformer models attention",
  queryVector,
  {
    k: 10,
    alpha: 0.7, // 0 = keyword only, 1 = vector only, 0.5 = balanced
  }
);

// Bulk search — multiple queries in one request
const results = await client.search.bulkSearch("articles", [
  { vector: query1, k: 5 },
  { vector: query2, k: 5, filters: { author: "Alice" } },
]);
// results[0] = hits for query1, results[1] = hits for query2

RAG — Documents & Query

// Upload a document (auto-chunked and stored)
const upload = await client.documents.upload("articles", "./paper.txt");
console.log(`Created ${upload.chunks_created} chunks, doc_id=${upload.document_id}`);

// Semantic search returning text chunks
const result = await client.query.query(
  "What is attention mechanism?",
  "articles",
  { top_k: 5 }
);
for (const chunk of result.results) {
  console.log(chunk.score, chunk.text);
}

// LLM-powered answer with source citations
const answer = await client.query.ask(
  "Explain transformers in simple terms",
  "articles",
  { k: 5 }
);
console.log(answer.answer);
for (const src of answer.sources) {
  console.log(src.external_id, src.score);
}

GraphRAG (Pro/Scale tier)

// Check graph status
const status = await client.graph.status("articles");
console.log(`Entities: ${status.entity_count}, Edges: ${status.edge_count}`);
console.log(`Pending jobs: ${status.jobs.pending}`);

// Search the knowledge graph
const graphResults = await client.graph.search("articles", "transformer architecture", {
  topK: 10,
});
for (const entity of graphResults.entities) {
  console.log(entity.entity, entity.entity_type, entity.score);
  for (const rel of entity.relations) {
    console.log(`  → ${rel.relation} → ${rel.target}`);
  }
}

// Find shortest path between two entities
const path = await client.graph.path("articles", "BERT", "GPT-4", { maxHops: 3 });
for (const route of path.paths) {
  for (const step of route) {
    console.log(`${step.source} --[${step.relation}]--> ${step.target}`);
  }
}

// Louvain community detection (Scale tier)
const summary = await client.graph.summarize("articles", { resolution: 1.0 });
for (const community of summary.communities) {
  console.log(`Community ${community.id}: ${community.entities.slice(0, 3).join(", ")}...`);
}

// Full GraphRAG answer (Scale tier)
const answer = await client.graph.ask("articles", "How does BERT relate to GPT?", {
  topKEntities: 5,
  maxHops: 2,
});
console.log(answer.answer);
console.log(`Used ${answer.entities_used.length} entities, ${answer.paths_used} paths`);

// Hybrid vector + graph answer (Scale tier)
const hybrid = await client.graph.hybridAsk(
  "articles",
  "What are attention mechanisms?",
  { topK: 5, alpha: 0.5 }
);
console.log(hybrid.answer);
for (const src of hybrid.sources) {
  console.log(src.external_id, src.source, src.score); // source: "vector" | "graph"
}

// Update graph config
await client.graph.config("articles", { model: "gpt-4o-mini", chunk_size: 512 });

Usage & Quotas

// Current usage
const usage = await client.usage.getCurrent();
console.log(`Tier: ${usage.tier}`);
console.log(`Requests: ${usage.request_count}/${usage.max_requests}`);
console.log(`Vectors: ${usage.vector_count}/${usage.max_vectors}`);
for (const warning of usage.warnings) {
  console.warn(warning);
}

// Usage history
const history = await client.usage.getHistory(30); // last 30 days

// Admin: upgrade a user's tier
await client.usage.updateUserTier(42, "pro");

// Admin: trigger cleanup of expired data
await client.usage.triggerCleanup();

API Keys

// Create a key
const key = await client.keys.create("my-app", "readwrite", 90); // expires in 90 days
console.log(key.key); // shown only once

// List all keys
const keys = await client.keys.list();
for (const k of keys) {
  console.log(k.id, k.name, k.role, k.is_active);
}

// Get one key
const key = await client.keys.get(3);

// Update
await client.keys.update(3, { name: "renamed", role: "readonly" });

// Revoke / restore
await client.keys.revoke(3);
await client.keys.restore(3);

// Rotate (generates new key value)
const newKey = await client.keys.rotate(3);
console.log(newKey.key); // new value, shown once

// Per-key usage stats
const stats = await client.keys.getUsage(3);
console.log(stats.total_requests, stats.last_24h, stats.by_endpoint);

// Overall usage summary
const summary = await client.keys.getUsageSummary();

// Delete
await client.keys.delete(3);

Observability

// Health check
const health = await client.observability.health();
console.log(health.status);             // "ok"
console.log(health.total_vectors);
console.log(health.total_collections);

// Prometheus metrics (raw text)
const metrics = await client.observability.metrics();
console.log(metrics);

Error Handling

import {
  VectorDBError,
  NotFoundError,
  AlreadyExistsError,
  DimensionMismatchError,
  AuthenticationError,
  RateLimitError,
  ValidationError,
} from "vectordb-client";

try {
  await client.collections.create("articles", 384);
} catch (err) {
  if (err instanceof AlreadyExistsError) {
    console.log("Collection already exists");
  } else if (err instanceof DimensionMismatchError) {
    console.log(`Wrong vector size: ${err.message}`);
  } else if (err instanceof AuthenticationError) {
    console.log("Invalid or expired API key");
  } else if (err instanceof RateLimitError) {
    console.log("Too many requests — back off and retry");
  } else if (err instanceof NotFoundError) {
    console.log("Collection or vector not found");
  } else if (err instanceof VectorDBError) {
    console.log(`API error ${err.statusCode}: ${err.message}`);
  }
}

Node.js < 18 (custom fetch)

import fetch from "node-fetch";
import { VectorDBClient } from "vectordb-client";

const client = new VectorDBClient({
  baseUrl: "http://localhost:8000",
  apiKey: "your-api-key",
  fetch: fetch as unknown as typeof globalThis.fetch,
});

TypeScript Types

All request and response shapes are fully typed and exported:

import type {
  Collection,
  SearchResult,
  VectorResult,
  UpsertResult,
  BulkUpsertResult,
  ScrollResult,
  UsageInfo,
  GraphStatusResponse,
  GraphSearchResponse,
  GraphPathResponse,
  GraphSummarizeResponse,
  GraphAskResponse,
  HybridAskResponse,
  AskResult,
  ApiKey,
  HealthStats,
  DocumentUploadResult,
  QueryResult,
} from "vectordb-client";

Configuration

| Option | Type | Description | |--------|------|-------------| | baseUrl | string | VectorDB server URL | | apiKey | string | API key (x-api-key header) | | fetch | FetchFn | Custom fetch (optional, for Node < 18) |


Requirements

  • Node.js 18+ (uses native fetch)
  • Or any runtime with a global fetch (Deno, Cloudflare Workers, Vercel Edge)

Links