{"id":15562134,"url":"https://github.com/mrkamel/spella","last_synced_at":"2026-06-23T13:33:31.627Z","repository":{"id":47751747,"uuid":"378377977","full_name":"mrkamel/spella","owner":"mrkamel","description":"Multi-language, Multi word, utf-8 spelling correction server for e.g. search engines using a levenshtein automaton and a Trie.","archived":false,"fork":false,"pushed_at":"2022-10-21T08:12:14.000Z","size":145,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-25T23:41:46.863Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrkamel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-19T09:51:58.000Z","updated_at":"2022-10-21T08:12:17.000Z","dependencies_parsed_at":"2023-01-20T10:16:28.944Z","dependency_job_id":null,"html_url":"https://github.com/mrkamel/spella","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mrkamel/spella","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fspella","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fspella/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fspella/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fspella/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrkamel","download_url":"https://codeload.github.com/mrkamel/spella/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkamel%2Fspella/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34691971,"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":"online","status_checked_at":"2026-06-23T02:00:07.161Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-10-02T16:11:55.052Z","updated_at":"2026-06-23T13:33:31.610Z","avatar_url":"https://github.com/mrkamel.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# spella\n\nMulti-language, Multi word, utf-8 spelling correction server for e.g. search\nengines using a levenshtein automaton and a Trie. Written in kotlin.\n\n* Is capable of splitting words, joining words, correcting phrases, etc\n* Calculates distances according to damerau-levenshtein and scores multi\n  character transliterations (german umlauts) with a distance of one.\n* Applies a max edit distance per word.\n* Uses several optimizations like re-using trie nodes when correcting\n  phrases to achieve single digit millisecond response times most of the\n  time.\n* Applies multiple rules for choosing the best correction, including a\n  user supplied score.\n\n## Compilation\n\n```shell\n./gradlew shadowJar\n```\n\n## Start\n\n```shell\n./spella --help\n./spella data/*.dic\n```\n\nThe `.dic` files are user-supplied tab separated text files:\n\n```\nen  some phrase  3942\nen  keyword  3491\n...\n```\n\ncontaining three columns per line. First column is an arbitrary language\nidentifier, the second column is the keyword or phrase and the third column is\na frequency or score value. If there are multiple matches with the same\ndistance, the one with a higher score wins. Correction is done greedily, i.e.\nphrases are generally preferred.\n\nPlease note, spella lowercases the phrases from the dictionary but does not\nnormalize them in any other way, as there is hardly any normalization that fits\nevery possible use case. Therefore, you better normalize the phrases in the\ndictionary files yourself beforehand according to your needs.\n\n## Requests\n\nThe server listens on port 8888 and uses a simple JSON based protocol.\n\nRequest:\n\ncurl -X GET http://127.0.0.1:8888/corrections?language=en\u0026text=some+phrse\n\nResponse:\n\n```json\n{\n  \"text\": \"some phrase\",\n  \"distance\": 1,\n  \"took\": 6\n}\n```\n\n`took` tells you how long the response took.\n\n## Choosing Corrections\n\nThe criteria for choosing the best correction are:\n\n1. the number of words (higher is better)\n2. distance (smaller is better)\n3. whether or not a correction matches the original when transliterated\n4. the user supplied score (higher is better)\n\n## Max Edit Distance\n\nCurrently, the default max allowed edit distances are:\n\n* token length \u003c 4 characters: won't be corrected\n* token length \u003c 9 characters: a maximum edit distance of 1 is used\n* else: a maximum edit distance of 2 is used\n\nYou can change those using the `--distances` command line option and pass a\ncomma separated list of string lenghts. For instance, `--distance 3,6,9` means\n\n* token length \u003c 3 characters: won't be corrected\n* token length \u003c 6 characters: a maximum edit distance of 1 is used\n* token length \u003c 9 characters: a maximum edit distance of 2 is used\n* else a maximum edit distance of 3 is used\n\nIt is strongly recommended to have an overall maximum edit distance of 2 for\nperformance reasons.\n\n## Limitations\n\nSpella currently does not split words if the resulting phrase is not present in\nany dictionary file. For instance, the query \"tabletennis\", will only be\ncorrected to \"table tennis\" if a dictionary file contains \"table tennis\". It is\nnot enough to have \"table\" and \"tennis\" individually present in dictionary\nfiles. This was decided because the respective corrections can be low quality\ndue to missing context.\n\n## Todo\n\n* keeping the case while being case insensitive\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkamel%2Fspella","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrkamel%2Fspella","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkamel%2Fspella/lists"}