An adapter that brings lightning-fast, typo-tolerant search powered by Typesense to your Fumadocs site.
Typesense is an open-source, lightning-fast search engine that delivers instant, typo-tolerant results with minimal setup. It's an open source alternative to Algolia and an easier-to-use alternative to ElasticSearch.
Fumadocs is a React.js documentation framework that lets you build fast, MDX-powered docs sites.
Together, Typesense and Fumadocs provide a seamless way to add powerful, blazingly-fast search to modern documentation websites.
Install dependencies:
npm install typesense typesense-fumadocs-adapterThen, follow the integration guide in the official Fumadocs documentation.
Refer to this Search UI guide to integrate Typesense with the Fumadocs UI components.
Results are cached in memory and cleared on reload. Cache hits do not extend expiry, displayed results do not refresh automatically. Full caches evict the least recently used result.
Create a shared cache outside your component to customize the limits:
import { createTypesenseSearchCache, useTypesenseSearch } from 'typesense-fumadocs-adapter/client';
const searchCache = createTypesenseSearchCache({
maxEntries: 200,
ttlMs: 5 * 60 * 1000,
});
function SearchDialog() {
const { search, setSearch, query } = useTypesenseSearch({
client,
typesenseCollectionName: 'docs',
cache: searchCache,
});
}| Option | Default | Purpose |
|---|---|---|
maxEntries |
100 |
Maximum number of cached responses |
ttlMs |
300_000 (5 min) |
Response lifetime in milliseconds |
Both options are optional set either to 0 to disable caching. Keep client and cache instances stable across renders.
Use cacheNamespace: indexRevision to force fresh results after an index rebuild. E.g. updating indexRevision from 'build-42' to 'build-43' triggers a new search for every users. Your application supplies the revision, the hook does not detect rebuilds automatically.
Also change the namespace when switching a custom search source, such as published versus preview documentation.
Use onSearch to call your own endpoint, which must return a Typesense search response. Forward signal to cancel obsolete requests:
const { search, setSearch, query } = useTypesenseSearch({
client,
typesenseCollectionName: 'docs',
locale,
onSearch: async (query, tag, locale, signal) => {
const params = new URLSearchParams({ q: query });
if (tag) params.set('tag', tag);
if (locale) params.set('locale', locale);
const response = await fetch(`/api/search?${params}`, { signal });
if (!response.ok) throw new Error('Search request failed');
return response.json();
},
});This repository uses Bun for package management and tests, and Docker for the integration test with Typesense server.
Install dependencies:
bun installThe docs app is part of the root Bun workspace and consumes the local adapter through workspace:*; it does not need a separate install.
Start Typesense using the repository's development configuration:
docker compose up -d typesense
curl http://localhost:8108/healthRun the integration suite:
bun run test:integrationThe integration command first builds the Fumadocs app in ./docs to produce its real search-index JSON then synced to Typesense. Test collections and aliases use a unique prefix and are removed after the suite.
The integration suite defaults to http://localhost:8108. Set TYPESENSE_URL and TYPESENSE_API_KEY to test against a different server.
Build the adapter package:
bun run plugin-buildRun the pure unit tests with bun run test:unit. React hook tests run in real Chromium through Vitest Browser Mode:
bun run test:browser:install
bun run test:browserBrowser tests require Node.js 24 and use mocked Typesense responses so Typesense server is not required.
Run the documentation site locally:
bun run docs-devLicensed under the Apache 2.0 License, Copyright © Typesense.
See LICENSE for more information.