---
title: Search
description: Lexical out of the box, semantic when you want it — both pure JavaScript.
section: Concepts
order: 1
sources: [packages/kura/**, packages/docs/src/search.ts]
---

# Search

Every Kura site ships with search built in. It comes in two flavors, and you choose per project.

## Lexical (default)

Out of the box, search is **lexical**: a zero-dependency keyword scan over your content. It needs
no model, no native modules, and no services — so a new site installs clean and deploys to
Cloudflare Workers (or anywhere) with nothing to provision. For most docs sites, this is enough.

## Semantic (opt-in)

Add an **embedder** to upgrade the same search box to **semantic** retrieval — matching by meaning,
not just keywords. Kura's retrieval engine is pure JavaScript with zero dependencies and runs the
same code on Node, Bun, Deno, and Cloudflare Workers.

```ts
import { Kb } from "@kurajs/core";
import { transformers } from "@kurajs/transformers";

const kb = new Kb({ embedder: transformers() });
await kb.addText([{ id: "intro", text: "..." }]);
const hits = await kb.searchText("How do I get started?", { topK: 5 });
```

At index time, documents are embedded into 1024-dim vectors with the bge-m3 model; at query time
the question is embedded too, compared by similarity, and the most relevant passages are returned.
On the edge, the same model runs through Cloudflare Workers AI (`@cf/baai/bge-m3`).

### Tiered strategy

- **Small corpora (≤ 10k)**: exact f32 brute force, 100% recall.
- **Large corpora**: a binary prefilter + f32 rerank — 1/32 the memory, with recall still near
  perfect.

### Performance

Query latency is roughly 0.1 ms per 1k vectors; on a real 200k-embedding corpus, binary + rerank
still holds 100% recall.
