Parity Features
Reef Search now matches (and exceeds) the capabilities of established search libraries like Fuse.js, MiniSearch, and Pagefind.
Fuse.js Compatibility
Normalized Scores
Enable includeScore: true to receive 0-1 normalized scores instead of raw additive values:
const results = searchSections(index, {
query: 'search',
includeScore: true
});
// results[0].score: 0.95 (normalized between 0 and 1)
Match Spans
Use includeMatches: true to get character ranges for highlighting:
const results = searchSections(index, {
query: 'install',
includeMatches: true
});
// results[0].matches: [{ key: 'headingText', start: 0, end: 7 }]
Extended Query Syntax
Search supports advanced operators:
// Exact phrase match
searchSections(index, { query: '"exact phrase"' });
// Exclude terms (NOT or -)
searchSections(index, { query: 'install NOT beta' });
searchSections(index, { query: 'install -beta' });
// OR operator
searchSections(index, { query: 'install OR setup' });
Field Weights
Custom scoring weights via weights option:
const results = searchSections(index, {
query: 'search',
weights: { headingText: 100, bodyText: 50 }
});
BM25 Scoring
Enable BM25 (TF-IDF) scoring for more principled relevance ranking across large indexes:
const results = searchSections(index, {
query: 'installation',
scoringAlgorithm: 'bm25',
includeScore: true
});
BM25 considers:
- Document frequency of query terms
- Field length normalization (shorter, more focused matches rank higher)
- Term frequency with saturation
Autocomplete / Suggest
Get search suggestions as users type:
const suggestions = suggest(index, 'inst');
// ['installation', 'instructions', 'instance']
This powers inline suggestions in custom implementations.
Faceted Search
Get counts of indexed records by type:
const counts = facets(index);
// { section: 150, action: 24, field: 12, link: 8 }
Use with filter to build faceted UIs:
const results = searchSections(index, {
query: 'search',
filter: (r) => r.type === 'action'
});
Query Analytics
Track popular queries locally (no backend required):
// Track when users perform searches
trackQuery(index, currentQuery);
// Get most popular queries
const popular = getPopularQueries(index, 10);
// [{ query: 'install', count: 42 }, ...]
Useful for analytics dashboards and improving search UX.
Index Manipulation
Index Mutations
Remove or update records after indexing:
// Remove a record
removeFromIndex(index, 'record-id');
// Update/replace a record
updateRecord(index, {
id: 'record-id',
url: '/new-url',
headingText: 'New Title',
bodyText: 'New content...',
type: 'section'
});
Serialization
Export and import indexes for pre-built search:
// Serialize index to JSON
const json = serializeIndex(index);
// Restore from JSON
const restored = deserializeIndex(json);
Prebuilt Index
Load a pre-built index instead of crawling:
// In browser config
const config: ReefConfig = {
prebuiltIndexUrl: '/search-index.json'
};
Text Processing Pipeline
Stemming & Stop Words
Enable tokenization pipeline for stemming, stop words, and diacritic folding:
const config: ReefConfig = {
tokenizePipeline: [
(tokens) => tokens.map(t => t.toLowerCase()),
(tokens) => tokens.filter(t => !stopWords.has(t)),
(tokens) => tokens.map(t => stem(t))
]
};
Synonym Expansion
Map alternate terms to improve recall:
const config: ReefConfig = {
synonyms: {
'log out': ['sign out', 'logout'],
'log in': ['sign in', 'login'],
'delete': ['remove']
}
};
Diacritic Folding
Automatic accent normalization (café ↔ cafe) can be enabled in the tokenization pipeline.
Feature Comparison
Indexed + Fuzzy
Reef uses inverted indexes for fast candidate shortlisting, then applies fuzzy matching. This outperforms full-scan libraries at scale.
7 Record Types
Unique to Reef: sections, actions, fields, links, files, media, and structured data. No other search library indexes UI controls.
Live DOM Extraction
Reef indexes the real live DOM, extracting actionable elements that generic search libraries cannot see.
Zero Dependencies
Everything runs in the browser using Web APIs. No Node.js, no build step required.
Backward Compatible
Existing SearchSections API continues working. New features are opt-in via configuration options.
Query Caching
LRU cache stores recent queries for faster incremental searches (pric → pricing).