chrono-node
A natural language date and time parser for JavaScript and TypeScript, extracting real dates from free-form text like "next Friday at 3pm".
Repository Health
Technical Analysis
chrono-node (published as the chrono-node npm package, developed under the wanasit/chrono repository) turns everyday phrases like “tomorrow”, “last Friday”, “5 days ago”, or “2014-11-30T08:15:30-05:30” into concrete JavaScript Date objects and structured parsing results. It ships with a strict mode for formal date patterns and a casual mode (the default) that also understands relative and colloquial expressions.
The library is built around a pipeline of composable Parser and Refiner objects: parsers scan input text with regular expressions and extract raw date/time components, then refiners merge, filter, and resolve overlapping matches into final results. This architecture is fully exposed, so applications can clone a Chrono instance and push custom parsers or refiners onto it to support new phrases or formats without forking the library.
Version 2 rewrote the project in TypeScript and narrowed the default English-only behavior (v1 tried every locale by default), while adding first-class support for fi, fr, it, ja, nl, ru, uk, and vi, plus partial support for several more locales including two Chinese script variants. Each locale can be imported independently (e.g. chrono-node/en) to avoid pulling in Intl-dependent code on restricted Node builds.
With zero runtime dependencies and dual CJS/ESM builds, chrono-node is a common building block behind calendar inputs, chatbot/NLU date extraction, and text-ingestion pipelines that need to recover scheduling intent from unstructured input.
What You Get
chrono.parse()andchrono.parseDate()shortcuts for quick extraction of one or many date mentions from a string- A
strictmode for formal date-only formats and acasual(default) mode that also understands relative/colloquial phrases like “today” or “next Friday” - Built-in locale support for English plus 13 other languages (full or partial), each independently importable via
chrono-node/<locale> - A pluggable
Parser/Refinerpipeline so applications canclone()a Chrono instance and register custom parsers for new date formats or domain-specific phrases - Timezone-aware parsing via a
ParsingReferenceobject, including custom named-timezone offsets and DST-aware ambiguous timezone mappings - Dual CommonJS and ESM builds with bundled TypeScript type definitions
Common Use Cases
- Turning free-text scheduling requests (“let’s meet next Tuesday at 2”) into calendar events in chat or email assistants
- Extracting due dates and deadlines from task descriptions or ticket text in project-management tools
- Normalizing inconsistent date mentions scraped from documents, articles, or user-generated content for search/indexing
- Powering natural-language input fields where users type a date phrase instead of picking from a calendar widget
- Pre-processing text for NLU/chatbot pipelines that need explicit date/time entities alongside intent classification
Under The Hood
Architecture
Execution starts in Chrono.parse() (src/chrono.ts), which builds a ParsingContext from the input text and reference date, runs every configured Parser against the remaining text with Chrono.executeParser, concatenates and index-sorts the resulting matches, then folds them through an ordered list of Refiners that merge, filter, or annotate results before returning ParsedResult[]. Locale packages (src/locales/en, de, ja, zh/hans, zh/hant, and others) each export a Configuration object assembled from locale-specific parser and refiner classes plus shared building blocks from src/common/parsers and src/common/refiners (e.g. ISOFormatParser, SlashDateFormatParser, OverlapRemovalRefiner, ForwardDateRefiner). This makes the core engine locale-agnostic while every date-format nuance lives in a small, named, single-responsibility parser or refiner class, and applications can call chrono.clone() to extend the pipeline with their own parsers without touching the core.
Tech Stack
The project is written in TypeScript (~5.8) with no runtime dependencies at all ("dependencies": {}), keeping the published package minimal. It builds dual output targets — CommonJS via tsc -p tsconfig.build.json and ESM via a second tsconfig plus tsc-esm-fix — and exposes locale-scoped entry points (chrono-node/en, chrono-node/ja, etc.) so consumers can avoid loading Intl-heavy locales they don’t need. Tooling includes ESLint with the TypeScript plugin, Prettier (enforced via a Husky pre-commit hook that also runs the silent test suite), rimraf for clean builds, and typedoc for generating API documentation published to a dedicated documentation branch via GitHub Actions.
Code Quality
Testing uses Jest with ts-jest, and the suite is extensive — 146 test files organized per locale (test/en, test/ja, test/zh, etc.) plus cross-cutting suites like result.test.ts, calculation_weekdays.test.ts, and system_timezone.test.ts; CI (test.yml) runs npm run test (Jest with coverage) on every push and pull request and reports coverage to Coveralls. Error handling favors returning null from failed parser matches over throwing, and the codebase is fully typed with explicit interfaces (Parser, Refiner, ParsingComponents) rather than loose objects. A checked-in AGENTS.md documents the parser/refiner architecture and explicit conventions (e.g. keep parsers single-concern) for contributors and AI coding agents alike, indicating a codebase that is deliberately kept navigable.
What Makes It Unique Most date libraries (date-fns, Day.js, Luxon) manipulate and format dates you already have; chrono-node instead recovers dates from unstructured natural-language text, understanding relative phrasing (“5 days ago”, “next Friday”), ambiguous time-of-day cues, and locale-specific colloquialisms across more than a dozen languages in one coherent object model. Its explicit Parser/Refiner abstraction is unusually exposed for a parsing library — refiners can be added to reinterpret ambiguous results (its own documented example resolves ambiguous AM/PM hours) — giving downstream projects a real extension point rather than a black-box regex blob.
Used by 12 apps in this directory
Dub
Marketing · Analytics
The open-source link attribution platform for short links, conversion tracking, and affiliate programs — powering 100M+ clicks monthly.
Epicenter
Knowledge Management · Note Taking · Developer Tools
A local-first monorepo led by Whispering, an open-source speech-to-text app, built on an MIT toolkit that turns your data into plain Markdown and SQLite files you own instead of a database you rent.
ERPNext
ERP · Invoicing Finance
100% free, open-source ERP unifying accounting, manufacturing, inventory, CRM, HR, and POS in a single self-hostable platform.
HyperDX
Developer Tools · Analytics · Monitoring
Open source observability platform that unifies logs, traces, metrics, and session replays on ClickHouse — now the core of ClickStack.
Logseq
Note Taking · Knowledge Management
A privacy-first, open-source knowledge graph platform combining Markdown, Org-mode, bidirectional linking, and local-first storage for building your second brain.
Midday
Invoicing Finance · Productivity
All-in-one AI-powered business operations platform for freelancers and solo entrepreneurs to manage invoicing, time tracking, banking, and financial intelligence.
Outline
Knowledge Management · Collaboration
A fast, real-time collaborative knowledge base for growing teams built on React, Node.js, and ProseMirror.
Papermark
Digital Signiture · File Storage
Open-source DocSend alternative with page-by-page analytics, secure data rooms, and custom domains for document sharing.
QRev
CRM · AI Agents
Open source AI-first sales platform that replaces Salesforce with autonomous agents handling prospecting, outreach, and lead management at scale.