Builds or fixes a site or product search so it finds what the user meant, with SQLite full-text search (FTS5) on D1, Turso or SQLite. Word order, singular or plural, endings, case, punctuation and accents stop mattering ("cafe" finds "Café", "tomatoes" finds "tomato", "red tomato" finds "Tomato, red", "ab1042" finds "AB-1042"), and the start of a word is enough ("tom" finds "tomatoes"). Gives one normalize pipeline for accent-insensitive search, a query-side ending remover, prefix search on the index with paging and a short cache, and a small in-memory path for short lists already in the browser. Never loads a whole table to filter it per keystroke. It does not correct typos. Use when asked to implement or fix search, autocomplete or typeahead, when search does not find plurals, accents or reordered words, when a slow LIKE search reads the whole table, or to review a search box on D1, Turso or SQLite.
SQLite Search Builder is a tested SKILL.md that builds or fixes a site or product search so it finds what the user meant, with SQLite full-text search (FTS5) on D1, Turso or SQLite; an agent buys it once for $0.01 over x402.
Not for
Typo correction or 'did you mean' suggestions: there is no edit distance, so 'tomatoe' will not find 'tomato'. Also not for ranking by relevance (results come newest first), semantic or vector search, or setting up Elasticsearch, Algolia or Meilisearch. Postgres gets a short note only.
Tested, honestly
Tested 2026-10-04 with a strong and a weak model.
With and without the skill
Results with and without the skill, for Sonnet and Haiku |
| with | without | with | without |
|---|
| Cases passed |
| Cases passed | 12/12 | 12/12 | 12/12 | 7/12 |
|---|
One run per model and case, the same checks for both sides; we read every failed answer and widened nine checks that rejected right answers for their wording. Without the skill Sonnet gave other working fixes (a Porter tokenizer, remove_diacritics 2, an exception list). Haiku without it kept LIKE '%q%' on the server, called the loss of 'й' in Bulgarian harmless and gave no Bulgarian rules, offered two fixes for product codes that each left one complaint unsolved, said an over-eager stemmer was fine for 'universe' and 'news', and changed the tokenizer without rebuilding the table.
Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.
- SonnetStrong model, claude-sonnet-5-5
- Fixed the planted problem in all 11 cases that had one and answered 'No findings.' for the clean search. It moved LIKE '%q%' and a load-the-whole-table route onto an FTS5 index with prefix search and a LIMIT, cut endings from the query only, added a dictionary for irregular plurals, and kept the breve of 'й' in a Bulgarian catalogue. On the product-code case it also stored the code without its dash, so 'ab1042' finds 'AB-1042', and it noticed that one complaint in our case could not happen with the code we showed. In 1 of 12 answers it left out the 3-letter prefix rule, which the skill asks for.
- HaikuWeak model, claude-haiku-4-5-20251001
- Fixed the planted problem in all 11 cases that had one. It followed the skill's form less closely: five of its answers each left out one part the skill asks for (a debounce, the 2,000-item limit of the in-memory mode, cutting endings from the query only, the 3-letter prefix rule, or storing dictionary forms), and once it described a stem wrongly ('tomat' for 'tomatoes'), though the prefix still matched. On the clean search it answered 'No findings.' once; in a second run it reported a cursor pattern that cannot overflow in practice. With Haiku, check the generated code against the skill's test table.
Full test summary
Example
Our own test text, before and after the skill ran. Excerpts only.
English · claude-sonnet-5-5
Before
Notes: React shop, Vite, no backend search. The catalog is one JSON file of about 400 products, fetched once when the app starts and kept in a context.
type Product = { id: string; name: string; sku: string };
Current search box code:
const results = products.filter((p) => p.name.includes(query));…
After
**Mode A (in memory):** your 400 products are fetched once and held in a context, which is the one case where filtering an array is allowed. This only holds below about 2,000 items (never above 5,000), and only while the list isn't re-fetched per search. If the catalog outgrows that, move to a database with an FTS5 prefix index.…
What is in the file
- Hard rules
- Choose the mode
- Normalize (both modes)
- Query-side ending remover
- Mode B: FTS5 prefix search (D1, Turso, SQLite)
- Mode A: list already in memory (limit about 2,000)
- Do not
- Tests (run before you say done)
Languages
Any language. Tried in: English.
License
Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.
Versions
Current version 1.0.0, updated 2026-10-04. Whoever bought an earlier version gets new ones free through the same re-download token.
v1.0.0 · 2026-10-04
First release: builds or fixes a site or product search that forgives word order, plurals, accents, case, punctuation and partly typed words, on an SQLite FTS5 index (D1, Turso) with prefix search, keyset paging and a short cache, plus an in-memory mode for short lists already in the browser. Every step is written out in words and tables, with a test table to run before calling the search done.
FAQ
Will the search read the whole table?
No. The default is an FTS5 index searched by word start, ordered by rowid and stopped at a LIMIT, so one request reads about two rows per result shown, and page 50 costs the same as page 1. Loading every item and filtering it in code is allowed only for a list of up to about 2,000 that is already in the browser.
Does it work outside English?
The steps are the same for any language: one cleaning function for stored and typed text, a dictionary, at most five ending rules and two length guards. Accents come off Latin letters only, so the Cyrillic 'й' survives. In our Bulgarian catalogue case both models passed with the skill; without it Haiku called the loss of 'й' harmless and gave no Bulgarian rules.
Is it worth it with a strong model?
In our twelve cases Claude Sonnet fixed every planted problem with or without the skill, in some cases with other working fixes such as a Porter tokenizer. The gain was on Claude Haiku: twelve of twelve with the skill, seven of twelve without.