Pagefind vs Lunr for Small Documentation Sites

For a large site the search question is settled: a single client-side index does not scale, and Pagefind or a hosted service is the answer. For a small documentation site — a library with 100 to 300 pages — it is genuinely open. Lunr, the long-standing client-side search library, builds one index that the browser downloads once; on a small site that file is tiny, and every query after it is instant. Pagefind splits its index into fragments and fetches only what each query needs, which is the right design at scale but adds requests at small sizes.

This comparison builds both for the same 150-page documentation site (an open-source CLI tool, built with Eleventy), measures index size, first-query time, relevance on 25 real queries and setup effort, then grows the content synthetically to find where one overtakes the other. It belongs to Search for Static Sites; the Lunr setup is covered in depth in Building a Lunr Index at Build Time in Eleventy.

Method

  • Content: 150 pages, about 104,000 words of prose and code, English only.
  • Lunr 2.3.9: index built at build time in an Eleventy eleventy.after hook with title (boost 10), headings (boost 5) and body fields; serialised to JSON with a separate document store for result titles and excerpts.
  • Pagefind 1.3: default settings with data-pagefind-body on the article element, default UI.
  • Measurement: Chrome DevTools with a Moto G Power profile on Fast 4G, cold cache, median of nine runs; brotli compression from Cloudflare.
  • Relevance: 25 queries from the project's issue tracker, each with an expected best page, scored by whether it appeared first or in the top three.

Index Size and Transfer

MeasureLunrPagefind
Index on disk1.1 MB (index + store)2.4 MB across 410 files
Transferred for first query96 KB (one file)62 KB (entry, wasm, 3 fragments)
Transferred per later query0 KB4–14 KB (new fragments)
JavaScript for search29 KB (lunr) + 6 KB (UI code)22 KB (UI) + 52 KB wasm (once)

At 150 pages the totals are close. Lunr downloads everything once; Pagefind downloads a little per query.

Milliseconds to first results on a throttled phone Vertical bars. Lunr took 410 milliseconds to first results, mostly downloading and deserialising the single index. Pagefind took 520 milliseconds, spread across loading the entry file, the WebAssembly module and three index fragments. Later queries took 8 milliseconds in Lunr and 60 to 120 milliseconds in Pagefind when new fragments were needed. Time from opening search to first results 410 ms Lunr first query 520 ms Pagefind first query 8 ms Lunr later query 90 ms Pagefind later query
Moto G Power profile, Fast 4G, cold cache, median of nine runs on the 150-page site.

Relevance

Measure (25 queries)LunrPagefind
Expected page first1719
Expected page in top 32223
Typo tolerance ("confgure")With ~1 fuzzy syntax onlyNo (exact stems)
Partial words ("conf")With trailing * onlyYes, prefix by default

Both were good on this content. Pagefind won slightly through prefix matching and better default stemming; Lunr needed query rewriting (appending * to the last term) to match as-you-type behaviour, which the site's UI code did.

Setup and Maintenance

WorkLunrPagefind
Build integration~60 lines (build index, store)1 command
Browser code~120 lines (load, query, highlight, render)3 lines + CSS
Accessibility of UIHand-built, audited separatelyDefault UI is keyboard and screen reader friendly
MultilingualPlugins per language, frozenBuilt in, index per lang
Maintenance statusLast release 2020Active

The setup gap is the most decisive difference for a small team. Pagefind's whole integration is a build step; Lunr's is a small search application to write, test and maintain. Accessible Search UI for Static Sites describes how much work a hand-built search UI takes to get right.

Comparison matrix of Pagefind and Lunr on six criteria A matrix of six criteria. First query speed at 150 pages favours Lunr slightly. Later query speed favours Lunr. Scaling with site size favours Pagefind strongly. Setup effort favours Pagefind. Default relevance is good for both, slightly better for Pagefind. Maintenance favours Pagefind, as Lunr has had no release since 2020. Pagefind and Lunr against the criteria Criterion Lunr Pagefind First query at 150 pages 410 ms 520 ms Later queries instant 60–120 ms Growth to 1000+ pages index grows linearly per-query cost flat Setup effort ~180 lines one command Relevance on 25 queries 17 first 19 first Maintenance no release since 2020 active
Lunr wins on raw speed at small sizes; Pagefind wins on everything that costs the team time.

Where the Crossover Is

To find the size at which Lunr stops being comfortable, the content was duplicated with varied text to 300, 600, 1,000 and 2,000 pages and both were measured again:

Milliseconds to first results for Lunr and Pagefind by site size Paired bars by page count. At 150 pages Lunr took 410 and Pagefind 520 milliseconds. At 300 pages 560 and 530. At 600 pages 820 and 540. At 1,000 pages 1,180 and 560. At 2,000 pages 2,150 and 590. First query time as the site grows Lunr Pagefind 150 pages 410 ms 520 ms 300 pages 560 ms 530 ms 600 pages 820 ms 540 ms 1,000 pages 1180 ms 560 ms 2,000 pages 2150 ms 590 ms
Same device profile; Lunr's single index grew by about 0.6 KB compressed per page, Pagefind's per-query transfer stayed nearly flat.

The lines cross at about 300 pages. Below that, Lunr is marginally faster to first result; above it, Pagefind is faster and the gap grows quickly. Lunr's index can be trimmed — indexing only titles, headings and the first paragraph of each section halved it on this site — which moves the crossover to about 600 pages, at the cost of relevance on body text.

Operational Differences

Two operational details are easy to miss when comparing the libraries on a laptop. The first is caching. Lunr's single index file changes whenever any page changes, so every deploy invalidates the reader's cached copy and the next search downloads the whole index again. Pagefind's fragments are content-hashed and change only when the words they hold change; after a typical one-page edit on this site, 97% of fragment files were byte-identical to the previous deploy, so returning readers' caches stayed warm. On a site deployed several times a day, that difference shows up in CDN bandwidth as well as in search speed.

The second is build integration. Lunr's index is built inside the generator, usually in a template or an Eleventy event, which means a bug in the indexing code can fail the whole build, and changing the generator means rewriting the indexer. Pagefind runs on the finished HTML after any generator, so the same configuration survived when another project on the same team moved from Eleventy to Astro without touching search at all. For teams that expect to change generators at some point, that independence is worth more than a hundred milliseconds of first-query time.

Finally, both libraries index only what is in the HTML they are given. Content rendered by client-side JavaScript — tabs populated at runtime, API tables fetched on load — is invisible to both, so the guidance about rendering searchable content at build time applies equally whichever you choose.

Migrating From Lunr to Pagefind

For the test site, replacing Lunr took under two hours: delete the indexing hook and the browser search code, add data-pagefind-body to the article element, add pagefind --site _site to the build script, and mount the default UI where the old search box was. The 25-query relevance check ran before and after to confirm nothing regressed.

Verdict

  • Choose Pagefind for almost every new documentation site. It is faster above about 300 pages, needs no search code, has an accessible UI out of the box, and is maintained.
  • Keep Lunr if you already have a working, accessible Lunr integration on a site that will stay under a few hundred pages; there is no urgent reason to replace it. If you prefer the single-index model for a new small site, consider MiniSearch, which is maintained.

Pitfalls

  • Judging Pagefind on first-query time alone at small sizes. The difference is about 100 ms and reverses as the site grows.
  • Shipping Lunr's full document store. Store only titles, URLs and short excerpts.
  • Forgetting accessibility in a hand-built Lunr UI. It is most of the work.
  • No compression on the host. Lunr's JSON index compresses about 10×.

Conclusion

On a 150-page documentation site Lunr and Pagefind are close: Lunr is about 100 ms quicker to the first result, Pagefind slightly more relevant. Everything else favours Pagefind — no search code to maintain, an accessible UI, active development, and per-query cost that stays flat as the site grows past the 300-page crossover. For a new small site, Pagefind is the better default; an existing good Lunr setup can stay until the site outgrows it.

FAQ

Is Pagefind always better than Lunr?

Not for very small sites. On the 150-page site in this guide, Lunr's single prebuilt index was 96 KB compressed and returned first results faster than Pagefind, which needs several fragment requests per query. Pagefind becomes the better choice as the site grows, and it requires less code at any size.

At what size does Lunr stop being practical?

When the index download becomes noticeable on a phone. In the measurements here, Lunr's compressed index grew by about 0.6 KB per page of typical documentation prose, so around 800 to 1,000 pages it passes 500 KB and the first query on a mid-range phone takes over a second. Pagefind's per-query transfer stayed roughly flat as the site grew.

Is Lunr still maintained?

Lunr 2.3.9 was released in 2020 and has had little activity since. It is stable and works, but its stemming and language support are frozen. MiniSearch is an actively maintained alternative with the same single-index model and a similar API, worth considering if you prefer that model.

Which is easier to set up?

Pagefind. It runs as one command after the build and ships a ready-made UI. Lunr needs code at build time to create and serialise the index, and code in the browser to load it, run queries, highlight matches and render results, which on the site in this guide was about 180 lines.

Filed underComparisonsPagefind