{"id":19592293,"url":"https://github.com/smikhalevski/trie","last_synced_at":"2025-07-08T10:09:36.599Z","repository":{"id":37435526,"uuid":"389125476","full_name":"smikhalevski/trie","owner":"smikhalevski","description":"🌲 The extremely fast compressed trie implementation in 2 kB gzipped.","archived":false,"fork":false,"pushed_at":"2023-09-04T18:18:41.000Z","size":996,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-08T10:09:33.575Z","etag":null,"topics":["autocomplete","data-structures","map","search","string","trie"],"latest_commit_sha":null,"homepage":"https://smikhalevski.github.io/trie/","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/smikhalevski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2021-07-24T14:58:43.000Z","updated_at":"2025-01-04T04:45:43.000Z","dependencies_parsed_at":"2023-02-09T04:00:44.949Z","dependency_job_id":null,"html_url":"https://github.com/smikhalevski/trie","commit_stats":{"total_commits":19,"total_committers":1,"mean_commits":19.0,"dds":0.0,"last_synced_commit":"ffbcaf8ebe770145c666b5dd71dc914a7c775444"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/smikhalevski/trie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikhalevski%2Ftrie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikhalevski%2Ftrie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikhalevski%2Ftrie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikhalevski%2Ftrie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smikhalevski","download_url":"https://codeload.github.com/smikhalevski/trie/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smikhalevski%2Ftrie/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264248021,"owners_count":23579058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["autocomplete","data-structures","map","search","string","trie"],"created_at":"2024-11-11T08:34:29.802Z","updated_at":"2025-07-08T10:09:36.563Z","avatar_url":"https://github.com/smikhalevski.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# trie 🌲\n\nThe [extremely fast](#performance) [compressed trie](https://en.wikipedia.org/wiki/Trie#Compressed_tries) implementation\nin [2 kB gzipped](https://bundlephobia.com/result?p=@smikhalevski/trie) and tree-shakeable.\n\n🔎 [API documentation is available here.](https://smikhalevski.github.io/trie/)\n\n```shell\nnpm install --save-prod @smikhalevski/trie\n```\n\n# Usage\n\nCreate a trie object:\n\n```ts\nimport { createTrie } from '@smikhalevski/trie';\n\nconst trie = createTrie();\n// ⮕ Trie { key: null, value: undefined }\n```\n\n[`Trie`](https://smikhalevski.github.io/trie/interfaces/Trie.html) is a plain object that you pass as an argument to\nvarious functions that traverse and update the data structure.\n\nTo associate a key with the value in the trie, use\n[`setValue`](https://smikhalevski.github.io/trie/functions/setValue.html):\n\n```ts\nconst fooLeaf = setValue(trie, 'foo', 111);\n// ⮕ Trie { key: 'foo', value: 111 }\n```\n\n[`setValue`](https://smikhalevski.github.io/trie/functions/setValue.html) returns the leaf trie object that withholds\nthe key-value pair. The returned leaf trie instance has stable identity: this object would represent this very key up to\nthe moment it is deleted. So, if you set a new value for the key, or add/delete other keys in the trie, the returned\nleaf object would still correspond to the original key.\n\n```ts\nsetValue(trie, 'foo', 222);\n// ⮕ fooLeaf\n```\n\nTo retrieve a value from the trie, use [`getValue`](https://smikhalevski.github.io/trie/functions/getValue.html):\n\n```ts\ngetValue(trie, 'foo');\n// ⮕ 111\n\ngetValue(trie, 'bar');\n// ⮕ undefined\n```\n\nOr you can retrieve the whole leaf that withholds the key-value pair:\n\n```ts\ngetLeaf(trie, 'foo');\n// ⮕ Trie { key: 'foo', value: 111 }\n\ngetLeaf(trie, 'bar');\n// ⮕ null\n```\n\nYou can delete a key from the trie:\n\n```ts\nconst leaf = setValue(trie, 'foo', 111);\n\ndeleteLeaf(leaf);\n```\n\nOr you can retrieve a leaf and then delete it:\n\n```ts\ndeleteLeaf(getLeaf(trie, 'foo'));\n```\n\n# Search\n\nTrie can be searched for a key that matches the longest substring in `input` that starts at `startIndex` and ends at\n`endIndex`.\n\n```ts\nconst trie = createTrie();\n\nsetValue(trie, 'foo', 111);\nsetValue(trie, 'foobar', 222);\n\nsearch(trie, '___foobar___', 3);\n// ⮕ Trie { key: 'foobar', value: 222, length: 6 }\n\nsearch(trie, '___fooba___', 3);\n// ⮕ Trie { key: 'foo', value: 111, length: 3 }\n```\n\nYou can provide the `endIndex` to limit the searched key length:\n\n```ts\nsearch(trie, '___foobar___', 3, 7);\n// ⮕ Trie { key: 'foo', value: 111, length: 3 }\n```\n\n[`search`](https://smikhalevski.github.io/trie/functions/search.html) is a powerful tool since it allow to search for\nkeys in strings without the need to create substrings.\n\n# Suggestions\n\nTrie can provide an array of values that are associated with keys that share the same prefix:\n\n```ts\nconst trie = createTrie();\n\nsetValue(trie, 'hotdog', 111);\nsetValue(trie, 'hotter', 222);\nsetValue(trie, 'hottest', 333);\n\nsuggestValues(trie, 'hot');\n// ⮕ [111, 222, 333]\n\nsuggestValues(trie, 'hott');\n// ⮕ [222, 333]\n\nsuggestValues(trie, 'cold');\n// ⮕ []\n```\n\nOr you can retrieve all leaf tries that withhold key-value pairs:\n\n```ts\nsuggestLeafs(trie, 'hot');\n// ⮕ [Trie { key: 'hotdog' }, Trie { key: 'hotter' }, Trie { key: 'hottest' }]\n\nsuggestLeafs(trie, 'hott');\n// ⮕ [Trie { key: 'hotter' }, Trie { key: 'hottest' }]\n\n// 🟡 null is returned if there are no matching leafs\nsuggestLeafs(trie, 'cold');\n// ⮕ null\n```\n\nUsing suggestions, you can delete all values with a particular prefix:\n\n```ts\nsuggestLeafs(trie, 'hott')?.forEach(deleteLeaf);\n```\n\n# Encoded tries\n\nEach leaf in the trie is an object. So storing _a lot_ of key-value pairs in a trie may require a significant amount of\nmemory. Encoded tries reduce the amount of required memory, and can also be easily serialized.\n\n[`EncodedTrie`](https://smikhalevski.github.io/trie/interfaces/EncodedTrie.html) is backed by an array of indices\ninstead of a multitude of objects, that's why it has a tiny memory footprint. For example, encoded trie requires\n400\u0026times; less memory than [`Trie`](https://smikhalevski.github.io/trie/interfaces/Trie.html) to store 60K key-value\npairs.\n\n_Encoded tries are read-only._\n\nTo create an [`EncodedTrie`](https://smikhalevski.github.io/trie/interfaces/EncodedTrie.html), we first need to create\na [`Trie`](https://smikhalevski.github.io/trie/interfaces/Trie.html) and then encode it. Usually you may want to encode\na trie at build time, serialize it, write to a JSON file and then import it at runtime.\n\n```ts\nconst trie = createTrie();\n\nsetValue(trie, 'foo', 111);\n\nconst encodedTrie = encodeTrie(trie);\n\ngetEncodedValue(encodedTrie, 'foo');\n// ⮕ 111\n```\n\nYou can search an encoded trie for a key that matches the longest substring in `input` that starts at `startIndex` and\nends at `endIndex`:\n\n```ts\nconst trie = createTrie();\n\nsetValue(trie, 'foo', 111);\nsetValue(trie, 'foobar', 222);\n\nconst encodedTrie = encodeTrie(trie);\n\nsearchEncoded(encodedTrie, '___foobar___', 3);\n// ⮕ Match { value: 222, lastIndex: 9 }\n\nsearchEncoded(encodedTrie, '___fooba___', 3);\n// ⮕ Match { value: 111, lastIndex: 6 }\n```\n\nYou can provide the `endIndex` to limit the searched key length:\n\n```ts\nsearchEncoded(encodedTrie, '___foobar___', 3, 7);\n// ⮕ { value: 111, lastIndex: 6 }\n```\n\n# Performance\n\nThe chart below showcases the performance comparison of this library and its peers, in terms of millions of operations\nper second (greater is better).\n\n\u003cimg src=\"./images/perf.svg\" alt=\"Performance\"\u003e\n\nTests were conducted using [TooFast](https://github.com/smikhalevski/toofast#readme) on Apple M1 with Node.js v20.4.0.\n\nTo reproduce [the performance test suite](./src/test/perf.js) results, clone this repo and run:\n\n```shell\nnpm ci\nnpm run build\nnpm run perf\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmikhalevski%2Ftrie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmikhalevski%2Ftrie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmikhalevski%2Ftrie/lists"}