lunr-languages review
A multilingual Lunr index sends each word through every selected language's stemmer. That detail matters when you choose between one shared index and separate indexes for each locale. lunr-languages 1.23.0 supplies language plugins for Lunr, including stemming, stopword filtering and tokenization for supported languages. You load the relevant registration modules, then select a plugin inside the index builder. It extends an existing search engine rather than providing a command-line search application. The 1.23.0 release notes list Farsi language support. Use this guide for pipeline selection and loading order; the [Lunr guide](https://mrkeyoor.com/libs/lunr/) covers the parent engine's indexing and query model.
Use lunr-languages when a Lunr integration needs explicit language processing and you can check its matching against your own content. Start with one known locale, then justify a combined pipeline with query examples before shipping it.
Answers from our run
lunr-languages or lunr: which should you use?
lunr: Use core Lunr alone when its default English processing meets your needs. Its registry describes browser full-text search; choose language plugins only when the corpus calls for them. Use lunr-languages when a Lunr integration needs explicit language processing and you can check its matching against your own content.
When should you not use lunr-languages?
You need translation or semantic answers across languages. These plugins process search terms; adding them does not supply a translation model or embeddings.
Use it if
- Your documentation already uses Lunr and needs a supported language's text processing instead of the default English pipeline.
- You can select language modules explicitly and maintain the same registration setup wherever you build indexes.
- You have mixed-language documents and can evaluate the combined pipeline against real queries before choosing it.
- Your Spanish search needs the documented opt-in accent-folding step, and you can configure both indexing and search pipelines.
- You need translation or semantic answers across languages. These plugins process search terms; adding them does not supply a translation model or embeddings.
- Your content has a known locale and you require each word to use only that locale's stemmer. The combined pipeline applies all selected stemmers to every word.
- You need Chinese search in browsers without Intl.Segmenter. The 1.23.0 documentation says there is no browser fallback.
- You expect a standalone search engine or CLI. This package's documented workflow registers plugins on a separately installed Lunr object.
- You cannot evaluate language-specific matching on your corpus. A list of supported languages does not establish that your spelling, names or terminology will match well.
Setup reality
Install Lunr separately, then load stemmer support before the chosen language module. Registering a module and selecting its pipeline are separate steps: require('lunr-languages/lunr.de')(lunr) attaches the German plugin, while this.use(lunr.de) applies it to a builder. Call the plugin before adding documents. The package's 1.23.0 registry manifest declares CommonJS, subpath exports and TypeScript declaration paths. Those declarations are packaging evidence, not a compatibility test of your bundler.
For a combined index, load each non-English language module before calling lunr.multiLanguage. English is built in. The version-pinned implementation resets the indexing pipeline and, when present, the search pipeline. It installs all selected stemmers rather than detecting the language of each document. Its own warning says words with the same stemming root may fail to converge. If documents already have a locale, compare a shared index with separate locale indexes using the queries your readers actually type. That is a suggested evaluation, not a measured result.
Spanish accent folding is optional. The documented recipe inserts lunr.es.accentFold before the Spanish stemmer in both pipelines. Configuring just the indexing side leaves the recipe incomplete. Chinese has a different deployment concern: the documentation describes Intl.Segmenter plus CJK bigrams, with optional @node-rs/jieba use in Node. Do not assume the browser and optional Node tokenizer produce identical results.
We did not install or execute this package for this guide. The snippets below are documentation-based, unexecuted illustrations using the published 1.23.0 documentation and multi-language implementation. Later snippets identify the earlier setup they require. No latency, bundle-size or search-quality measurement is claimed.
Ratings use a documentation-based scale from 1 to 5: 1 means substantial unresolved concerns, 3 means a usable documented path with material caveats, and 5 would require unusually complete evidence for that dimension. API stability considers the published module contract and pipeline behavior. Documentation quality considers setup instructions and disclosed limits. Maintenance considers the release notes, not a response-time promise. Ecosystem considers integration choices, not downloads or proven adoption.
Patterns
Install the engine and language package install-language-plugins
npm install lunr@2.3.9 lunr-languages@1.23.0Unexecuted setup command. The README imports Lunr separately; these pins identify the versions discussed, not a tested compatibility matrix.
Register German after stemmer support register-german
const lunr = require('lunr')
require('lunr-languages/lunr.stemmer.support')(lunr)
require('lunr-languages/lunr.de')(lunr)Documentation-based illustration. Loading the module attaches lunr.de; choose it in the builder before adding documents.
Select German in the builder build-german-index
// Continue after the German registration example.
const germanIndex = lunr(function () {
this.use(lunr.de)
this.ref('id')
this.field('title', { boost: 10 })
this.field('body')
this.add({
id: 'de-1',
title: 'Dokument',
body: 'Beispieltext'
})
})Unexecuted adaptation of the published German example with an explicit document ID. The language plugin belongs before document insertion; no expected result count is asserted.
Use import syntax for registration import-registration-modules
import lunr from 'lunr'
import stemmerSupport from 'lunr-languages/lunr.stemmer.support'
import de from 'lunr-languages/lunr.de'
stemmerSupport(lunr)
de(lunr)The 1.23.0 README documents these imports and the manifest maps the subpaths. This illustration was not executed in Node or a bundler. Registration still needs a builder's this.use(lunr.de).
Load modules before combining languages register-mixed-languages
const lunr = require('lunr')
require('lunr-languages/lunr.stemmer.support')(lunr)
require('lunr-languages/lunr.de')(lunr)
require('lunr-languages/lunr.multi')(lunr)
const englishAndGerman = lunr.multiLanguage('en', 'de')Unexecuted illustration backed by lunr.multi.js 1.23.0. English is built in; the non-English language must already be registered when multiLanguage is called.
Apply the combined pipeline once build-mixed-index
// Continue after the mixed-language registration example.
const mixedIndex = lunr(function () {
this.use(englishAndGerman)
this.ref('id')
this.field('body')
this.add({ id: 'en-1', body: 'Search documentation' })
this.add({ id: 'de-1', body: 'Dokumentation suchen' })
})The plugin resets the indexing pipeline and the search pipeline when present. Every word passes through both selected stemmers. This is an unexecuted example, not evidence of matching quality or automatic language detection.
Prepare the Spanish plugin register-spanish
const lunr = require('lunr')
require('lunr-languages/lunr.stemmer.support')(lunr)
require('lunr-languages/lunr.es')(lunr)The published accent-folding recipe begins with these registrations. Registration alone does not enable the optional accentFold function. This example was not executed.
Configure accent folding on both sides fold-spanish-accents
// Continue after the Spanish registration example.
const spanishIndex = lunr(function () {
this.use(lunr.es)
this.pipeline.before(lunr.es.stemmer, lunr.es.accentFold)
this.searchPipeline.before(lunr.es.stemmer, lunr.es.accentFold)
this.ref('id')
this.field('body')
this.add({ id: 'es-1', body: 'Respiración' })
})Documentation-based, unexecuted adaptation of the 1.23.0 Lunr 2 recipe. Insert accentFold before the stemmer in both pipelines. The README describes omitted-accent matching; this guide does not report a local match test.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| lunr | npm | Use core Lunr alone when its default English processing meets your needs. Its registry describes browser full-text search; choose language plugins only when the corpus calls for them. |
| minisearch | npm | Evaluate MiniSearch when you are still choosing the underlying engine rather than extending an existing Lunr installation. Its registry describes a full-text search engine for browser and Node; language-processing suitability needs a separate check. |
More cli & tooling guides
commander · chalk · click · esbuild · typescript · yargs · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.