Installation
Install Vecal and configure its module Worker.
Installation
Install the release candidate from npm:
npm install vecal@1.0.0-rc.1
# or
yarn add vecal@1.0.0-rc.1Vecal is ESM-only and has no runtime dependencies.
Open a database
import { VectorDB } from 'vecal';
const db = await VectorDB.open({
name: 'documents',
dimension: 384,
metric: 'cosine',
});| Option | Required | Meaning |
|---|---|---|
name | Yes | Logical database name. Its physical IndexedDB name is vecal:${name}:v1. |
dimension | Yes | Positive integer length required for every stored and query vector. |
metric | Yes | Stable database metric: cosine, l2, or dot. |
workerUrl | No | Override the adjacent dist/worker.js module URL. |
workerFactory | No | Create a Worker-like object for CSP, bundler, or test integration. |
The name, dimension, and metric are durable schema. Reopening the same name with a different dimension or metric throws SchemaMismatchError; 0.0.1 databases are not migrated.
Worker and CSP
By default, Vecal uses the standard package-relative form:
new Worker(new URL('./worker.js', import.meta.url), {
type: 'module',
name: 'vecal:documents',
});If your Content Security Policy needs an explicit asset URL, deploy the emitted Worker module together with its adjacent internal modules:
const db = await VectorDB.open({
name: 'documents',
dimension: 384,
metric: 'cosine',
workerUrl: new URL('/vecal/dist/worker.js', location.origin),
});Or let your application bundler compile an app-local Worker entry:
const db = await VectorDB.open({
name: 'documents',
dimension: 384,
metric: 'cosine',
workerFactory: () =>
new Worker(new URL('./vecal.worker.ts', import.meta.url), { type: 'module' }),
});import { startVecalWorker } from 'vecal/worker';
startVecalWorker();Serve Worker modules with JavaScript MIME type and allow their origin in worker-src. Vecal intentionally has no main-thread storage/search fallback: if the Worker cannot start, open() fails.
SSR frameworks
The package can be imported on a server, but only call VectorDB.open() from a client component, effect, browser event, or other client-only path.
'use client';
import { useEffect } from 'react';
import { VectorDB } from 'vecal';
export function SearchClient() {
useEffect(() => {
let disposed = false;
let database: Awaited<ReturnType<typeof VectorDB.open>> | undefined;
void VectorDB.open({ name: 'search', dimension: 384, metric: 'cosine' }).then((db) => {
if (disposed) void db.close();
else database = db;
});
return () => {
disposed = true;
void database?.close();
};
}, []);
return null;
}Compatibility
Vecal supports the latest two releases of Chrome, Firefox, and Safari. It requires IndexedDB, Dedicated Workers, module Workers, structured clone, BroadcastChannel for fast cross-tab notification, and crypto.randomUUID() for generated IDs. Authoritative revision checks still protect operation-boundary consistency when a notification is delayed.