{"id":17255248,"url":"https://github.com/wulf/nodehun","last_synced_at":"2025-12-16T13:57:48.541Z","repository":{"id":13035173,"uuid":"15714889","full_name":"Wulf/nodehun","owner":"Wulf","description":"The Hunspell binding for NodeJS that exposes as much of Hunspell as possible and also adds new features. Hunspell is a first class spellcheck library used by Google, Apple, and Mozilla.","archived":false,"fork":false,"pushed_at":"2025-11-22T14:56:51.000Z","size":9118,"stargazers_count":292,"open_issues_count":7,"forks_count":42,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-11-22T15:11:07.549Z","etag":null,"topics":["grammar","hunspell","node","npm-package","spellcheck","words","wrapper"],"latest_commit_sha":null,"homepage":"","language":"C++","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/Wulf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2014-01-07T19:53:24.000Z","updated_at":"2025-11-22T14:42:51.000Z","dependencies_parsed_at":"2024-01-13T21:53:23.042Z","dependency_job_id":null,"html_url":"https://github.com/Wulf/nodehun","commit_stats":{"total_commits":181,"total_committers":16,"mean_commits":11.3125,"dds":0.3370165745856354,"last_synced_commit":"03c9dcf1fcd965031a68553ccaf6487d1fe87f79"},"previous_names":["nathanjsweet/nodehun"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Wulf/nodehun","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wulf%2Fnodehun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wulf%2Fnodehun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wulf%2Fnodehun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wulf%2Fnodehun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wulf","download_url":"https://codeload.github.com/Wulf/nodehun/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wulf%2Fnodehun/sbom","scorecard":{"id":152554,"data":{"date":"2025-08-11","repo":{"name":"github.com/Wulf/nodehun","commit":"03c9dcf1fcd965031a68553ccaf6487d1fe87f79"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":3,"reason":"Found 4/11 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"19 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-2j2x-2gpw-g8fm","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T11:05:43.499Z","repository_id":13035173,"created_at":"2025-08-16T11:05:43.499Z","updated_at":"2025-08-16T11:05:43.499Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27765948,"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","status":"online","status_checked_at":"2025-12-16T02:00:10.477Z","response_time":57,"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":["grammar","hunspell","node","npm-package","spellcheck","words","wrapper"],"created_at":"2024-10-15T07:11:05.146Z","updated_at":"2025-12-16T13:57:48.509Z","avatar_url":"https://github.com/Wulf.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nodehun\n[![npm version](https://badge.fury.io/js/nodehun.svg)](https://badge.fury.io/js/nodehun) [![Build Status](https://travis-ci.org/Wulf/nodehun.svg?branch=master)](https://travis-ci.org/Wulf/nodehun) [![Build status](https://ci.appveyor.com/api/projects/status/9ky5lws4d191qrui/branch/master?svg=true)](https://ci.appveyor.com/project/Wulf/nodehun/branch/master)\n\n## Introduction\n\nNodehun aims to expose as much of hunspell's functionality as possible in an easy to understand and maintainable way, while also maintaining the performance characteristics expected of a responsible node module. \n\n## Features\n\n* Native performance.\n* Exposes all of hunspell's functionality:\n\t* Spell checking,\n\t* suggestions,\n\t* personal dictionaries and word management,\n\t* stems/roots of words,\n\t* morphological generation, and,\n\t* word analysis.\n* TypeScript declaration file.\n* Synchronous + promise-based async API.\n* Extensive unit testing.\n* Completely re-written using N-API (thus, stability in future v8 versions)\n\n## Installation\n\n\tnpm install nodehun\n\nIf you run into any build errors, make sure you satisfy the requirements for [`node-gyp`](https://github.com/nodejs/node-gyp#installation).\n\n## Quick Start\n\n```js\nimport { Nodehun } from 'nodehun'\n\nconst fs          = require('fs')\nconst affix       = fs.readFileSync('path/to/*.aff')\nconst dictionary  = fs.readFileSync('path/to/*.dic')\n\nconst nodehun     = new Nodehun(affix, dictionary)\n\n// Promise example\nnodehun.suggest('colour')\n\t\t   .then(suggestions =\u003e { })\n\n// async/await example\nasync function example() {\n\tconst suggestions = await nodehun.suggest('colour')\n}\n\n// sync example\nconst suggestions = nodehun.suggestSync('colour')\n```\n\nNote: It's probably not a good idea to use `readFileSync` in production.\n\n\n## Table of Contents\n\n1. \u003ca href=\"#migration-notes\"\u003eImportant migration notes from v2 -\u003e v3\u003c/a\u003e\n2. \u003ca href=\"#examples\"\u003eExamples\u003c/a\u003e\n\t* \u003ca href=\"#checking-for-correctness\"\u003eSpell checking\u003c/a\u003e\n\t* \u003ca href=\"#spell-suggestions\"\u003eSpelling suggestions\u003c/a\u003e\n\t* \u003ca href=\"#add-dictionary\"\u003eAdding a dictionary\u003c/a\u003e\n\t* \u003ca href=\"#add-word\"\u003eAdd a word\u003c/a\u003e\n\t* \u003ca href=\"#add-word-with-affix\"\u003eAdd a word (with affix)\u003c/a\u003e\n\t* \u003ca href=\"#remove-word\"\u003eRemove a word\u003c/a\u003e\n\t* \u003ca href=\"#stem\"\u003eWord stem\u003c/a\u003e\n\t* \u003ca href=\"#analyse\"\u003eWord analysis\u003c/a\u003e\n\t* \u003ca href=\"#generate\"\u003eWord generation\u003c/a\u003e\n3. \u003ca href=\"#notes\"\u003eNotes\u003c/a\u003e\n\t* \u003ca href=\"#improving-performance\"\u003eImproving performance\u003c/a\u003e\n\t* \u003ca href=\"#notes-warning-on-synchronous-methods\"\u003eA Warning on Synchronous Methods\u003c/a\u003e\n\t* \u003ca href=\"#notes-open-office-dictionaries\"\u003eA Note About Open Office Dictionaries\u003c/a\u003e\n\t* \u003ca href=\"#notes-creating-dictionaries\"\u003eA Note About Creating Dictionaries\u003c/a\u003e\n\t* \u003ca href=\"#notes-finding-dictionaries\"\u003eWhere To Get Dictionaries\u003c/a\u003e\n4. \u003ca href=\"#development\"\u003eDevelopment and Contribution\u003c/a\u003e\n\t* \u003ca href=\"#development-scripts\"\u003eScripts\u003c/a\u003e\n\t* \u003ca href=\"#development-notes\"\u003eNotes\u003c/a\u003e\n\t* \u003ca href=\"#development-mentions\"\u003eMentions\u003c/a\u003e\n\n## \u003ca id=\"migration-notes\"\u003e\u003c/a\u003eImportant migration notes from v2 -\u003e v3\n\n1. The API now reflects hunspell's API almost exactly. Please see `src/Nodehun.d.ts` for the API exposed by v3.\n\n2. Unlike Nodehun2, `suggestSync` for a word spelled correctly returns `null` instead of an empty array.\n\t For example:\n\n\t```js\n\tnodehun2.spellSuggestionsSync('color') // =\u003e []\n\tnodehun3.suggestSync('color') // =\u003e null\n\t```\n\n3. There are performance gains to be seen for those who wrapped the library in promises.\n\n\t![Spelling performance comparison graph](./test/performance/spell.png \"Spelling performance comparison graph\")\n\t![Suggestions performance comparison graph](./test/performance/suggest.png \"Suggestions performance comparison graph\")\n\n\tTo run the tests on your machine, execute `npm run performance-test` and find the graphs in the `test/performance` folder.\n\n4. To continue using the old version, use:\n\n\t`npm install --save nodehun@2.0.12`\n\n\tWorks with Node v11 or lower, but some have reported compilation issues in v10 and v11.\n\tIf you plan to use this version, please refer to the [old](https://github.com/Wulf/nodehun/blob/77e4be9e2cde8805061387d4783357c45c582a04/readme.md) readme file.\n\n\n## \u003ca id=\"examples\"\u003e\u003c/a\u003eExamples\n\nThe following section includes short examples of various exposed operations.\nFor complete examples, see the `/examples` directory.\n\n### \u003ca id=\"checking-for-correctness\"\u003e\u003c/a\u003eChecking for Correctness\nNodehun offers a method that returns true or false if the passed word exists in the dictionary, i.e. is \"correct\".\n\n```js\nawait nodehun.spell('color') // =\u003e true\nawait nodehun.spell('colour') // =\u003e false, assuming en_US dictionary\n```\n\n### \u003ca id=\"spell-suggestions\"\u003e\u003c/a\u003eSpelling Suggestions\nNodehun also offers a method that returns an array of words that could possibly match a misspelled word, ordered by most likely to be correct.\n\n```js\nawait nodehun.suggest('color')\n// =\u003e null (since it's correctly spelled)\n\nawait nodehun.suggest('calor')\n// =\u003e ['carol','valor','color','cal or','cal-or','caloric','calorie']\n```\n\n### \u003ca id=\"add-dictionary\"\u003e\u003c/a\u003eAdd Dictionary\nNodehun also can add another dictionary on top of an existing dictionary object at runtime (this means it is not permanent) in order to merge two dictionaries. Once again, please do not actually use `readFileSync`.\n\n```js\nconst en_CA = fs.readFileSync('./path/to/en_CA.dic');\n\nawait nodehun.suggest('colour') // =\u003e [ ...suggestions... ]\n// because \"colour\" is not a defined word in the US English dictionary\nawait nodehun.addDictionary(en_CA)\nawait nodehun.suggest('colour') // =\u003e null\n// (since the word is considered correctly spelled now)\n```\n\n### \u003ca id=\"add-word\"\u003e\u003c/a\u003eAdd Word\nNodehun can also add a single word to a dictionary at runtime (this means it is not permanent) in order to have a custom runtime dictionary. If you know anything about Hunspell you can also add flags to the word.\n\n```js\nawait nodehun.suggest('colour') // =\u003e [ ...suggestions...]\n// because \"colour\" is not a defined word in the US English dictionary\nawait nodehun.add('colour')\nawait nodehun.suggest('colour') // =\u003e null\n// (since 'colour' is correct now)\n```\n\nNote: _colouring_ will still be considered incorrect. See the the `addWithAffix` example below.\n\n### \u003ca id=\"add-word-with-affix\"\u003e\u003c/a\u003eAdd Word (with affix)\nLike the method above, except it also applies the example word's affix definition to the new word.\n\n```js\nawait nodehun.suggest('colouring') // =\u003e [ ...suggestions...]\n// because \"colour\" is not a defined word in the US English dictionary\nawait nodehun.addWithAffix('colour', 'color')\nawait nodehun.suggest('colouring') // =\u003e null\n// (since 'colouring' is correct now)\n```\n\n### \u003ca id=\"remove-word\"\u003e\u003c/a\u003eRemove Word\nNodehun can also remove a single word from a dictionary at runtime (this means it is not permanent) in order to have a custom runtime dictionary. If you know anything about Hunspell this method will ignore flags and just strip words that match.\n\n```js\nawait nodehun.suggest('color') // =\u003e null (since the word is correctly spelled)\nawait nodehun.remove('color')\nawait nodehun.suggest('color') // =\u003e ['colon', 'dolor', ...etc ]\n```\n\n### \u003ca id=\"stem\"\u003e\u003c/a\u003eWord Stems\nNodehun exposes the Hunspell `stem` function which analyzes the roots of words. Consult the Hunspell documentation for further understanding.\n\n```js\nawait nodehun.stem('telling') // =\u003e [telling, tell]\n```\n\n### \u003ca id=\"analyse\"\u003e\u003c/a\u003eWord Analysis\nNodehun exposes the Hunspell `analyze` function which analyzes a word and return a morphological analysis. Consult the Hunspell documentation for further understanding.\n\n```js\nawait nodehun.analyze('telling') \n// with the appropriate dictionaries files, it will return:\n// =\u003e [' st:telling ts:0', ' st:tell ts:0 al:told is:Vg']\n```\n\n### \u003ca id=\"generate\"\u003e\u003c/a\u003eWord Generation\nNodehun exposes the Hunspell `generate` function which generates a variation of a word by matching the morphological structure of another word. Consult the Hunspell documentation for further understanding.\n\n```js\nawait nodehun.generate('telling', 'ran') // =\u003e [ 'told' ]\nawait nodehun.generate('told', 'run') // =\u003e [ 'tell' ]\n```\n\n## \u003ca id=\"notes\"\u003e\u003c/a\u003eNotes\n\n### \u003ca id=\"improving-performance\"\u003e\u003c/a\u003e Improving Performance\n\nIf the native performance isn't fast enough for your workload, you can try using an LRU cache for your operations. The idea is to cache the results of the operation and only repeat the operations on cache misses.\n\n```js\nconst LRUCache = require('lru-native2')\n\nvar cache = new LRUCache({ maxElements: 1000 })\n\nasync function suggestCached() {\n  let cachedResult = cache.get(word)\n  if (cachedResult) {\n    // cache hit\n    return cachedResult\n  } else {\n    // cache miss\n    let result = await nodehun.suggest(word)\n    cache.set(word, result)\n    return result\n  }\n}\n\n// ... example usage:\n\nconst suggestions = await suggestCached('Wintre')\n// now 'wintre' results are cached\n\n// ... some time later...\n\nconst suggestions = await suggestCached('Wintre')\n               // =\u003e this is fetched from the cache\n```\n\nHere are two LRU implementations you can consider:\n* [lru-native2](https://github.com/adzerk/node-lru-native)\n* [lru-cache](https://github.com/isaacs/node-lru-cache)\n\n### \u003ca id=\"notes-warning-on-synchronous-methods\"\u003e\u003c/a\u003eA Warning on Synchronous Methods\nThere are synchronous versions of all the methods listed above, but they are not documented as they are only present for people who really know and understand what they are doing. I highly recommend looking at the C++ source code if you are going to use these methods in a production environment as the locks involved with them can create some counterintuitive situations. For example, if you were to remove a word synchronously while many different suggestion threads were working in the background the remove word method could take seconds to complete while it waits to take control of the read-write lock. This is obviously disastrous in a situation where you would be servicing many requests.\n\n### \u003ca id=\"notes-open-office-dictionaries\"\u003e\u003c/a\u003eA Note About Open Office Dictionaries\nAll files must be UTF-8 to work! When you download [open office dictionaries](http://cgit.freedesktop.org/libreoffice/dictionaries/tree/) don't assume that the file is UTF-8 just because it is being served as a UTF-8 file. You may have to convert the file using the `iconv` unix utility (easy enough to do) to UTF-8 in order for the files to work.\n\n### \u003ca id=\"notes-creating-dictionaries\"\u003e\u003c/a\u003eA Note About Creating Dictionaries\n\nIf you want to create a new Hunspell dictionary you will need a base affix file. I recommend simply using one of the base affix files from the open office dictionaries for the language you are creating a dictionary for. Once you get around to creating a dictionary read the hunspell documentation to learn how to properly flag the words. However, my guess is that the vast majority of people creating dictionaries out there will be creating a dictionary of proper nouns. Proper nouns simply require the \"M\" flag. This is what a dictionary of proper nouns might look like:\n\n\tAachen/M\n\taardvark/SM\n\tAaren/M\n\tAarhus/M\n\tAarika/M\n\tAaron/M\n\nNotice that the \"S\" flag denotes a proper noun that isn't capitalized, otherwise look in the docs.\n\n### \u003ca id=\"notes-finding-dictionaries\"\u003e\u003c/a\u003eWhere To Get Dictionaries\n\nThe included dictionaries were extracted from Libre Office. The Libre Office versions have a modified aff file that makes generate() and analyze() much more useful. However, any MySpell style dictionary will work. Here are a few sources:\n\n* [Libre Office dictionaries](http://cgit.freedesktop.org/libreoffice/dictionaries/tree/)\n* [Official Aspell dictionaries](http://wordlist.aspell.net/dicts/)\n* [Open Office extensions](http://extensions.services.openoffice.org/dictionary)\n* [Mozilla Extensions](https://addons.mozilla.org/en-us/firefox/language-tools/)\n\nAlso, check out [@wooorm]()'s UTF-8 dictionary collection [here](https://github.com/wooorm/dictionaries).\n\nLet the community know if you've found other dictionary repositories!\n\n# \u003ca id=\"development\"\u003e\u003c/a\u003eDevelopment and Contribution\n\n## \u003ca id=\"development-scripts\"\u003e\u003c/a\u003eScripts\n\nThe following is a a list of commands and their descriptions which may\nhelp in development.\n\n`npm start`: to jumpstart the development server. This will automatically recompile the\nc++ source when changes are made and run the tests once more.\n\n`npm run start-test`: if you don't want to continuously compile the c++ source, but do want\nthe tests to re-run when changes are made to the test files.\n\n`npm run build`: to compile the addon once.\n\n`npm test`: to run the tests once.\n\n`npm run performance-test`: to run the performance tests and output updated graphs. (see `test/performance`)\n\n## \u003ca id=\"development-notes\"\u003e\u003c/a\u003eNotes\n\nMake `node-gyp` build faster by increasing the number of cores it uses:\n\n```bash\nexport JOBS=max\nnpm run build # super fast now!\n```\n\n## \u003ca id=\"development-mentions\"\u003e\u003c/a\u003eMentions\n\nSpecial thanks to [@nathanjsweet](https://github.com/nathanjsweet) for his grass roots efforts with this project, including the `hunspell-distributed` package upon which this library relies to provide buffer-based Hunspell initialization.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwulf%2Fnodehun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwulf%2Fnodehun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwulf%2Fnodehun/lists"}