Cron Expressions
Cron expression toolkit for standard 5-field crontab syntax (minute hour day-of-month month day-of-week): parse an expression into structured fields with expanded value sets (parse), explain any cron...
cron-expressions
Toolkit for standard 5-field crontab syntax — minute hour day-of-month month day-of-week. Parse, explain, build, validate, and compute the next N run times of any cron expression. Deterministic scheduler math, pure ESM, zero dependencies.
Tools
| Tool | Purpose |
|---|---|
parse | Cron (or @-macro) → structured fields + expanded value sets. |
explain | Cron → one plain-English sentence. Optional LLM enrichment via options.enrich. |
describe | Fields + English + the next 3 run times in one call. |
build | { minute, hour, dayOfMonth, month, dayOfWeek } spec → a valid cron string. |
nextRuns | The next N future run times as ISO timestamps (count, from, tz). |
validate | Check an expression; returns { valid, errors, normalized } (never throws). |
common | Ready-made presets (@daily, every-15-minutes, weekdays-9am, business-hours, …). |
Supported syntax
* any, a-b ranges, a/n and a-b/n steps, a,b,c lists, month/weekday names (JAN, SUN, MON-FRI), Sunday as 0 or 7, and @-macros: @hourly @daily @weekly @monthly @yearly (@reboot is recognized but has no scheduled time). Follows the Vixie-cron rule: when both day-of-month and day-of-week are restricted, a run matches if either matches.
Usage
import cron from './index.js';
cron.adapters.parse({ cron: '*/15 9-17 * * MON-FRI' });
await cron.adapters.explain({ cron: '0 9 * * 1-5' }); // "At 09:00, on weekdays (Monday–Friday)."
cron.adapters.build({ spec: { minute: 0, hour: 9, dayOfWeek: '1-5' } }); // "0 9 * * 1-5"
cron.adapters.nextRuns({ cron: '0 0 1 * *', count: 3 }); // next 3 first-of-month midnights (UTC)
cron.adapters.validate({ cron: '99 * * * *' }); // { valid:false, errors:[...] }
cron.adapters.common({ options: { filter: 'week' } });
Hybrid intelligence
The entire scheduler (field expansion + next-run search) is deterministic and offline. explain and describe additionally support an optional LLM path (options.enrich: true) that rewrites the baseline English into a friendlier sentence, silently falling back to the built-in phrasing when no model is reachable. Results are tagged { mode: 'heuristic' | 'llm' }. No tool ever requires a model.
DRY boundary
The existing cron pack parses human intervals ("5m" → milliseconds) and fires scheduled HTTP actions. This pack is crontab syntax — a different grammar entirely. No overlap. Only cross-pack import: ../_shared/llm.js.