You need search in your application. Not "filter a list by substring" search — real, ranked, relevant search. The kind where typing "javscript tutrial" still finds "JavaScript Tutorial" and the most relevant results appear first. So you look at your options.
The Infrastructure Tax
Elasticsearch
forge/search
Elasticsearch is extraordinary software. It powers search at Netflix, GitHub, and Wikipedia. But it is a distributed Java application that requires dedicated infrastructure, cluster management, and ongoing operational expertise. For the vast majority of applications — those with under 10 million documents — it is like renting a cargo ship to carry a backpack.
Algolia is simpler to operate, but you pay per search operation. At scale, costs climb quickly: $1.50 per 1,000 search requests on their standard plan. An application handling 100,000 searches per day hits $4,500/month in Algolia fees alone.
MeiliSearch and Typesense are lighter alternatives, but they are still separate services. You deploy them, connect to them over the network, and maintain them as part of your infrastructure. Another server to patch. Another service to monitor. Another failure point in your architecture.
What If Search Was Just a Function Call?
forge/search implements the BM25 ranking algorithm — the same algorithm that Elasticsearch uses by default — in pure JavaScript. It runs in your application process. No network calls. No separate service. No infrastructure.
import { createIndex } from '@hyperbridge/forge/search'; const index = createIndex({ fields: { title: { weight: 3.0, stored: true }, body: { weight: 1.0, stored: true }, tags: { weight: 2.0, facet: true }, author: { weight: 1.5, facet: true }, }, language: 'en', }); // Index your documents await index.addDocuments(articles); // Indexes 50,000 documents in ~800ms
BM25 Ranking That Actually Works
BM25 (Best Matching 25) is a probabilistic ranking function that considers term frequency, inverse document frequency, and document length normalization. In simpler terms: it ranks documents higher when they contain your search terms more often, penalizes common words that appear everywhere, and does not unfairly favor long documents over short ones.
// Simple search with BM25 ranking const results = index.search('javascript async patterns'); // → [{ id, title, body, score: 12.847, highlights }] // Search with field boosting const results = index.search('authentication', { boostFields: { title: 5.0 }, limit: 20, offset: 0, });
Fuzzy Matching for Real-World Typos
Users misspell words. They type "authetication" instead of "authentication", "recieve" instead of "receive". A search engine that only does exact matching is a search engine that frustrates users.
// Fuzzy search with configurable edit distance const results = index.search('javscript tutrial', { fuzzy: true, maxDistance: 2, }); // → Finds "JavaScript Tutorial" (distance 1 + distance 1) // Prefix matching for autocomplete const suggestions = index.search('reac', { prefix: true, limit: 5, }); // → "React", "Reactive", "React Hooks", ...
Faceted Search for Filtering
E-commerce sites, documentation browsers, and content platforms need faceted search: filtering by category, tag, date range, or any other attribute while showing aggregated counts. Elasticsearch excels at this — but forge/search handles it too.
const results = index.search('state management', { facets: ['tags', 'author'], filters: { tags: ['react', 'javascript'], }, }); // results.facets: // { // tags: { react: 45, javascript: 38, vue: 12, svelte: 8 }, // author: { "Dan Abramov": 6, "Ryan Carniato": 4, ... } // }
Geosearch for Location-Aware Apps
// Index documents with coordinates const geoIndex = createIndex({ fields: { name: { weight: 2.0 }, cuisine: { facet: true }, }, geo: { field: 'location' }, }); // Find restaurants within 2km const nearby = geoIndex.search('biryani', { geoWithin: { center: { lat: 13.0827, lng: 80.2707 }, // Chennai radiusKm: 2, }, sortBy: 'distance', });
Multilingual Support
// Built-in stemmers and stop words for 15+ languages const frIndex = createIndex({ fields: { titre: { weight: 2 }, contenu: {} }, language: 'fr', }); // French stemmer: "mangeons" → "mang", "mangez" → "mang" // Multi-language index const multiIndex = createIndex({ fields: { title: {}, body: {} }, language: 'auto', // detect per-document });
Performance at Scale
The natural question: can an in-process JavaScript search engine actually perform? We benchmarked forge/search against a 3-node Elasticsearch cluster using the English Wikipedia dataset (6.7 million articles).
For datasets under 1 million documents, forge/search matches or beats Elasticsearch on query latency — because there is zero network overhead.
At 100,000 documents (a typical SaaS application), forge/search returns BM25-ranked results in 2-8ms. That is faster than the network round-trip to Elasticsearch alone, which typically adds 5-15ms even on the same VPC. Indexing 100,000 documents takes approximately 1.6 seconds, and the resulting index consumes around 45MB of memory.
At 1 million documents, query times increase to 15-40ms — still well within acceptable latency for user-facing search. The index occupies roughly 400MB of memory. For most applications, this is entirely reasonable.
At 10 million documents and beyond, you probably do need a dedicated search service. forge/search is not trying to replace Elasticsearch for petabyte-scale log analytics or billion-document search. It is replacing it for the 95% of applications where Elasticsearch is overkill.
Persistence and Serialization
// Serialize index to disk or storage const snapshot = index.serialize(); await writeFile('search-index.bin', snapshot); // Restore in ~50ms (no re-indexing) const data = await readFile('search-index.bin'); const restored = createIndex.fromSnapshot(data);
The serialized format is a compact binary representation that loads orders of magnitude faster than re-indexing from source documents. Ship a pre-built index with your application, or store it in S3 and load it on server start.
When to Reach for Elasticsearch
If you need distributed search across multiple nodes, real-time log aggregation, or complex analytics queries across billions of documents — use Elasticsearch. It is purpose-built for that scale.
But if you are building a blog with search, a SaaS product search, documentation search, an e-commerce catalog under a million products, or any application where search is a feature rather than the product itself — you do not need a $500/month cluster. You need a function call.
HBForge is currently available exclusively for enterprise clients. Opening to the Developer Community on June 25, 2026.
Contact kr@hyperbridge.in for early access.