A powerful, performance-optimized Svelte 5 component for fuzzy search with real-time results and adjustable sensitivity.
FlexiLexi is a feature-rich search component built for Svelte 5 that leverages Fuse.js to provide intelligent fuzzy searching. Whether you're building a dictionary, product catalog, documentation search, or any searchable dataset, FlexiLexi delivers fast, relevant results with a customizable user interface.
Perfect for:
Note: For large-scale documentation sites with many pages, consider dedicated solutions like Algolia DocSearch or Pagefind. FlexiLexi works best with datasets that can be loaded as JSON (typically under 10,000 items).
Key Highlights:
MIT
npm i -D flexilexi // npm
pnpm i -D flexilexi // pnpm
yarn add -D flexilexi // yarn
<script>
import data from './data/example-data.json';
import { Fuzzy } from 'flexilexi';
</script>
<div class="wrapper">
<h1 class="text-4xl">Search Example</h1>
<h2 class="text-3xl">Type to search through your data</h2>
<Fuzzy {data} />
</div>
<style>
.wrapper {
text-align: center;
}
</style>
<script>
const products = [
{ name: 'Laptop Pro', category: 'Electronics', price: 999, brand: 'TechCorp' },
{ name: 'Wireless Mouse', category: 'Accessories', price: 29, brand: 'TechCorp' },
{ name: 'USB-C Cable', category: 'Accessories', price: 12, brand: 'CableCo' }
];
</script>
<Fuzzy
data={products}
keys={['name', 'category', 'brand']}
fields={['name', 'price']}
thresholdValue={0.4}
/>
<script>
const apiDocs = [
{
method: 'GET /api/users',
description: 'Retrieve list of all users',
category: 'Users'
},
{
method: 'POST /api/users',
description: 'Create a new user account',
category: 'Users'
},
{
method: 'DELETE /api/users/:id',
description: 'Delete user by ID',
category: 'Users'
}
];
</script>
<Fuzzy data={apiDocs} keys={['method', 'description']} thresholdValue={0.3} />
<script>
// Single object format
const glossary = {
API: 'Application Programming Interface',
REST: 'Representational State Transfer',
CRUD: 'Create, Read, Update, Delete'
};
</script>
<Fuzzy data={glossary} />
The Fuzzy component accepts the following props:
The dataset to search through. Accepts either an array of objects or a single object (for key-value pairs). This should be your JSON data or imported from a file.
example-data.json:
[
{
"key-1": "value-1",
"key-2": "value-2",
"key-3": "value-3"
},
{
"key-1": "value-4",
"key-2": "value-5",
"key-3": "value-6"
},
// more lines
]
Or an object:
{
"key-1": "value-1",
"key-2": "value-2",
"key-3": "value-3",
}
An array of field names that should be searchable. If specified, only these fields will be searched. If not provided, all fields in your data will be searchable.
<script>
import data from './data/example-data.json';
import { Fuzzy } from 'flexilexi';
let keys = ['name', 'description'];
</script>
<Fuzzy {data} {keys} />
<style>
.wrapper {
text-align: center;
}
</style>
An array of field names to display in search results. If not specified, defaults to the same fields as keys. Use this when you want to search through certain fields but only display others.
<script>
import data from './data/example-data.json';
import { Fuzzy } from 'flexilexi';
let fields = ['title', 'category'];
</script>
<Fuzzy {data} {fields} />
<style>
.wrapper {
text-align: center;
}
</style>
A number between 0 and 1 that controls search fuzziness. Lower values (0.0-0.3) require closer matches, higher values (0.6-1.0) are more forgiving of typos and variations.
<script>
import data from './data/example-data.json';
import { Fuzzy } from 'flexilexi';
</script>
<Fuzzy {data} thresholdValue={0.3} />
<style>
.wrapper {
text-align: center;
}
</style>
Use the following classes to style items in your style sheet:
.divclass.div2class.rangeLabelClass.rangeInputClass.searchLabelClass.searchInputClass.ulclass.liclassCreate static/css/style.css and add the following example:
.divclass {
margin: 1rem;
}
.rangeLabelClass {
margin-bottom: 0.5rem;
display: block;
font-size: 0.875rem;
font-weight: 500;
color: #1f2937;
}
.rangeInputClass {
height: 0.5rem;
width: 30%;
cursor: pointer;
appearance: none;
border-radius: 0.5rem;
background-color: #e5e7eb;
}
.searchLabelClass {
margin-bottom: 0.5rem;
display: block;
font-size: 1.25rem;
font-weight: 500;
color: #1f2937;
}
.searchInputClass {
display: block;
border-radius: 0.5rem;
border: 1px solid #d1d5db;
background-color: #f3f4f6;
padding: 0.625rem;
font-size: 1.25rem;
color: #1f2937;
width: 20rem;
margin: auto;
}
.ulclass {
max-width: 32rem;
list-style-position: inside;
list-style-type: disc;
line-height: 1.25;
color: #4b5563;
text-align: left;
width: 24rem;
margin: auto;
}
And add the following link to app.html:
<link rel='stylesheet' href='%sveltekit.assets%/css/style.css'>
If you are using TailwindCSS, update app.css by adding the following example:
@import 'tailwindcss';
@layer components {
.divclass {
@apply m-4;
}
.rangeLabelClass {
@apply mb-2 block text-sm font-medium text-gray-900 dark:text-white;
}
.rangeInputClass {
@apply h-2 w-full cursor-pointer appearance-none rounded-lg bg-gray-200 sm:w-1/3 dark:bg-gray-700;
}
.searchLabelClass {
@apply mb-2 block text-lg font-medium text-gray-900 dark:text-white;
}
.searchInputClass {
@apply block rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-lg text-gray-900 focus:border-blue-500 focus:ring-blue-500 w-80 m-auto dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500
}
.ulclass {
@apply max-w-md list-inside list-disc space-y-1 text-gray-500 dark:text-gray-400 text-left w-96 m-auto
}
}
If you want to search through markdown files, you'll need to convert them to JSON at build time. Here's a simple approach:
1. Create a build script (scripts/generate-search-data.js):
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter'; // npm install gray-matter
const docsDir = './src/docs';
const output = './src/lib/search-data.json';
const files = fs.readdirSync(docsDir);
const searchData = files
.filter((f) => f.endsWith('.md'))
.map((file) => {
const content = fs.readFileSync(path.join(docsDir, file), 'utf8');
const { data, content: body } = matter(content);
return {
title: data.title,
description: data.description,
url: `/docs/${file.replace('.md', '')}`,
content: body.slice(0, 200) // First 200 chars
};
});
fs.writeFileSync(output, JSON.stringify(searchData, null, 2));
2. Add to package.json:
{
"scripts": {
"prebuild": "node scripts/generate-search-data.js"
}
}
3. Use in your app:
<script>
import searchData from '$lib/search-data.json';
import { Fuzzy } from 'flexilexi';
</script>
<Fuzzy
data={searchData}
keys={['title', 'description', 'content']}
fields={['title', 'description']}
/>