FlexiLexi
A powerful, performance-optimized Svelte 5 component for fuzzy search with real-time results and adjustable sensitivity.
Description
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:
- Dictionaries and glossaries
- Product catalogs and e-commerce search
- Static data lists and reference tables
- Data exploration tools
- Dashboard filtering
- Configuration browsers and setting explorers
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:
- Performance-optimized: Intelligent search index caching prevents unnecessary re-indexing
- Real-time adjustable threshold: Live sensitivity slider from exact to fuzzy matching
- Instant results: Debounced search with smooth UX
- Accessible: Full ARIA support and keyboard navigation
- Fully customizable: Style with CSS or Tailwind
- Responsive: Works great on all screen sizes
Features
- Fuzzy Searching: Uses Fuse.js for flexible searches within datasets
- Adjustable Threshold: Live slider to control search sensitivity (0.0 = exact, 1.0 = very fuzzy)
- Performance Optimized: Search index is cached and only rebuilt when data changes, not on threshold adjustments
- Dynamic Field Selection: Customize which fields to search or let it auto-detect
- Debounced Search: Smooth typing experience with configurable debounce delay
- Real-time Updates: Instant results as you type or adjust settings
- Match Scoring: Shows relevance scores for each result
- Flexible Display: Choose which fields to show in results
- Type-safe: Built with TypeScript for excellent IDE support
Demo
Repo
Requirement
- Svelte 5
- Fuse.js
License Information
MIT
Installation
npm i -D flexilexi // npm
pnpm i -D flexilexi // pnpm
yarn add -D flexilexi // yarn
Usage
<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>
Example Use Cases
Product Catalog
<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}
/>
API Documentation Index
<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} />
Dictionary/Glossary
<script>
// Single object format
const glossary = {
API: 'Application Programming Interface',
REST: 'Representational State Transfer',
CRUD: 'Create, Read, Update, Delete'
};
</script>
<Fuzzy data={glossary} />
Props
The Fuzzy component accepts the following props:
data: (Required)
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",
}
keys=[]: (Optional)
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>
fields=[]: (Optional)
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>
thresholdValue=0.6: (Optional)
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>
Sample data
Styling
Use the following classes to style items in your style sheet:
.divclass.div2class.rangeLabelClass.rangeInputClass.searchLabelClass.searchInputClass.ulclass.liclass
CSS
Create 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'>
TailwindCSS
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
}
}
Recipes
Searching Through Markdown Documentation
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']}
/>