Lunr.js

JavaScript-only client-side search. The original Pagefind, now mostly superseded.

VISIT LUNR.JS

Key takeaway: New projects should not start here. Lunr predates build-time WASM indexes and ships the whole index to the browser as JSON, which stops being viable well before Pagefind does. Keep it if you already run it on a small site. Choose it deliberately only when you need to build an index in the browser at runtime, which is the one thing Pagefind cannot do.

Quick facts

  • CategoryEmbedded / static
  • EngineJavaScript
  • PricingOpen source
  • LicenseMIT
  • Created2013
  • GitHub stars9k
  • Vector supportNo
  • Edge-readyYes

What it is

Lunr.js is a small full-text search library for the browser, modelled on Solr. Pre-Pagefind era, works but the index ships as JSON which gets large fast. Maintained but feature pace has slowed.

Best for

  • Existing Lunr deployments, stable
  • Tiny static sites with under ~500 pages where Pagefind feels like overkill

When not to pick it

For new projects in 2026, Pagefind is a better default, smaller index, faster query, better DX.

My take

Pre-Pagefind era. Lunr is fine for the legacy use case but new projects should pick Pagefind.

The JSON index is the whole constraint

Lunr builds an inverted index modelled on Solr and serialises it to JSON. Everything good and bad follows from that one decision. Good: no build tooling, no binary, no WASM, it runs in any JavaScript runtime, and you can construct the index at runtime from data the page already has. Bad: the entire index is a single download the visitor pays for before the first query resolves, and it grows roughly with the corpus. A few hundred pages is fine. A few thousand and you are shipping a payload that competes with your actual page weight, then parsing it on the main thread while the page is trying to become interactive. There is no chunking, no lazy loading, and no way to fetch only the postings a query needs. Pagefind exists because that ceiling is real and people kept hitting it.

The narrow case where Lunr is still the pragmatic pick

Two situations survive. The first is a deployment that already works. Lunr is stable and maintained, and rewriting a search box nobody complains about is a poor use of a sprint. The second is search over data that does not exist at build time: a client-rendered app searching a JSON payload it just fetched, an offline tool, a browser extension or an Electron context where no post-build crawl step is available. Pagefind assumes a static build it can read; Lunr assumes nothing but a JavaScript runtime. Two things to know before you commit either way. Language support beyond English requires the separate lunr-languages package, and stemming quality varies noticeably by language. Feature development has slowed, so treat what exists today as what you get.

Frequently asked questions

Is Lunr.js still maintained?

It is maintained in the sense that it works and is not abandoned, but feature development has slowed considerably and it is no longer where the category is moving. For an existing deployment that is fine, since a small search index is not something that rots. For a new build, pick something with active development behind it.

Lunr or Pagefind?

Pagefind for anything new with a static build. It produces a much smaller download because the index is chunked and fetched on demand rather than shipped whole, and query performance is better because the work happens in WASM. Lunr only when you cannot run a post-build step, or when the index must be built in the browser from data fetched at runtime.

How big can a Lunr index get?

Bigger than you want, quickly. Because the serialised JSON index downloads in full before the first query, practical comfort runs out somewhere in the low thousands of documents, earlier if pages are long. Watch the transferred size and the main-thread parse cost rather than the document count. Once either becomes noticeable, move to Pagefind.

Links

Similar tools you should also consider

If Lunr.js is your pick, the next conversation is short

The 30-min call is where your search choice becomes a real architecture, a relevance-tuning plan, and a price range you can take to your stakeholders.