{"id":47615908,"url":"https://github.com/formation-res/querylight-ts","last_synced_at":"2026-05-26T19:01:15.071Z","repository":{"id":345743343,"uuid":"1187107938","full_name":"formation-res/querylight-ts","owner":"formation-res","description":"Search library for static websites. Bm25, faceting, Sparse \u0026 dense vector search, reciprocal rank fusion for hybrid search. Perfect for small sites and blogs.","archived":false,"fork":false,"pushed_at":"2026-05-15T15:42:34.000Z","size":511,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-15T16:35:47.559Z","etag":null,"topics":["bm25","search","sparse-vector","static-sites","vector-search"],"latest_commit_sha":null,"homepage":"https://querylight.tryformation.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/formation-res.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-20T10:53:59.000Z","updated_at":"2026-05-15T15:42:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/formation-res/querylight-ts","commit_stats":null,"previous_names":["formation-res/querylight-ts"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/formation-res/querylight-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formation-res%2Fquerylight-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formation-res%2Fquerylight-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formation-res%2Fquerylight-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formation-res%2Fquerylight-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/formation-res","download_url":"https://codeload.github.com/formation-res/querylight-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/formation-res%2Fquerylight-ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33534563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"ssl_error","status_checked_at":"2026-05-26T15:22:15.568Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bm25","search","sparse-vector","static-sites","vector-search"],"created_at":"2026-04-01T21:25:50.511Z","updated_at":"2026-05-26T19:01:15.058Z","avatar_url":"https://github.com/formation-res.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Querylight TS\n\n[![npm version](https://img.shields.io/npm/v/%40tryformation%2Fquerylight-ts)](https://www.npmjs.com/package/@tryformation/querylight-ts)\n[![build status](https://github.com/formation-res/querylight-ts/workflows/Test%20and%20Deploy%20Demo/badge.svg)](https://github.com/formation-res/querylight-ts/actions/workflows/ci-demo-deploy.yml)\n\nPure TypeScript port of the Kotlin `querylight` library, packaged for browsers and Node.js.\n\nQuerylight TS is an in-process search toolkit for static sites, browser apps, and Node.js projects that need more than fuzzy matching but do not want a separate search server. It is positioned as the most feature-rich local search library in this category: BM25 and TF-IDF ranking, structured queries, aggregations, highlighting, geo search, dense vector search, sparse vector search, and hybrid reranking behind one API.\n\nThe vector story is a first-class part of the library:\n\n- dense vector search with `VectorFieldIndex` for semantic retrieval, ANN lookup, related-content features, and vector rescoring\n- sparse vector search with `SparseVectorFieldIndex` for learned token-weight retrieval in the style of OpenSearch neural sparse search\n- hybrid search patterns that combine lexical retrieval with dense or sparse vector ranking\n\nThat makes it practical to ship lexical, dense, sparse, and hybrid search locally in one package instead of stitching together multiple narrower tools.\n\nProject links:\n\n- Documentation: [`docs/`](docs/)\n- Live demo and documentation portal: [https://querylight.tryformation.com/](https://querylight.tryformation.com/)\n\n## Use Cases\n\nQuerylight TS can cover a wide range of local search problems without forcing you into a backend search stack.\n\n| Use Case | Description | Features |\n| --- | --- | --- |\n| Text search | Find the right page, document, or product from normal keyword queries. | [TF-IDF and BM25 Ranking](docs/ranking/tfidf-and-bm25-ranking.md), [Term, Terms, Prefix, Exists, and Match Queries](docs/lexical-querying/term-terms-prefix-exists-and-match-queries.md), [BoolQuery for Must, Should, Filter, MustNot, and MinimumShouldMatch](docs/lexical-querying/bool-query.md), [Highlighting with Querylight TS](docs/features/highlighting-with-querylight-ts.md) |\n| Search as you type | Show useful matches while somebody is still typing. | [SimpleTextSearch for Plain JSON Documents](docs/features/simple-text-search-for-plain-json-documents.md), [Trie-Backed Prefix Expansion](docs/indexing/trie-backed-prefix-expansion.md), [How To Build Autocomplete](docs/guides/how-to-build-autocomplete.md) |\n| Did you mean | Recover from typos, partial words, and slightly wrong queries. | [SimpleTextSearch for Plain JSON Documents](docs/features/simple-text-search-for-plain-json-documents.md), [Approximate Nearest Neighbor Vector Search](docs/features/approximate-nearest-neighbor-vector-search.md), [Reciprocal Rank Fusion](docs/ranking/reciprocal-rank-fusion.md) |\n| Related documents | Show similar articles, products, help pages, or records. | [Approximate Nearest Neighbor Vector Search](docs/features/approximate-nearest-neighbor-vector-search.md), [Document Chunking Strategies](docs/features/document-chunking-strategies.md), [Vector Rescoring for Faster Hybrid Search](docs/features/vector-rescoring-for-faster-hybrid-search.md) |\n| Ask the docs | Answer natural-language questions by retrieving the most relevant chunks first. | [Approximate Nearest Neighbor Vector Search](docs/features/approximate-nearest-neighbor-vector-search.md), [Document Chunking Strategies](docs/features/document-chunking-strategies.md), [Vector Rescoring for Faster Hybrid Search](docs/features/vector-rescoring-for-faster-hybrid-search.md), [Ask the Docs End to End](docs/demo/ask-the-docs-end-to-end.md) |\n| Sparse neural search | Run learned token-weight retrieval when your model emits sparse vectors instead of dense embeddings. | [Sparse Vector Search](docs/features/sparse-vector-search.md), [Reciprocal Rank Fusion](docs/ranking/reciprocal-rank-fusion.md), [Ask the Docs End to End](docs/demo/ask-the-docs-end-to-end.md) |\n| Faceting | Let users narrow results by tags, sections, categories, ranges, or counts. | [Terms Aggregation](docs/discovery/terms-aggregation.md), [Significant Terms Aggregation](docs/discovery/significant-terms-aggregation.md), [Range Aggregation](docs/discovery/range-aggregation.md), [Histogram Aggregation](docs/discovery/histogram-aggregation.md), [Date Histogram Aggregation](docs/discovery/date-histogram-aggregation.md), [How To Build Faceted Navigation](docs/guides/how-to-build-faceted-navigation.md) |\n| Filtered search | Combine full-text queries with hard constraints such as section, product type, date, or status. | [BoolQuery for Must, Should, Filter, MustNot, and MinimumShouldMatch](docs/lexical-querying/bool-query.md), [NumericFieldIndex and DateFieldIndex for Structured Features](docs/indexing/numeric-and-date-fields.md), [RangeQuery Over Lexical Fields](docs/lexical-querying/range-query-over-lexical-fields.md) |\n| Dashboards | Slice and explore local data with counts, buckets, and ranked result lists. | [Using Querylight TS as a Local Analytics Engine](docs/guides/using-querylight-ts-as-a-local-analytics-engine.md), [From Raw API Payloads to Browser Dashboards](docs/guides/from-raw-api-payloads-to-browser-dashboards.md), [Build Interactive ECharts Dashboards from Plain JSON](docs/guides/building-echarts-dashboards-from-plain-json.md), [Terms Aggregation](docs/discovery/terms-aggregation.md), [Stats Aggregation](docs/discovery/stats-aggregation.md) |\n| Hybrid search | Blend lexical ranking with dense or sparse vectors instead of picking one retrieval model. | [Reciprocal Rank Fusion](docs/ranking/reciprocal-rank-fusion.md), [Vector Rescoring for Faster Hybrid Search](docs/features/vector-rescoring-for-faster-hybrid-search.md), [Sparse Vector Search](docs/features/sparse-vector-search.md), [Approximate Nearest Neighbor Vector Search](docs/features/approximate-nearest-neighbor-vector-search.md) |\n| Geo-aware search | Find results inside a point radius, map area, or polygon. | [Geo Indexing with Points and Polygons](docs/features/geo-indexing-with-points-and-polygons.md), [BoolQuery for Must, Should, Filter, MustNot, and MinimumShouldMatch](docs/lexical-querying/bool-query.md) |\n| Static-site search shipped to the browser | Build indexes ahead of time and ship them with your site or app. | [Portable JSON Index State](docs/indexing/portable-json-index-state.md), [Serialization, Hydration, and Shipping Indexes](docs/indexing/serialization-hydration-and-shipping-indexes.md), [Getting Started with Browser Search](docs/overview/getting-started-with-browser-search.md) |\n\n## Try The Demo\n\nOpen the live documentation portal and demo on Cloudflare Pages:\n\n- [https://querylight.tryformation.com/](https://querylight.tryformation.com/)\n\nIt is both the main documentation site and the live product demo. Use it to read the docs, inspect the indexed content, and compare lexical, dense vector, sparse vector, and hybrid retrieval in the browser.\n\n## Workspace Layout\n\n- `packages/querylight`: the library package (`@tryformation/querylight-ts`)\n- `apps/demo`: a Hugo-based static demo site with generated docs content and bundled client-side enhancements\n\n## Features\n\n- In-memory reverse index for structured documents\n- TF-IDF and BM25 ranking\n- Reciprocal rank fusion for combining lexical, geo, filter, and vector results\n- Dense vector retrieval with `VectorFieldIndex`\n- Sparse vector retrieval with `SparseVectorFieldIndex`\n- Hybrid retrieval with vector rescoring and rank fusion\n- Boolean, term, terms, wildcard, regex, exists, range, phrase, prefix, multi-match, dis-max, boosting, and match-all queries\n- Numeric/date field indexes plus distance-feature, rank-feature, and JS script scoring queries\n- Beginner-friendly plain JSON indexing with `simpleTextSearch`\n- Offset-based exact, phrase, prefix, and fuzzy highlighting\n- Analyzer/tokenizer/token-filter pipeline\n- Trie-backed prefix expansion\n- Aggregations and significant terms\n- Approximate nearest-neighbour dense vector search\n- Basic geo point/polygon queries\n- Portable JSON-serializable index state\n\n## Dense And Sparse Vector Search\n\nQuerylight TS supports two different vector retrieval models.\n\n- Dense vectors use `VectorFieldIndex`. This is the right fit for embeddings, semantic similarity, related-content features, ANN lookup, and lexical-first reranking with `VectorRescoreQuery`.\n- Sparse vectors use `SparseVectorFieldIndex`. This is the right fit when your model produces token-weight maps and you want a retrieval path closer to an inverted index.\n- Hybrid search works with both. You can fuse lexical and vector result sets with `reciprocalRankFusion(...)`, or retrieve lexically first and rescore a smaller candidate window with vectors.\n\nStart here if vector search is the reason you are evaluating the library:\n\n- Dense vector search: [docs/features/approximate-nearest-neighbor-vector-search.md](docs/features/approximate-nearest-neighbor-vector-search.md)\n- Sparse vector search: [docs/features/sparse-vector-search.md](docs/features/sparse-vector-search.md)\n- Hybrid reranking: [docs/features/vector-rescoring-for-faster-hybrid-search.md](docs/features/vector-rescoring-for-faster-hybrid-search.md)\n- Demo internals: [docs/demo/ask-the-docs-end-to-end.md](docs/demo/ask-the-docs-end-to-end.md)\n\n## Documentation\n\nBrowse the canonical documentation source in [`docs/`](docs/) or open the published documentation portal and live demo at [https://querylight.tryformation.com/](https://querylight.tryformation.com/).\n\n## Install\n\nInstall the published package in another project with:\n\n```bash\nnpm install @tryformation/querylight-ts\n```\n\nFor local development in this repository:\n\n```bash\nnpm install\n```\n\n## Beginner Path\n\nIf you want a reasonable default without composing your own queries, use `createSimpleTextSearchIndex` and `simpleTextSearch`:\n\n```ts\nimport { createSimpleTextSearchIndex, simpleTextSearch } from \"@tryformation/querylight-ts\";\n\nconst search = createSimpleTextSearchIndex({\n  documents: [\n    {\n      id: \"intro\",\n      title: \"Querylight TS\",\n      description: \"Portable browser and Node.js search\",\n      body: \"A compact search toolkit with BM25, phrase search, and fuzzy recovery.\"\n    }\n  ],\n  primaryFields: [\"title\"],\n  secondaryFields: [\"description\", \"body\"]\n});\n\nconst hits = simpleTextSearch(search, { query: \"portble sear\", limit: 5 });\n```\n\nIf you need highlight fragments, run highlighting as a second step on the returned ids:\n\n```ts\nimport { MatchQuery } from \"@tryformation/querylight-ts\";\n\nconst query = new MatchQuery(\"title\", \"range filters\");\nconst hits = search.documentIndex.searchRequest({ query, limit: 5 });\nconst highlight = search.documentIndex.highlight(hits[0]![0], query, {\n  fields: [\"title\", \"body\"]\n});\n```\n\n## Commands\n\n```bash\nnpm install\nnpm test\nnpm run build\nnpm run dev\n```\n\n## Positioning\n\nThis is intended as a broader client-side search toolkit than fuzzy-match-only libraries such as `fuse.js`: it combines ranking, boolean logic, multi-field search, phrase search, prefixes, aggregations, dense vector search, sparse vector search, and geo support behind one small pure TypeScript API. For a fuller comparison with `fuse.js`, Lunr, MiniSearch, FlexSearch, Pagefind, and Orama, see [the comparison article](docs/overview/browser-search-library-comparison.md).\n\n## Project Notes\n\nParts of this project were developed with AI-assisted agentic coding tools, with design, review, and release decisions still made manually.\n\nMost of the documentation was also AI-generated. That makes broad docs coverage easier to maintain, and it provides a large enough corpus for the [demo application](https://querylight.tryformation.com/) to showcase lexical, dense-vector, sparse-vector, and hybrid search modes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformation-res%2Fquerylight-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fformation-res%2Fquerylight-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fformation-res%2Fquerylight-ts/lists"}