Officially Supported Languages

ZBSearch supports 34 languages out of the box in 8 different alphabets. For every language, ZBSearch provides a default tokenizer, stop-words, and stemmer.

Right now, ZBSearch supports 34 languages out of the box in 8 different alphabets.
For every language, ZBSearch provides a default tokenizer, stop-words, and stemmer.

πŸ‡¨πŸ‡³πŸ‡―πŸ‡΅ A note on Chinese and Japanese

At the time of writing, Chinese (Mandarin) and Japanese are the only exception, since ZBSearch provides everything by default but the stemmer.

Since Chinese and Japanese logograms follow different rules than other alphabets, you will need to import a dedicated tokenizer for it.

Read more here about Chinese here and about Japanese here.

Multilingual mode (zero-config)

If you don't know the language of your documents ahead of time - or a single index mixes several languages - use multilingual instead of a specific language:

import { create } from 'zbsearch'

const db = create({
  schema: { title: 'string', content: 'string' },
  language: 'multilingual'
})

In this mode ZBSearch tokenizes with Intl.Segmenter (Unicode word segmentation, with a Unicode regex fallback on runtimes that lack it), so Latin, Cyrillic, Greek, Arabic, Hebrew, Indic, and CJK text all index correctly with no per-language setup. Tokens are lowercased, and diacritics are folded so that cafΓ© matches cafe, Ρ‘Π»ΠΊΠ° matches Π΅Π»ΠΊΠ°, and ؒلاف matches الاف.

Trade-offs compared to a per-language configuration:

  • No stemming and no stop-words by default. Queries for inflected forms (running vs. run) won't match unless you pass a custom stemmer function. Per-language installs with @zbsearch/stemmers remain the quality ceiling for single-language content: in the quality benchmark that ships with the repo (benchmarks/, npm run benchmark:multilingual-quality), the multilingual mode reaches ~0.70 recall@10 vs ~0.98 for tuned per-language installs, with most of the gap on inflection queries - while non-Latin scripts go from 0 (English default) to fully searchable.
  • CJK segmentation is script-based, not dictionary-based. It works well with prefix search, but for production Japanese or Chinese search prefer the dedicated tokenizers.
  • Sorting falls back to the runtime's default collation, since there is no single locale.

For multilingual sites (one locale per document), the recommended pattern is to keep a single multilingual index and store the locale as an enum, then filter at query time:

const db = create({
  schema: { title: 'string', content: 'string', locale: 'enum' },
  language: 'multilingual'
})

await search(db, { term: 'getting started', where: { locale: { eq: 'it' } } })

Latin Alphabet

LanguageTokenizerStop-wordsStemmer
Czechβœ…βœ…βœ…
Danishβœ…βœ…βœ…
Dutchβœ…βœ…βœ…
Englishβœ…βœ…βœ…
Finnishβœ…βœ…βœ…
Frenchβœ…βœ…βœ…
Germanβœ…βœ…βœ…
Hungarianβœ…βœ…βœ…
Indonesianβœ…βœ…βœ…
Irishβœ…βœ…βœ…
Italianβœ…βœ…βœ…
Lithuanianβœ…βœ…βœ…
Norwegianβœ…βœ…βœ…
Portugueseβœ…βœ…βœ…
Romanian (*)βœ…βœ…βœ…
Serbian (**)βœ…βœ…βœ…
Slovakβœ…βœ…βœ…
Slovenianβœ…βœ…βœ…
Spanishβœ…βœ…βœ…
Swedishβœ…βœ…βœ…
Turkishβœ…βœ…βœ…
Vietnameseβœ…βœ…βœ…

(*) = also uses a few additional diacritic marks
(**) = uses both Cyrillic and Latin scripts

Cyrillic Alphabet

LanguageTokenizerStop-wordsStemmer
Bulgarianβœ…βœ…βœ…
Russianβœ…βœ…βœ…
Serbian (*)βœ…βœ…βœ…
Ukrainianβœ…βœ…βœ…

(*) = uses both Cyrillic and Latin scripts

Greek Alphabet

LanguageTokenizerStop-wordsStemmer
Greekβœ…βœ…βœ…

Devanagari Script

LanguageTokenizerStop-wordsStemmer
Hindiβœ…βœ…βœ…
Nepaliβœ…βœ…βœ…
Sanskritβœ…βœ…βœ…

Arabic Script

LanguageTokenizerStop-wordsStemmer
Arabicβœ…βœ…βœ…

Armenian Alphabet

LanguageTokenizerStop-wordsStemmer
Armenianβœ…βœ…βœ…

Tamil Script

LanguageTokenizerStop-wordsStemmer
Tamilβœ…βœ…βœ…

Chinese Characters (Logographic Script)

LanguageTokenizerStop-wordsStemmer
Chinese (Mandarin)βœ…βœ…βŒ
Japaneseβœ…βœ…βŒ

On this page