Developer documentation

SeekySense SDK

A JavaScript library that adds search by meaning, duplicate detection, cited answers and other AI features to an existing web application. Models run in the user's browser, so the backend stays as it is.

Version 1.1.0-rc.1 ES modules and classic script TypeScript types Get the SDK Integration strategies

Goals

Business applications already hold the data their users search for: items, customers, tickets, documents, menus. What they usually lack is search that understands intent, in any language, and tolerates the words people actually type. Adding it the usual way means a new service, a vector database, an embedding API and a bill that grows with every query.

The SDK takes a different route. It brings the model to the data that is already on screen:

  • No backend changes. Records come from the API you already have. Embeddings, indexes and ranking are computed in the browser.
  • No per query cost. The model is downloaded once and cached; searches are local and take milliseconds.
  • Private by construction. Queries, records and vectors stay on the device. The SDK can prove it at runtime.
  • Never broken. When a device cannot run a model, the same call answers by exact words and tells you why.
  • Under your control. Every optional capability is off until you switch it on, and every switch can be inspected.

Architecture

The SDK is a set of ES modules loaded by your page. Heavy work runs in Web Workers; data persists in the browser's own storage. Your server keeps serving JSON, exactly as today.

SeekySense SDK architecture The web application uses the SDK in the page. The SDK keeps collections with a word index and a vector store, runs models in an engine worker and scoring in a scoring worker, and stores vectors and models in browser storage. The server is unchanged and optionally serves snapshots. BROWSER Your web application ERP, CRM, help desk, shop: grids, menus, forms, search boxes SeekySense SDK (in the page) Collections records, fingerprints word index vector store Engine ladder words light model (no GPU) transformer Feature control presets, switches state and reasons download plan Workers model on WebGPU or WebAssembly, scoring Browser storage vectors and records, model files One model can serve every open tab of the application. Nothing in this box sends your data anywhere. YOUR SERVER, UNCHANGED Existing API the JSON you already serve Static snapshots optional: indexes built in CI served as plain files Your vector database optional: pgvector, Qdrant, Elasticsearch, behind your API Model files public mirror or self-hosted Dashed: used only by the integration strategy you choose.
Solid arrows are always present; dashed ones depend on the integration strategy. Model files are downloaded once per device and then read from the browser's storage.

Where each part runs

PartRuns inResponsibility
CollectionPageYour records, change detection, word index, vector store, search API
EngineEngine workerLoads the model, turns text and images into vectors, optional reranker and generator
ScoringScoring workerCompares a query with every stored vector without blocking the page
StorageIndexedDB, Cache Storage or OPFSVectors and records survive reloads and work offline; model files are cached
UI layerPageWeb Components and adapters for React, Vue and Angular, all optional

Models and the engine ladder

A profile describes a model: where it lives, what it needs and how to read its scores. With profile: 'auto' the SDK checks the device and picks the best profile it can run.

ProfileNeedsDownloadLanguagesLicence
gemma-multimodal
EmbeddingGemma 2
WebGPU203 MB, images +104 MB100+, text, images, video framesGemma Terms of Use
granite-multilingual
Granite Embedding 97M R2
WebAssembly, any modern browser117 MB200+, textApache-2.0
compact
all-MiniLM-L6-v2
WebAssembly28 MBEnglish onlyApache-2.0

The automatic chain is gemma-multimodal, then granite-multilingual. The English-only profile is never chosen automatically: on non-English data its quality drops too far to happen silently. You can still select it by name, or put it in your own order. Custom profiles accept any compatible ONNX sentence-embedding model, including your own fine-tuned one.

The engine ladder

Search always answers with the best rung that is ready, and says which one in result.tier:

  1. Words: exact and typo-tolerant matching. Available immediately, on every device.
  2. Light model (optional): multilingual static embeddings, no GPU, sub-millisecond queries.
  3. Transformer: the profile's full model, once downloaded and warm.

Records added while a model was still loading are embedded automatically when it becomes ready.

Data and indexing

A collection is a named set of your records. You decide which fields are embedded and which ones the word index sees. Each record gets a content fingerprint: on the next update, unchanged records cost nothing.

const items = seeky.collection('items', {
  id: (r) => r.code,
  fields: (r) => ({ title: r.description, text: `${r.category}. ${r.description}` }),
});
await items.sync(rowsFromYourApi);                 // add, update and remove in one call
await items.applyChanges({ upserts, deletes, cursor }); // or a delta feed from your backend
Persistence
IndexedDB by default: after a reload, search works before your API answers, and offline.
Profile change
Records are kept and re-embedded automatically; your application sends nothing again.
Several tabs
Changes made in one tab reach the others without a new download or a new embedding.
Snapshots
A collection exports to a compact binary file, and to deltas between versions or to shards for large catalogues.

Feature control

Every optional capability sits behind a switch. With no configuration the SDK behaves like its base release. A preset is a readable starting point; each switch can be set per instance, per collection or per call, and changed at runtime.

const seeky = createSeekySense({
  profile: 'auto',
  preset: 'balanced',                    // 'compat' | 'balanced' | 'max'
  features: { rerank: true, similar: true },
});
seeky.features().rerank;    // { requested, active, reason, fallback, downloadMb, hosts, sendsData }
await seeky.plan();          // every file, host and megabyte, before anything is fetched
seeky.configure({ preset: 'compat' });   // back to the base behaviour in one call

A feature that cannot run on a device falls back to its documented behaviour and reports the reason in plain words, ready to show to a user. Features that need explicit consent, such as generated answers or learning from clicks, are never part of a preset.

Capabilities

Fast at scale

Scoring in a worker on WebAssembly or WebGPU; a million vectors searched in tens of milliseconds.

Works without a GPU

A multilingual WebAssembly model and an optional light model keep every device useful.

Similar and duplicates

Records like this one, duplicate groups with field confirmation, a check before insert.

Business vocabulary

Glossaries and acronyms, pinned and boosted results, filters read from the query in Italian, English and German.

Reranker

A second, finer reading of the first results, on the device.

Cited answers

Answers built only from your records, each sentence citing its source; refusal when nothing relevant is found. Structured extraction from text.

Learns from use

Results chosen by users rise for similar queries, locally, with suggested thresholds you decide whether to apply.

Provable privacy

A log of every request the SDK made, a host allow-list, and proof that nothing left the page after loading.

Ready-made UI

A search box and a command palette as Web Components, plus React, Vue and Angular adapters.

Integration strategies

Pick the strategy that matches your constraints. They combine: most teams start with A and add the others where they pay off. Each example below is complete and runs as is.

Strategy A

Frontend only, on the API you already have

Load your records as today, hand them to a collection, search. The first visit embeds the records on the device; later visits reuse what is stored. Ideal for catalogues and lists up to tens of thousands of records per user.

import { createSeekySense } from 'https://www.seekysense.com/sdk/1.1.0-rc.1/seekysense.esm.js';

const seeky = createSeekySense({ profile: 'auto' });
const items = seeky.collection('items', { fields: (r) => ({ title: r.name, text: r.description }) });
await items.sync(await (await fetch('/api/items')).json());
const { hits } = await items.search(userInput);
Quick startHybrid search with a consent step before the model download.Run
Existing ERP gridOne call connects a grid you already have; filters such as "under 20 euro" are read from the query.Run
Strategy B

Indexes built in CI, served as static files

For large catalogues, or devices that should not embed anything, build the index in your pipeline with the SeekySense command line tool and publish it as a file next to your assets. Clients download it once and only embed their own queries. Deltas and shards keep updates small.

# in CI
seekysense build --input items.json --config seeky.config.mjs --out items.sks1 --previous items.sks1

// in the page
await items.import(await (await fetch('/static/items.sks1')).arrayBuffer());

The command line tool is provided to licensees.

Strategy C

Your vector database, embeddings from the browser

If you already run pgvector, Qdrant or Elasticsearch, keep it. The browser computes the vectors; three small functions you write move them through your own API, with your authentication and tenancy. The word index, fallback and ranking stay in the SDK.

const store = new RemoteVectorStore({
  search: (vector, { limit }) => api.post('/vectors/search', { vector, limit }),
  upsert: (rows) => api.post('/vectors', rows),
  remove: (ids) => api.post('/vectors/delete', ids),
});
const items = seeky.collection('items', { store, fields });
Strategy D

Drop-in UI

For screens where you do not want to write UI code: a search box and a command palette as Web Components, styled with CSS variables. In React, Vue or Angular, use the adapters instead.

<seeky-command-palette collection="screens"></seeky-command-palette>
import { defineElements } from 'https://www.seekysense.com/sdk/1.1.0-rc.1/seekysense-ui.esm.js';
defineElements(seeky);
Command paletteUsers type what they need, in any language, and land on the right screen.Run

Beyond search

Duplicate customersGroups of duplicate accounts confirmed by VAT number, and a warning before a duplicate is saved.Run
Compatibility checkWhat a browser can run and what would be downloaded, before anything is downloaded.Run

Performance

Measured in Chrome on an Apple Silicon laptop. Each search compares the query with every stored vector; model time is excluded. Slower hardware will be slower: run the compatibility example on your target devices.

ScenarioSearch timePage blocked per search
100,000 records × 768 dimensions, base behaviour150 ms150 ms
Same, WebAssembly scoring in a worker9 msabout 1 ms
Same, WebGPU scoring in a worker5 msabout 1 ms
1,000,000 records × 256 dimensions, WebGPU26 msabout 11 ms
Query embedding, model warm13 to 18 ms0 ms (worker)
Model start from cache0.2 to 1.7 s0 ms (worker)
Accelerated scoring returns the same top results as the base behaviour: the speed comes from where and how the work runs, not from looser matching.

Security and privacy

  • Data stays on the device. The SDK sends no telemetry. The only downloads are the model files and the runtime, from the hosts you allow.
  • Host allow-list. privacy.allowHosts blocks any SDK request to another host before it is made.
  • Runtime proof. seeky.networkProof() lists every request the SDK made, including those of its workers, and confirms that none happened after the model was ready.
  • Integrity. Every published file has a sha384 hash for Subresource Integrity.
  • Closed networks. The SDK, the runtime and the models can all be served from your own servers; with an empty allow-list nothing leaves your origin.

A Content Security Policy for the default hosts:

script-src 'self' 'wasm-unsafe-eval' https://www.seekysense.com https://cdn.jsdelivr.net;
worker-src 'self' blob:;
connect-src 'self' https://www.seekysense.com https://cdn.jsdelivr.net https://huggingface.co https://*.huggingface.co https://*.hf.co;

Browser support

BrowserWhat runs
Chrome, Edge, Opera 113+ (desktop)Everything, including the multimodal model on WebGPU
Safari 26+, Chrome on recent AndroidWebGPU model on supported GPUs, multilingual WebAssembly model otherwise
Firefox, older Safari, other devicesMultilingual WebAssembly model; words only if memory is too low

detectCapabilities() and recommendProfile() answer the question for a given device before any download, with reasons and suggested actions you can show to users.

Get the SDK

Version
1.1.0-rc.1
Base URL
https://www.seekysense.com/sdk/1.1.0-rc.1/
Download
seekysense-sdk-1.1.0-rc.1.zip (146 KB, for self-hosting)
Types
index.d.ts, ui.d.ts
Integrity hashes
sri.json

As an ES module

import { createSeekySense } from 'https://www.seekysense.com/sdk/1.1.0-rc.1/seekysense.esm.js';

As a classic script

<script src="https://www.seekysense.com/sdk/1.1.0-rc.1/seekysense.iife.js"
        integrity="sha384-ML/wpXoxGgJqxJMpCE3lCn9oooBKe9qcetj2TQ0dp3vkSqmpoOMps/TRsk+yJ6Go"
        crossorigin="anonymous"></script>
<script> const seeky = SeekySense.createSeekySense(); </script>

The worker files are loaded from the same folder as the bundle, also when your page is on another domain. To self-host, copy the folder from the zip and load the bundle from there.

Licence

For licensing, an evaluation or integration support, contact us.

Contact us