@englishword/lingose
v0.1.0
Published
Offline English pronunciation, word structure, meanings, and IPS text annotation.
Readme
Lingose
Offline English pronunciation, word structure, meanings, vocabulary categories, and IPS text annotation for JavaScript and TypeScript.
IPA is phonetic transcription; IPS is Lingose pronunciation notation; ISM is morpheme division; IPSM combines IPS with ISM. The package includes its dictionary and TypeScript declarations, with no runtime dependencies or online dictionary requests.
Install
npm install @englishword/lingoseThis is the scoped distribution of lingose, with the same APIs and bundled data. The examples below use @englishword/lingose.
Use ESM in Node.js 22+ or a modern ES2022 browser. Browser resource validation requires Web Crypto in an HTTPS or localhost context.
Quick start
import { ipa, IPA, ips, ism, ipsm, root_lemma } from "@englishword/lingose";
console.log(ipa === IPA); // true
console.log(await ipa("apple")); // ["æpəl"]
console.log(await ips("running")); // ["rûnning"]
console.log(await ism("running")); // "runn-ing"
console.log(await ipsm("running")); // ["rûnn-ing"]
console.log(await root_lemma("running")); // "run"All data functions return Promises. The named exports share a default instance; no initialization call is required. Importing the module or creating an instance does not load the dictionary. Resources load on demand and are reused by that instance.
The four pairs ipa / IPA, ips / IPS, ism / ISM, and ipsm / IPSM are identical function objects. Results preserve the original Unicode notation; returned arrays are independent copies.
API
| Function | Result | Default |
| --- | --- | --- |
| ipa(word) / IPA(word) | IPA string[]; missing: [] | — |
| ips(word) / IPS(word) | IPS string[]; missing: [] | — |
| ism(word) / ISM(word) | Morpheme division string \| null | — |
| ipsm(word) / IPSM(word) | IPSM string[]; missing: [] | — |
| root_lemma(word) | Saved word-family value string \| null | — |
| meaning(word, lang?) | Meaning string \| null | lang = "en"; also accepts "zh" |
| kind(word, label?) | Category membership boolean | label = "CET4" |
| kind_list(label?) | Complete ordered category string[] | label = "CET4" |
| labels() | Registered boolean category names string[] | — |
| annotate_ips(text, options?) | Annotated plain text string | { skip_top: 0 } |
Word queries prefer exact spelling. A missing entry with an initial uppercase letter may fall back to its lowercase spelling; all-uppercase words are not automatically lowercased. Words must be nonempty strings without NUL or leading/trailing whitespace. An unknown word returns the missing result for that API. IPA, IPS, and IPSM arrays may have different lengths; their indices do not establish pronunciation pairs.
root_lemma returns a stored field. kind_list preserves Lingose's word-family ordering. Category names are case-sensitive; COLLINS and Band are not boolean category labels.
import { meaning, kind, kind_list, labels } from "@englishword/lingose";
console.log(await meaning("apple", "zh")); // "n. 苹果, 家伙"
console.log(await kind("apple")); // true
console.log((await kind_list()).slice(0, 5));
// ["a", "able", "ability", "disable", "enable"]
console.log((await labels()).includes("CET4")); // true
console.log(await meaning("unknownwordzz")); // nullText annotation
import { annotate_ips } from "@englishword/lingose";
console.log(await annotate_ips("Abandon the book."));
// "Åbando̊n ṫhe̊ book."
console.log(await annotate_ips("Abandon the book.", { skip_top: 1000 }));
// "Åbando̊n the book."
console.log(await annotate_ips("unknownwordzz"));
// "[unknownwordzz]"skip_top leaves frequent words and their recorded inflections unchanged. It accepts a nonnegative safe integer number or nonnegative bigint, and clamps values above 5062 to 5062. Booleans, fractions, unsafe numbers, NaN, and Infinity are rejected. Use { skip_top: 1000 }, with the underscore.
Annotation preserves whitespace, punctuation, and non-English text. It handles the contextual pronunciation of the, capitalization, apostrophes, and hyphens. Words that cannot be converted are bracketed according to the annotation rules. Input is plain text; HTML is not parsed.
Browser setup
With a bundler, copy the entire node_modules/@englishword/lingose/data/ directory to your site's static assets. For a project that serves public/ at its root:
node --input-type=module -e "import { cp } from 'node:fs/promises'; await cp('node_modules/@englishword/lingose/data', 'public/lingose-data', { recursive: true });"Then bundle this application code:
import { createLingose } from "@englishword/lingose/browser";
const lexicon = createLingose({
dataUrl: new URL("/lingose-data/", location.href),
});
const output = document.createElement("p");
output.textContent = (await lexicon.ipsm("running")).join(" / ");
document.body.append(output);dataUrl points to the data directory, not a dictionary service. Once the code and data are available locally, no external dictionary connection is needed. If deploying the package's dist/ and data/ directories together without bundling, the default relative data location works.
Instances and errors
import { createLingose } from "@englishword/lingose";
const lexicon = createLingose({ maxCachedShards: 128 });
console.log(lexicon.ipsm === lexicon.IPSM); // true
console.log(await lexicon.ipsm("running")); // ["rûnn-ing"]Reuse an instance across calls to share in-flight loads and cached resources. Each instance has its own cache. maxCachedShards defaults to 128; use 0 to avoid retaining parsed word shards. A custom loadResource(relativePath): Promise<Uint8Array> can supply packaged resource bytes through your application's asset loader. A failed load can be retried by calling the API again.
Data functions reject with TypeError for invalid input types, ValueError (a RangeError) for invalid values, LexiconDataError for resource failures, or its subclass SchemaVersionError for incompatible data. The three custom error classes are exported. Invalid createLingose configuration throws synchronously.
License and credits
Original Lingose data and notation by ZHAN Xianjue. Lingose code and original material use CC BY 4.0; third-party material retains its own terms. See sources and attribution.
