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
Super Productivity
Productivity · Project Management
A privacy-respecting, local-first task manager with built-in timeboxing, Pomodoro timer, and deep integrations for Jira, GitHub, GitLab, and CalDAV — no accounts, no data collection, ever.
Typebot
AI Assistants · AI Development · Developer Tools
Build sophisticated chatbots visually, embed them anywhere without iframes, and own your data — fully self-hostable with a modular block system and 30+ integrations.
useSend
Developer Tools · Marketing
Self-hostable open source email platform built on Amazon SES with a full dashboard, SMTP relay, REST API, and multi-language SDKs.