Fuzzy search that earns its rank.
A practical system for imperfect input, weighted fields, explicit closeness scores, and opt-in matching behavior. Built for static SPAs. Useful far beyond command palettes.
Closeness is the invariant.
The engine always returns ranked matches. Features change what counts as a match. They do not change the result contract.
A small, inspectable ranking pipeline.
Normalization and indexing happen once. Query parsing, enabled match strategies, weighted aggregation, and stable sorting happen for each search.
flowchart LR
A[Structured records] --> B[Normalize fields]
B --> C[Build lightweight records]
Q[User query] --> D[Parse query]
D --> E[Run enabled match strategies]
C --> E
E --> F[Apply field weights]
F --> G[Combine token coverage]
G --> H[Optional bounded boost]
H --> I[Threshold + stable sort]
I --> R[rank · score · distance · matches]
Mermaid source
flowchart LR A[Structured records] --> B[Normalize fields] B --> C[Build lightweight records] Q[User query] --> D[Parse query] D --> E[Run enabled match strategies] C --> E E --> F[Apply field weights] F --> G[Combine token coverage] G --> H[Optional bounded boost] H --> I[Threshold + stable sort] I --> R[rank · score · distance · matches]
Change the behavior. Keep the contract.
This lab runs the embedded SlimSearch engine against structured datasets. Every result reveals its score, distance, matched field, and winning strategy.
Opt in by search need.
Start with prefix, substring, and ordered subsequence matching. Add typo tolerance, acronyms, operators, or synonyms only when the corpus and user behavior justify them.
prefix · word · substring · subsequence→Fuzzy
typos · transpositions→Command
acronyms · camelCase→Full
operators · synonyms
flowchart TB
M[Minimal core] --> P[Prefix + word boundary + substring + subsequence]
P --> F[Fuzzy preset]
F --> T[Typo + transposition tolerance]
T --> C[Command preset]
C --> A[Acronyms + camelCase]
A --> X[Full preset]
X --> O[Operators + synonyms]
Mermaid source
flowchart TB M[Minimal core] --> P[Prefix + word boundary + substring + subsequence] P --> F[Fuzzy preset] F --> T[Typo + transposition tolerance] T --> C[Command preset] C --> A[Acronyms + camelCase] A --> X[Full preset] X --> O[Operators + synonyms]
Drop-in JavaScript. No build step.
The browser global exposes a small create/search API. Data remains ordinary objects. Results remain inspectable.
<script src="./slim-search.js"></script>
<script>
const search = SlimSearch.create(items, {
preset: 'fuzzy',
keys: [
{ name: 'title', weight: 6 },
{ name: 'aliases', weight: 4 },
{ name: 'keywords', weight: 2 },
{ name: 'description', weight: 1 }
]
});
const results = search.search(query, {
limit: 8,
threshold: 0.30,
includeMatches: true
});
</script>
One ranker. Multiple retrieval surfaces.
Commands are one corpus type. The same weighted contract supports navigation, settings, saved objects, local documentation, help routing, and constrained conversational flows.
A conversational router without an LLM.
Fuzzy retrieval can emulate a narrow chatbot when intents, utterances, slots, confidence gates, and responses are explicit. It is a state machine with a conversational surface.
flowchart LR
U[User text] --> N[Normalize]
N --> R{Exact rule?}
R -->|yes| A[Execute intent]
R -->|no| F[Fuzzy-rank utterances]
F --> B[Apply state boost]
B --> G{Score + margin pass?}
G -->|yes| S[Extract and validate slots]
S --> A
G -->|no| C[Constrained clarification]
A --> T[Approved response template]
Mermaid source
flowchart LR
U[User text] --> N[Normalize]
N --> R{Exact rule?}
R -->|yes| A[Execute intent]
R -->|no| F[Fuzzy-rank utterances]
F --> B[Apply state boost]
B --> G{Score + margin pass?}
G -->|yes| S[Extract and validate slots]
S --> A
G -->|no| C[Constrained clarification]
A --> T[Approved response template]Choose the matching model, not the logo.
Small launchers, object search, and full-text retrieval are different workloads. Bundle size matters. Ranking transparency and corpus fit matter more.
| Engine | Reported size | Core model | Weighted objects | Typo handling | Best fit |
|---|
Benchmark the corpus you actually ship.
The local benchmark below measures this embedded engine. It is directional evidence, not a browser SLA.
Method
Node.js 22.16.0. Four weighted fields. Ten fuzzy queries. Forty warmups. Eight measured rounds. Median milliseconds per query.
Operating envelope
Search directly for hundreds of short records. Debounce and limit rendering as the corpus grows. Move indexing or search to a worker when main-thread latency becomes visible.
Artifact size
21,747 bytes readable source. 5,549 bytes with gzip level 9. Mermaid is loaded separately and is not part of the search engine size.
Relevance is a tested product behavior.
A ranker is not complete when it returns results. It is complete when expected records consistently occupy the expected positions.
Claims mapped to primary sources.
Generated July 19, 2026. Library capabilities and reported sizes use project documentation. SlimSearch sizes and performance use local measurements recorded in this artifact.