mrkeyoor.com_
Sat 19 Sept 23:48 UTC
npmUtilsupdated 18 Sept 2026

parse-latin review

parse-latin 7.0.0 turns Latin-script prose into an nlcst tree with paragraphs, sentences, words, whitespace, punctuation, symbols, and exact source positions. Its rules keep forms such as `non-profit`, `she's`, `G.I.`, `11:00`, and `N/A` together and avoid treating every period as a sentence boundary. It performs tokenization and structural splitting only: there is no tagging, stemming, entity recognition, sentiment, or model inference. That makes `utils` a more accurate category than the queue's `ai-ml` hint.

Verdict

parse-latin 7.0.0 added 10 packages and 1 MB in our sandbox, bundled to 10 KB gzipped, and produced 0 audit findings with types included. Install it for offset-accurate Latin-script token trees or retext work; do not install it for AI, linguistic tagging, or a simple boundary list that `Intl.Segmenter` can supply.

We installed it

Lab card: what happened when we installed parse-latinScreenshot of parse-latin documentation
Install✓ · 2.6s10 packages on disk · 1 MB
ImportESM import works · require() works · ESM package with exports map
Browser10 KBgzipped (28.5 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does parse-latin install cleanly?

Yes. In a fresh container with an empty cache, npm install parse-latin finished in 3 seconds, leaving 10 packages and 1 MB on disk. npm audit reported no known vulnerabilities.

How much does parse-latin add to a browser bundle?

10 KB gzipped (28.5 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does parse-latin work with both ESM and CommonJS?

Yes. Both import 'parse-latin' and require('parse-latin') worked in Node 22 in our run. The package is published as ESM with an exports map.

Does parse-latin include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

parse-latin or retext-latin: which should you use?

retext-latin: Use it when a unified processor and plugins should own the parse rather than direct tree construction. parse-latin 7.0.0 added 10 packages and 1 MB in our sandbox, bundled to 10 KB gzipped, and produced 0 audit findings with types included.

When should you not use parse-latin?

You need part-of-speech tags, lemmas, entities, sentiment, or semantic similarity. parse-latin produces token structure and never performs those analyses.

API stability5/5Version 7.0.0 exposes one named `ParseLatin` class and documents `parse(value)` as the public operation. The nlcst output shape and unist positions are established ecosystem contracts. Major 6 removed older customization helpers and added types, while major 7 has remained unchanged since July 2023. That small surface reduces churn, though consumers extending internal tokenizer plugin arrays accept a less documented contract.
Docs4/5The README explains installation, its ESM-only support promise, the single export, nlcst output, token categories, word-merging examples, sentence exceptions, language scope, Node compatibility, and TypeScript status. A live demo exposes the tree for arbitrary input. Practical traversal, reconstruction, mutation, and retext integration are delegated to nlcst, unist, vfile, and retext documentation, so first-time users must follow several projects.
Maintenance3/5npm published 7.0.0 on July 17, 2023, and GitHub's last push was October 24, 2024. The repository is unarchived and currently reports 0 open issues and pull requests, which suggests a quiet and bounded package rather than an ignored queue. Still, the generated character tables cite Unicode 15.0.0, and no newer release has refreshed runtime expectations or those classifications.
Ecosystem4/5The latest completed week recorded 4,294,174 npm downloads. parse-latin produces nlcst, works with unist visitors and vfile messages, and underpins retext-latin; the package also includes TypeScript declarations and a 10 KB gzipped browser bundle in our test. Its interoperability is strongest inside unified. Consumers outside that family must adopt a tree format and several small helpers for work that native segmentation may already cover.

Use it if

  • A prose linter or editor needs word and sentence nodes that point back to exact line, column, and offset positions.
  • You are writing a retext plugin and want the nlcst shape used by the unified text ecosystem.
  • Latin-script input contains abbreviations, initials, contractions, or hyphenated words that defeat a period or whitespace split.
  • One parser must handle several Latin-script languages without pretending to provide language-specific linguistic analysis.
Skip it if

Setup reality

We installed parse-latin 7.0.0 in 2.6 seconds in a fresh Node 22 Bookworm sandbox. The install left 10 packages and 1 MB on disk. parse-latin has 6 direct dependencies, no peers, a 212 KB unpacked size, and an MIT license. npm audit found 0 known vulnerabilities. The package includes TypeScript declarations. Our minified browser build measured 28.5 KB and 10 KB gzipped.

Version 7 declares ESM with an exports map. Both require() and ESM import worked in our Node 22 measurement, but the README promises ESM usage and Node 16 compatibility, so use the named ParseLatin export in portable examples. There is no default export, credential, config file, native build, or background service. Browser documentation uses esm.sh; bundler users can import the npm package normally.

The public API looks small because parse(value) is the documented entry point, but the returned nlcst tree is the actual integration contract. Parent nodes store children instead of a value; use nlcst-to-string to reconstruct text and a unist visitor to traverse nodes. Positions refer to the exact input string. Trimming, newline conversion, or Unicode normalization after parsing breaks offset mapping back to the original source.

Sentence boundaries are rules, not linguistic understanding. Version 7 merges punctuation inside known word shapes and handles terminal punctuation followed by quotes or parentheses, yet language-specific abbreviations can still need parse-english, parse-dutch, or a custom pass. For retext applications, install retext-latin or use retext's configured parser instead of parsing a second tree beside the processor. The 10 KB gzipped browser result is reasonable for editor tooling, but Intl.Segmenter is cheaper when you only need segmentation.

Patterns

Create an nlcst document tree parse-document

import { ParseLatin } from 'parse-latin';

const parser = new ParseLatin();
const tree = parser.parse('First sentence. Second sentence.');

Version 7 has no default export. `parse()` returns RootNode, then ParagraphNode and SentenceNode children with source positions.

Print a readable nlcst tree inspect-syntax-tree

import { ParseLatin } from 'parse-latin';
import { inspect } from 'unist-util-inspect';

const tree = new ParseLatin().parse('A small example.');
console.log(inspect(tree));

`unist-util-inspect` is separate from parse-latin. It displays node types, child counts, values, and offsets more clearly than a raw object dump.

Extract sentence text collect-sentences

import { visit } from 'unist-util-visit';
import { toString } from 'nlcst-to-string';

const sentences = [];
visit(tree, 'SentenceNode', (node) => {
  sentences.push(toString(node));
});

Sentence nodes have children rather than a text property. `nlcst-to-string` joins their leaves without discarding punctuation or whitespace.

Count tokenizer-defined words count-word-nodes

import { visit } from 'unist-util-visit';

let count = 0;
visit(tree, 'WordNode', () => {
  count += 1;
});

Version 7 can keep `non-profit`, `11:00`, and `N/A` as one WordNode, so this count differs from whitespace splitting.

Slice the original text by node offsets map-node-to-source

visit(tree, 'WordNode', (node) => {
  const { start, end } = node.position;
  const original = source.slice(start.offset, end.offset);
  console.log(start.line, start.column, original);
});

Offsets match the exact parsed string. Do not normalize or trim `source` before applying them to editor ranges.

Inspect sentence splitting around abbreviations find-abbreviation-boundaries

const source = 'Use e.g. a fixture. Then inspect the tree.';
const tree = new ParseLatin().parse(source);
const sentences = [];
visit(tree, 'SentenceNode', (node) => sentences.push(toString(node)));

The built-in rules avoid ending a sentence at common forms such as `e.g.`. Domain abbreviations can still require a language parser or custom handling.

Read the children of a merged word preserve-contractions

const tree = new ParseLatin().parse("she's ready");
const word = tree.children[0].children[0].children[0];
console.log(word.type, toString(word), word.children);

A merged WordNode may contain text and punctuation children. Match reconstructed text when an apostrophe matters instead of assuming one TextNode.

Report a word from a retext plugin lint-word-in-retext

import { visit } from 'unist-util-visit';
import { toString } from 'nlcst-to-string';

export default function noTodo() {
  return (tree, file) => {
    visit(tree, 'WordNode', (node) => {
      if (toString(node).toLowerCase() === 'todo') {
        file.message('Remove TODO from prose', node);
      }
    });
  };
}

Passing the node to `file.message` carries its line, column, and offset into the diagnostic automatically.

Use the parser through retext run-retext-parser

import { retext } from 'retext';
import retextRepeatedWords from 'retext-repeated-words';

const file = await retext()
  .use(retextRepeatedWords)
  .process('It it repeats.');
console.error(file.messages);

retext uses retext-latin as its normal Latin-script parser. Avoid constructing a separate parse-latin tree when the processor already owns one.

Visit paragraphs separated by newlines handle-multiple-paragraphs

const tree = new ParseLatin().parse('First paragraph.

Second paragraph.');
for (const paragraph of tree.children) {
  console.log(toString(paragraph));
}

Whitespace containing line endings drives paragraph structure. Preserve the original newline sequence if positions must map back to a file.

Load the named export from CommonJS load-from-commonjs

async function parseText(value) {
  const { ParseLatin } = await import('parse-latin');
  return new ParseLatin().parse(value);
}

Our Node 22 `require()` check worked, but the package documents ESM usage. Dynamic import is the portable CommonJS bridge for version 7.

Use a native alternative for flat boundaries segment-with-native-api

const segmenter = new Intl.Segmenter('en', { granularity: 'word' });
const words = [...segmenter.segment(text)]
  .filter((part) => part.isWordLike)
  .map((part) => ({ value: part.segment, index: part.index }));

`Intl.Segmenter` returns flat locale-aware boundaries and offsets, not nlcst paragraphs, punctuation nodes, or retext-compatible trees.

Alternatives

PackageRegistryPick it when
retext-latinnpmUse it when a unified processor and plugins should own the parse rather than direct tree construction.
wink-tokenizernpmUse it for a flat tokenizer with categories such as emoji, URL, mention, and number.
naturalnpmUse it when tokenization must sit beside stemming, classification, phonetics, or other English NLP tools.
francnpmUse it to identify a text's likely language rather than split it into nlcst nodes.

More utils guides

lru-cache · type-fest · ajv · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.