{"_id":"@didrod2539/croniq","_rev":"2-d34cd0250ce1bd4d3f4bca4748349d4c","name":"@didrod2539/croniq","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@didrod2539/croniq","version":"0.1.0","keywords":["cron","crontab","cron-parser","schedule","scheduler","cron-expression","next-run","cron-validate","cron-description","interval","zero-dependency"],"author":{"url":"https://github.com/didrod205","name":"didrod205"},"license":"MIT","_id":"@didrod2539/croniq@0.1.0","maintainers":[{"name":"didrod2539","email":"ykc205@naver.com"}],"homepage":"https://github.com/didrod205/croniq#readme","bugs":{"url":"https://github.com/didrod205/croniq/issues"},"dist":{"shasum":"a9afcaa1186e279153b438910c3ef9fefb932b18","tarball":"https://registry.npmjs.org/@didrod2539/croniq/-/croniq-0.1.0.tgz","fileCount":9,"integrity":"sha512-NKVqPqhYZ7SnkyfK9BNhgxahL1RyO1EDSZo45xaUkOze5stt4hTkslhN60q+r6tK7aqHC5zKNecBrKssNBboXA==","signatures":[{"sig":"MEQCIEUlqRTn8yDZ5YXyF2OhCP1xA7q7hHF2M7iV3u0QNavvAiA6WE2wxuWjb99BBGt1m5nI7aG1aaDNeyPavy311x0sZw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85960},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"0983466e0cd402aa5dc6097269830ac440bfca40","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsup","coverage":"vitest run --coverage","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"didrod2539","email":"ykc205@naver.com"},"repository":{"url":"git+https://github.com/didrod205/croniq.git","type":"git"},"_npmVersion":"11.12.1","description":"Tiny, zero-dependency cron toolkit: parse cron expressions, compute next/previous run times (field-jumping, fast), validate, and describe them in plain English. Works in Node, Deno, Bun and the browser.","directories":{},"sideEffects":false,"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"^5.7.2","@vitest/coverage-v8":"^2.1.8"},"_npmOperationalInternal":{"tmp":"tmp/croniq_0.1.0_1780059383904_0.056143071463067296","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@didrod2539/croniq","version":"0.2.0","publishConfig":{"access":"public"},"description":"Tiny, zero-dependency cron toolkit: parse cron expressions, compute next/previous run times (field-jumping, fast), validate, and describe them in plain English. Works in Node, Deno, Bun and the browser.","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"sideEffects":false,"engines":{"node":">=18"},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest","coverage":"vitest run --coverage","typecheck":"tsc --noEmit","lint":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["cron","crontab","cron-parser","schedule","scheduler","cron-expression","next-run","cron-validate","cron-description","interval","zero-dependency","cli"],"author":{"name":"didrod205","url":"https://github.com/didrod205"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/didrod205/croniq.git"},"bugs":{"url":"https://github.com/didrod205/croniq/issues"},"homepage":"https://github.com/didrod205/croniq#readme","devDependencies":{"@types/node":"^22.19.19","@vitest/coverage-v8":"^2.1.8","tsup":"^8.3.5","typescript":"^5.7.2","vitest":"^2.1.8"},"bin":{"croniq":"dist/cli.js"},"gitHead":"fcbc95bda11a8f131732f1af1dfd59b552f90baa","_id":"@didrod2539/croniq@0.2.0","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-BEvo578BovaOrEu4I94JnnbDoaBQBm+KgasDaqyv9ljg8N0J/NsEmQtrNgOWiYUUQ6zENIR0ZLdftmPfh1R8og==","shasum":"ae27bf76c47cab2648618afced3798b421aa0c3d","tarball":"https://registry.npmjs.org/@didrod2539/croniq/-/croniq-0.2.0.tgz","fileCount":15,"unpackedSize":145875,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDgK5AlA+QIF3GEHE4zvrFdzXhkuIFCkL2zFI54e+nuIQIhAI6BYahuq/RprVaMtRq6Rev5uQ/bgwRO1HdGHi7qjiAm"}]},"_npmUser":{"name":"didrod2539","email":"ykc205@naver.com"},"directories":{},"maintainers":[{"name":"didrod2539","email":"ykc205@naver.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/croniq_0.2.0_1780374844320_0.9883288541357536"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-29T12:56:23.700Z","modified":"2026-06-02T04:34:04.653Z","0.1.0":"2026-05-29T12:56:24.051Z","0.2.0":"2026-06-02T04:34:04.527Z"},"bugs":{"url":"https://github.com/didrod205/croniq/issues"},"author":{"name":"didrod205","url":"https://github.com/didrod205"},"license":"MIT","homepage":"https://github.com/didrod205/croniq#readme","keywords":["cron","crontab","cron-parser","schedule","scheduler","cron-expression","next-run","cron-validate","cron-description","interval","zero-dependency","cli"],"repository":{"type":"git","url":"git+https://github.com/didrod205/croniq.git"},"description":"Tiny, zero-dependency cron toolkit: parse cron expressions, compute next/previous run times (field-jumping, fast), validate, and describe them in plain English. Works in Node, Deno, Bun and the browser.","maintainers":[{"name":"didrod2539","email":"ykc205@naver.com"}],"readme":"<div align=\"center\">\n\n# croniq\n\n**Parse cron expressions, compute the next/previous run times, and describe them in plain English — in ~2 KB, with zero dependencies.**\n\n[![npm version](https://img.shields.io/npm/v/@didrod2539/croniq.svg?color=success)](https://www.npmjs.com/package/@didrod2539/croniq)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/@didrod2539/croniq?label=gzip)](https://bundlephobia.com/package/@didrod2539/croniq)\n[![CI](https://github.com/didrod205/croniq/actions/workflows/ci.yml/badge.svg)](https://github.com/didrod205/croniq/actions/workflows/ci.yml)\n[![types](https://img.shields.io/npm/types/@didrod2539/croniq.svg)](https://www.npmjs.com/package/@didrod2539/croniq)\n[![license](https://img.shields.io/npm/l/@didrod2539/croniq.svg)](./LICENSE)\n\n</div>\n\n\"When does `0 9 * * 1-5` run next?\" is a question you should never answer by\nhand — and definitely shouldn't trust an LLM to guess. It's exact calendar\narithmetic (ranges, steps, month lengths, leap years, the day-of-month/day-of-week\nunion rule). **croniq** does it deterministically, and tells you in English.\n\n```ts\nimport { parse } from \"@didrod2539/croniq\";\n\nconst cron = parse(\"0 9 * * 1-5\");      // 09:00, weekdays\ncron.next();                            // → Date of the next weekday 09:00\ncron.describe();                        // \"At 09:00, Monday through Friday\"\ncron.matches(new Date());               // is right now a run time?\n```\n\n---\n\n## Why croniq?\n\n- 🎯 **Correct, not approximate.** Leap days, month lengths, and the Vixie-cron day-of-month **OR** day-of-week rule are all handled. Verified against known schedules in tests.\n- ⚡ **Fast.** Field-jumping (not minute-by-minute scanning), so sparse schedules like `0 0 29 2 *` resolve in microseconds.\n- 🗣️ **Human-readable.** `describe()` turns an expression into a sentence — great for dashboards and confirmations.\n- 🧩 **Full syntax.** 5 fields or 6 (with seconds), ranges `1-5`, lists `1,3,5`, steps `*/15`, names `JAN`/`MON`, `?`, and macros `@daily`/`@hourly`/`@weekly`/…\n- 🕒 **UTC or local.** One flag.\n- 🪶 **~2 KB gzipped, zero dependencies.** Node 18+, Deno, Bun, Workers and the browser.\n\n## Install\n\n```bash\nnpm install @didrod2539/croniq\n# or: pnpm add @didrod2539/croniq  /  yarn add @didrod2539/croniq\n```\n\n> Published under the `@didrod2539` npm scope (the unscoped name `croniq` was\n> blocked by npm for being too close to `cron`). The import name matches the\n> package name; everything else is identical.\n\nShips ESM **and** CommonJS:\n\n```ts\nimport { parse, isValid } from \"@didrod2539/croniq\";        // ESM / TypeScript\nconst { parse, isValid } = require(\"@didrod2539/croniq\");   // CommonJS\n```\n\n## CLI\n\n```bash\nnpx @didrod2539/croniq \"0 9 * * 1\"             # describe + the next runs\nnpx @didrod2539/croniq describe \"*/15 * * * *\" # \"Every 15 minutes\"\nnpx @didrod2539/croniq next \"0 0 1 * *\" --iso -n 5\nnpx @didrod2539/croniq valid \"61 * * * *\"      # exit 1 if invalid\n```\n\nThe bundled command is **`croniq`**. Commands: `describe`, `next`, `prev`,\n`valid`. Options: `-n/--count`, `--utc`, `--iso`. `valid` sets the exit code.\n\n## Usage\n\n### Next & previous runs\n\n```ts\nconst cron = parse(\"*/15 * * * *\");       // every 15 minutes\n\ncron.next();                              // next run after now\ncron.next(new Date(\"2026-03-15T12:07Z\")); // → 2026-03-15T12:15:00Z\ncron.prev();                              // previous run before now\ncron.nextN(5);                            // next five runs (Date[])\n```\n\n### Validate\n\n```ts\nisValid(\"0 9 * * 1-5\"); // true\nisValid(\"99 * * * *\");  // false\n```\n\n### Describe\n\n```ts\nparse(\"0 9 * * 1-5\").describe();   // \"At 09:00, Monday through Friday\"\nparse(\"*/15 * * * *\").describe();  // \"Every 15 minutes\"\nparse(\"@hourly\").describe();       // \"At 0 minutes past every hour\"\nparse(\"0 0 1 1 *\").describe();     // \"At 00:00, on day-of-month 1, in January\"\n```\n\n### UTC vs local\n\n```ts\nparse(\"0 0 * * *\", { utc: true }).next();  // midnights in UTC\nparse(\"0 0 * * *\").next();                 // midnights in the host's local time\n```\n\n### Seconds field\n\nA 6-field expression adds a leading seconds column:\n\n```ts\nparse(\"*/30 * * * * *\").next(); // every 30 seconds\n```\n\n## Supported syntax\n\n| Field         | Values            | Allowed                       |\n| ------------- | ----------------- | ----------------------------- |\n| Second (opt.) | 0–59              | `* , - /`                     |\n| Minute        | 0–59              | `* , - /`                     |\n| Hour          | 0–23              | `* , - /`                     |\n| Day of month  | 1–31              | `* , - / ?`                   |\n| Month         | 1–12 or `JAN`–`DEC` | `* , - /`                   |\n| Day of week   | 0–7 or `SUN`–`SAT` (0 & 7 = Sunday) | `* , - / ?` |\n\nMacros: `@yearly` / `@annually`, `@monthly`, `@weekly`, `@daily` / `@midnight`,\n`@hourly`. When both day-of-month and day-of-week are restricted, a date matches\nif **either** matches (standard cron behavior).\n\n> `L`, `W`, and `#` modifiers aren't supported yet — [open an issue](https://github.com/didrod205/croniq/issues) if you need them.\n\n## API\n\n| Member | Description |\n| ------ | ----------- |\n| `parse(expr, opts?)` | Parse into a `Cron` (throws on invalid input). |\n| `isValid(expr, opts?)` | `true`/`false` without throwing. |\n| `cron.next(from?)` / `cron.prev(from?)` | Next/previous run `Date`. |\n| `cron.nextN(n, from?)` / `cron.prevN(n, from?)` | Arrays of run times. |\n| `cron.matches(date?)` | Does the date satisfy the expression? |\n| `cron.describe()` | Plain-English description. |\n| `cron.minutes` / `.hours` / `.daysOfMonth` / `.months` / `.daysOfWeek` / `.seconds` | Parsed value arrays. |\n\n## Comparison\n\n|                          | `croniq` | hand-rolled date math | heavier cron libs |\n| ------------------------ | :------: | :-------------------: | :---------------: |\n| next / prev computation  |    ✅    |          ⚠️           |        ✅         |\n| Plain-English describe   |    ✅    |          ❌           |        ⚠️ (separate lib) |\n| Validation               |    ✅    |          ❌           |        ✅         |\n| Zero dependencies        |    ✅    |          ✅           |        ⚠️         |\n| ~2 KB gzipped            |    ✅    |          —            |        ❌         |\n\n## Contributing\n\nContributions are very welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md)\nand our [Code of Conduct](./CODE_OF_CONDUCT.md).\n\n```bash\ngit clone https://github.com/didrod205/croniq.git\ncd croniq\nnpm install\nnpm test\n```\n\n## 💖 Sponsor\n\n`croniq` is free and MIT-licensed, built and maintained in spare time. If it\nsaved you from debugging a misfiring schedule, please consider supporting it —\nevery bit helps keep the project healthy.\n\n- ⭐ **Star this repo** — the simplest, free way to help others discover it.\n- 🍋 **[Sponsor via Lemon Squeezy](https://elab-studio.lemonsqueezy.com/checkout/buy/5d059b89-51d0-456b-b33a-ed56994f7010)** — one-time or recurring support.\n\n> Sponsoring? Open an issue and we'll add your name/logo here. Thank you! 🙏\n\n## License\n\n[MIT](./LICENSE) © croniq contributors\n","readmeFilename":"README.md"}