Comparing Fuse.js and Elasticlunr.js for Zola’s client-side search. Learn which library suits your static site’s needs.
Zola is a fast and lightweight static site generator. To implement client-side search functionality without a server, you need a suitable JavaScript library. Zola supports generating index formats based on Fuse and Elasticlunr for search, making it easy to implement search features.
Both are lightweight and operate without dependencies, but they differ in Korean language support and ease of use. In this article, I'll discuss the features, performance, Korean support of these two libraries, and why I chose Fuse.js.
To add search functionality in Zola, you need a client-side JavaScript library. Fuse.js and Elasticlunr.js are popular options, each strong in fuzzy search and full-text search, respectively.
Library | Features | Pros/Cons |
---|---|---|
Fuse.js | Library specialized in fuzzy search | Pros: Strong in handling typos or partial matches, simple setup for quick implementation Cons: Does not support complex search features |
Elasticlunr.js | Supports full-text search | Pros: Provides advanced features like Boolean queries, TF/IDF ranking Cons: Requires additional setup for Korean search |
Search functionality for blogs or documents should be simple yet support multiple languages well. Both libraries are appealing because they work without dependencies and can be easily integrated with Zola's Tera templates and JavaScript. However, for me, the key factors in choosing were Korean search performance, ease of setup, and how well it aligns with Zola's simple philosophy.
title
, content
. Flexible query adjustments are possible with search threshold or weights.e.g.
const fuse = new Fuse(list, { keys: ['title', 'content'], threshold: 0.4 });
const results = fuse.search('한글');
title:검색
).lunr-languages
plugin for proper Korean tokenization.e.g.
const index = elasticlunr();
index.addField('title');
index.addDoc(doc);
const results = index.search('한글', { fields: { title: { boost: 2 } } });
Zola allows easy configuration of search UI with Tera templates and JavaScript. Depending on the config.toml
settings, a JSON format index file is generated during build, which can be loaded in JavaScript to add search functionality.
Set index_format
to fuse_javascript
or fuse_json
, and during build, an index file in a format usable by Fuse.js, like search_index.en.json
, will be generated.
# config.toml
[search]
index_format = "fuse_javascript" # or "fuse_json"
Similarly, set it to elasticlunr_javascript
or elasticlunr_json
to generate an index file in Elasticlunr format.
# config.toml
[search]
index_format = "elasticlunr_javascript" # or "elasticlunr_json"
I added more weight to title
and included body
and tags
in the search targets as follows. You can adjust the threshold
value to set search sensitivity.
var options = {
keys: [
{ name: "title", weight: 2 },
{ name: "body", weight: 1 },
{ name: "tags", weight: 1 },
],
includeScore: true,
ignoreLocation: true,
threshold: 0.4, // Adjust as needed for search sensitivity
};
var currentTerm = "";
var documents = Object.values(window.searchIndex.documentStore.docs);
var fuse = new Fuse(documents, options);
// https://github.com/hahwul/goyo/blob/main/static/goyo.js
Initially, since Zola didn't directly support Korean indexes, I was using Elasticlunr, which only worked for English searches. However, in May of this year (2025.05), the PR I submitted was merged, officially enabling Korean index support, and it was included in a recent release.
This led me to reconsider search libraries, and ultimately, I leaned towards Fuse.js because it aligns well with Zola's simple philosophy. The fact that the Fuse.js community is much more active was also appealing. Additionally, while lunr-language
supports Korean, integrating it with Elasticlunr.js requires a lot of effort, whereas Fuse.js can be used immediately without separate setup, making it convenient.
If you're implementing search functionality in Zola, I recommend Fuse.js as a simple and fast solution. It's especially optimal for small to medium-sized sites, providing flexible fuzzy search for Korean without additional setup. Elasticlunr.js is useful where advanced search features are needed, but in most cases, I think Fuse offers better value for the investment.
Both libraries are excellent, but in my experience, Fuse.js fits better with Zola's conciseness. If you're running a blog or documentation page, I hope you'll compare various search features and create an even better search experience.