@pascal-app/lingo weekly downloads statistics
By pascal-app · npm · MCP servers
Make forms easier, LLM tools safer. Parse what humans type and what models emit — natural-language quantities, units, dates and ranges — into canonical, validated values. Two-way, zero dependencies.
@pascal-app/lingo has 5,834 recorded weekly downloads on npm, a decrease of 7.2% over the past 30 days.
It ranks #1049 of 2,256 tracked npm listings by weekly downloads.
Over 90 days, weekly downloads changed by +355%.
PluginStats has 121 daily observations since Jun 19, 2026; the latest is from Oct 17, 2026.
About @pascal-app/lingo
lingo
Make forms easier, LLM tools safer.
Docs with live demos: lingo.pascal.app · every section as agent-readable markdown: lingo.pascal.app/llms.txt
lingo parses what humans type and what models emit: natural-language quantities, units, dates, and ranges. It turns them into canonical, validated values and humanizes them back. Zero runtime dependencies. The size gate lives in scripts/size.mjs, and the package includes thirty-three built-in kinds (chrono-node needs 35 kB for dates alone). English is the default; opt-in locale packs (createLingo({ locales }), @pascal-app/lingo/locales/*) add number words, grammar, units, and relative-date idioms for Spanish, French, Portuguese, Chinese, Japanese, and en-GB. Wave-1 packs cover Romance number composition, CJK number tokens, localized date grammar, and per-locale corpus gates. Number *formatting* is locale-aware via Intl in every locale; humanizeDate() output stays English for now.
People type it quick and abbreviated: 180cm, 5ft 11, 1m80, 72 in, 1.5 cups, 500 KB, 5 Mbps, 5 gpm, 500 mAh, $1,234.50, 50p, about 20C, under 10 minutes. Models and pasted text bring the fluent, typographic forms: 5'11", 1½ cups, twenty-five kg, 3×10⁵ m, 10 inH₂O, 1 kgf/cm², 5 uM, 9.8 m/s², 10 Nm, 500 lux, 20 mSv, fifty cents. Your database wants one number in one unit. The library is the layer in between: forgiving in, canonical through, human out.
Why lingo
• Actually parses language. Number words ("an hour and a half"), unicode (½, μm, ℃, ′ ″, curly quotes), typos with did-you-mean, compounds (5'11", 2 lb 3 oz, 1h30), ranges, tolerances, qualifiers ("about", "at least"), conversion requests ("72 in to cm"), and fuzzy words ("hot") when you opt a field into them. • Canonical underneath. Every value normalizes to an SI-anchored base (meters, kilograms, kelvin, seconds) or a self-canonical currency unit, with exact legal conversion factors, never rounded anchors. Temperature *deltas* convert correctly (a 5 °C rise is a 9 °F rise). • Two-way. Everything default format() emits, parse() reads back. Tests enforce the invariant. localizedUnits: true is the explicit display-only escape hatch for Intl unit words the English parser cannot read yet. 1.9999 m formats as 6′7″, never 5′12″. • Honest about ambiguity. 1,234 (dot-decimal? comma-decimal?), 5m (meters? minutes?), ton (which ton?) return a deterministic best reading, ranked discriminated alternatives, and structured warnings. The parser does not guess silently. • Errors are UX. Every issue has a stable code, a human message you can override, an input span for highlighting, and did-you-mean suggestions. • Tiny and dependency-free. No runtime deps. Tree-shakeable. Intl handles locale number formatting, so the main entry ships no locale data — parser locale packs are opt-in @pascal-app/lingo/locales/* subpaths you load explicitly.
Performance
lingo is designed to be cheap enough to run while someone types, and fast enough to validate large imports without a worker queue.
The checked-in baseline uses a deterministic generated-English corpus built from the library's own aliases, number forms, qualifiers, ranges, conversions, typos, dates, durations, and sentence templates. On the local Node v24.5.0 backend baseline in this repo:
• A normal single-value field parsed 492,739 values/second across 900 generated cases, about 2.03 µs per input. • Strict bulk validation without did-you-mean suggestions ran at 550,270 checks/second across 240 generated unknown-unit cases, about 1.82 µs per row. • Scanning generated sentences for values ran at 53,533 scans/second across 260 cases. • A no-match stress test over 50,000 characters finished in 0.341 ms.
Those numbers are a machine-local snapshot, not a universal promise. The point is the order of magnitude: ordinary parsing is microsecond-scale, so debounce is a UX choice, not something the parser needs to survive. Reproduce with bun run bench:backend; the checked-in baseline lives in bench/baseline-node.json.
Install
Coding agents: the package ships an inline reference at node_modules/@pascal-app/lingo/llms.txt (also at lingo.pascal.app/llms-small.txt). Online, start at lingo.pascal.app/llms.txt.
The 5-minute tour
Parse
Serialized parse results are flat v3: `{ schemaVersion: 3, ok, type, …value fields…, text, span, issues, confidence }`. A quantity is { …, type: 'quantity', kind, value, unit, base, baseUnit, … } right at the top (no nesting); a conversion has source + converted (no redundant targetUnit); failures use type: 'failure' and may include a full candidate. Every result and issue carries a span: { start, end, text } — half-open UTF-16 offsets into the original input plus the matched substring, so span reads for itself (input.slice(start, end) === span.text). ok: false means at least one error-severity issue; warnings (AMBIGUOUS_NUMBER, TYPO_CORRECTED, RANGE_REVERSED, and others) accompany successful parses so you can surface them or ignore them. A machine-readable JSON Schema, OpenAPI, and ready-made Zod/Valibot/TypeBox/ArkType/Effect schemas live in @pascal-app/lingo/schema.
Need a richer view for docs, logs, or tool output? Keep toJSON() for compact wire storage and import describeResource() for direct lingo.quantity / lingo.range resources, or describeResult() for whole parse-result resources with issues and source spans:
Strictness & error escalation
Use one dial for field personality, then override the pieces that matter:
| mode | behavior |
| forgiving | Default. Typos, ambiguities, slang and assumptions can succeed with warnings/infos. | | confirm | Assumption-class issues escalate to error; the would-have-been result is attached as candidate. | | strict | confirm plus typo fixing off, number words/fuzzy/approximations/bare-number assumptions rejected. |
Candidate UX is built into the DOM layer:
Acceptance switches reject whole shapes while keeping a candidate:
Tolerance switches control how hard the parser tries:…
Description from the npm listing.
- parse
- natural-language
- units
- measurement
- convert
- unit-conversion
- input
- mask
- form
- date
- duration
- i18n
- locale
- humanize
- quantity
- typescript
- zero-dependencies
- llm
- ai
- agents
Where @pascal-app/lingo sits in the listing
Each band is one page of 20. Weekly downloads on a log scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.
Charts
Images: 30d · 1y · all time · 1600×900 dark
Adoption over time
7/30/90-day growth
Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.
Recent observations
Full history (121)Similar npm MCP servers plugins
Data source
Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.
Listing: https://www.npmjs.com/package/@pascal-app/lingo. First seen Oct 16, 2026; last successful collection Oct 19, 2026. See the methodology.