Getting started

From purchase to live: one zip, three commands and a script tag. No server to run, no API key to manage, no per-query fee — search runs on the visitor's own device.

1. Purchase and zip

After paying you are redirected to a thank-you page. It shows your licence key and the download link. The key looks like this:

LE-XXXX-XXXX-XXXX-XXXX

Keep the key. There are no accounts and no passwords here; the key is your identity. You will use the same key to download updates. If you lose it, email us and we will find it from your order.

The zip contains:

lightembed-1.0.0.zip
├── model-tr-1.0.0.bin          the model, fingerprinted to you
├── lightembed-cli-1.0.0.tgz    command-line tool
├── lightembed-client-1.0.0.tgz browser client and search widget
├── LICENCE.txt                 licence text and your key
└── docs/                       an offline copy of this page

2. Install

Nothing is published to the npm registry; you install from inside the zip:

unzip lightembed-1.0.0.zip -d lightembed
cd lightembed
npm install ./lightembed-cli-1.0.0.tgz ./lightembed-client-1.0.0.tgz

This install never touches the network — the packages have no dependencies, and the search engine (WebAssembly) ships inside the CLI package. To check:

npx lightembed inspect ./model-tr-1.0.0.bin

3. Index your content

If you already have a content directory:

npx lightembed index ./content \
  --model ./model-tr-1.0.0.bin \
  --out ./public/lightembed \
  --base-url https://yoursite.com

If all you have is the live site, download it first:

npx lightembed crawl https://yoursite.com/docs/ --out ./content

crawl mirrors the site's URL structure onto disk, so the result links point at real pages. It obeys robots.txt, fetches serially with a delay, and exits non-zero if it fetched nothing rather than quietly leaving you an empty directory.

The setting that needs the most care: --content-selector. When indexing HTML it decides which part of the page counts as content (main, .article, #content). Get it wrong and the index holds your navigation and footer instead of your article — search does not "break", it talks nonsense. That is why a selector matching no file is an error.

4. Add search to your page

The ready-made component — one script tag and one element:

<script type="module" src="/lightembed/widget.mjs"></script>
<lightembed-search src="/lightembed" hotkey="cmd+k" placeholder="Search the docs…">
</lightembed-search>

Or drive it yourself:

import { createSearch } from 'lightembed-client';

const search = await createSearch('/lightembed');

// Warm on focus: the download happens while the user types, so the first
// search feels like the tenth.
input.addEventListener('focus', () => search.warm());

const hits = await search.query('how do I get a tax refund', { topK: 5 });

Copy public/lightembed/ to any static host. Nothing in it needs a server.

What downloads, and when

MomentBytes (gzip)
Page load8.2 KB — manifest, widget and client
Visitor focuses the search boxengine 48 KB + model 2.58 MB + index
Every search after that0

A visitor who never searches pays 8.2 KB. One who does pays once, while typing.

5. Updating

Re-run lightembed index whenever your content changes. When a new model version is released:

npx lightembed update --key LE-XXXX-XXXX-XXXX-XXXX
npm install ./lightembed-update/lightembed-cli-<new>.tgz

The command downloads the newest release your licence covers and unpacks it into ./lightembed-update/. Swap in the new model file. Every update is included for the first 12 months; after that renewing is an optional $10/year, and if you skip it the version you have keeps working forever.

Whether a model change forces a re-index:

Model changeIndex
1.2.0 → 1.2.1stays valid
1.2.0 → 1.3.0stays valid
1.2.0 → 2.0.0must be rebuilt

A major version moves the embedding space. Comparing a query embedded in the new space against documents embedded in the old one produces confident, wrong results with no other symptom — so the client refuses to search and tells you to re-index, rather than failing quietly.

Troubleshooting

"index was built with model X but Y is loaded" — the model file next to the index is not the one that built it. Re-run lightembed index, or put the right model back.

Results are relevant but the exact term I searched is missing. If the term lives inside a code block, look at --include-code. Otherwise the keyword half of search should have caught it; try raising --lexical-weight (12 for sites where people search part numbers and error codes, 00.5 for sites where they ask questions).

The first search is slow. Call warm() earlier — on focus, or on hover over the search button.

For anything that stays broken: [email protected]. Within 14 days the refund is no-questions too.