Package Exports
- @devloops/jcron
- @devloops/jcron/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@devloops/jcron) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@devloops/jcron
A high-performance, type-safe job scheduler for Node.js, React Native, and browsers
Features • Installation • Quick Start • Documentation • Examples • API Reference
🌟 Why JCRON?
JCRON is a next-generation cron scheduler that combines the power of Go's performance with the flexibility of TypeScript. Unlike other schedulers that rely on polling or setInterval, JCRON uses a mathematical scheduling algorithm for precise, CPU-efficient execution.
Key Highlights
- ⚡ Blazing Fast: Mathematical scheduling, not polling-based (~0.002ms per calculation)
- 🎯 100% Cron Compatible: All standard Unix/Linux patterns work perfectly
- 🌍 Universal: Node.js, React Native, Browsers (UMD/ESM/CJS)
- 🔒 Type-Safe: Full TypeScript support with strict typing
- 🌐 i18n Ready: Human-readable descriptions in 10+ languages
- 🚀 Zero Idle CPU: Near-zero CPU usage when no jobs are running
- 📦 Tiny Bundle: < 50KB gzipped, tree-shakeable
- 🧪 Battle-Tested: 175+ test cases, 91.6% coverage
🎯 Features
Core Scheduling
- ✅ Classic Cron Syntax: Full support for Unix/Linux cron patterns
- ✅ Shortcuts:
@yearly,@monthly,@weekly,@daily,@hourly,@minutely - ✅ Advanced Patterns:
L(last day/weekday of month)#(nth weekday occurrence, e.g.,1#2= 2nd Monday)W(week-based, e.g.,1W3= Monday of week 3)- Multiple patterns (e.g.,
1#1,5#3= 1st Monday and 3rd Friday)
- ✅ Week of Year:
WOY:33for ISO week-based scheduling - ✅ End of Duration (EOD): Schedule tasks relative to period ends
Timezone & Internationalization
- 🌍 Timezone Support: Full IANA timezone database support
- 🔄 DST Handling: Automatic daylight saving time adjustments
- 🗣️ Human-Readable: Convert cron expressions to natural language
- 🌐 10+ Languages: English, Turkish, Spanish, French, German, Polish, Portuguese, Italian, Czech, Dutch
Performance & Reliability
- ⚡ Optimized Engine: Timezone caching (41x → 1.68x overhead)
- 📊 Smart Caching: nthWeekDay caching, validation optimization
- 🛡️ Error Recovery: Built-in retry policies and error handling
- 🔍 Logging: Compatible with popular Node.js loggers (Winston, Pino, Bunyan)
Developer Experience
- 📘 TypeScript-First: Full type definitions with IntelliSense
- 🧪 Well-Tested: Comprehensive test suite with edge cases
- 📖 Rich Documentation: API reference, examples, migration guides
- 🔧 Flexible API: Function-based, object-based, or class-based usage
📦 Installation
# npm
npm install @devloops/jcron
# yarn
yarn add @devloops/jcron
# pnpm
pnpm add @devloops/jcron
# bun
bun add @devloops/jcronPlatform Support
| Platform | Support | Entry Point |
|---|---|---|
| Node.js (CJS) | ✅ Full | dist/index.cjs |
| Node.js (ESM) | ✅ Full | dist/index.mjs |
| React Native | ✅ Full | dist/index.mjs |
| Browser (UMD) | ✅ Full | dist/jcron.umd.js |
| Browser (ESM) | ✅ Full | dist/index.mjs |
| Bun | ✅ Full | dist/index.mjs |
| Deno | ✅ Full | dist/index.mjs |
🚀 Quick Start
Basic Usage
import { Runner } from "@devloops/jcron";
const runner = new Runner();
// Run every day at 9 AM
runner.addFuncCron("0 9 * * *", () => {
console.log("Daily morning task executed!");
});
runner.start();Calculate Next Run Time
import { getNext, toString } from "@devloops/jcron";
const nextRun = getNext("0 9 * * *");
console.log("Next execution:", nextRun);
const humanReadable = toString("0 9 * * *");
console.log("Description:", humanReadable); // "Daily at 9:00 AM"Timezone-Aware Scheduling
import { Schedule, getNext } from "@devloops/jcron";
const schedule = new Schedule({
h: "9",
m: "0",
tz: "America/New_York",
});
const nextRun = getNext(schedule);
console.log("Next run in NYC timezone:", nextRun);📚 Documentation
Core Concepts
- API Reference - Complete API documentation
- Build System - Build configuration and outputs
- React Native Compatibility - Mobile development guide
Advanced Topics
- Performance Optimization - Performance benchmarks and optimizations
- Examples & Recipes - Real-world use cases
- Migration Guide - Upgrading from older versions
- Contributing - How to contribute
💡 Examples
1. Classic Cron Patterns
import { Runner } from "@devloops/jcron";
const runner = new Runner();
// Every 15 minutes
runner.addFuncCron("*/15 * * * *", () => {
console.log("Runs every 15 minutes");
});
// Every weekday at 9 AM
runner.addFuncCron("0 9 * * 1-5", () => {
console.log("Weekday morning task");
});
// First Monday of every month at midnight
runner.addFuncCron("0 0 * * 1#1", () => {
console.log("First Monday task");
});
runner.start();2. Advanced Patterns
import { Runner } from "@devloops/jcron";
const runner = new Runner();
// Multiple nth weekdays: 1st Monday and 3rd Friday
runner.addFuncCron("0 0 * * 1#1,5#3", () => {
console.log("Bi-monthly specific weekdays");
});
// Week-based pattern: Monday of week 4
runner.addFuncCron("0 0 * * 1W4", () => {
console.log("Monday of the 4th week");
});
// Last day of the month
runner.addFuncCron("0 0 L * *", () => {
console.log("Last day of month");
});
// Last Friday of the month
runner.addFuncCron("0 0 * * 5L", () => {
console.log("Last Friday");
});
runner.start();3. End of Duration (EOD)
import { Schedule, Runner } from "@devloops/jcron";
const runner = new Runner();
// Run at 9 AM daily, until the end of the day
const schedule = new Schedule({
h: "9",
m: "0",
eod: "E1D", // End of 1 Day
});
runner.addScheduleCron(schedule, () => {
console.log("Daily task with EOD");
});
runner.start();4. Human-Readable Descriptions
import { toHumanize } from "@devloops/jcron";
// Natural language descriptions
console.log(toHumanize("0 9 * * *")); // "Daily at 9:00 AM"
console.log(toHumanize("0 0 * * 0")); // "Weekly on Sunday"
console.log(toHumanize("0 0 1 * *")); // "Monthly on 1st"
console.log(toHumanize("0 0 1 1 *")); // "Yearly on January 1st"
console.log(toHumanize("0 0 * * 1-5")); // "at midnight, on weekdays"
console.log(toHumanize("0 0 * * 6,0")); // "at midnight, on weekends"
console.log(toHumanize("0 0 * * 1#2")); // "at midnight, on 2nd Monday of the month"
console.log(toHumanize("0 0 * * 1W4")); // "at midnight, on Monday of week 4"
console.log(toHumanize("*/15 9-17 * * 1-5")); // Smart time range formatting
// Multi-language support
console.log(toHumanize("0 9 * * *", { locale: "tr" })); // "Günlük saat 9:00"
console.log(toHumanize("0 9 * * *", { locale: "de" })); // "Täglich um 9:00"
console.log(toHumanize("0 9 * * *", { locale: "fr" })); // "Quotidien à 9:00"5. Week of Year Scheduling
import { Schedule, Runner } from "@devloops/jcron";
const runner = new Runner();
// Run on week 33 of the year
const schedule = new Schedule({
h: "9",
m: "0",
woy: "33",
});
runner.addScheduleCron(schedule, () => {
console.log("Week 33 task");
});
runner.start();6. React Native Usage
import { Runner } from "@devloops/jcron";
import { useEffect } from "react";
function useScheduler() {
useEffect(() => {
const runner = new Runner();
// Background sync every 15 minutes
runner.addFuncCron("*/15 * * * *", async () => {
await syncDataWithServer();
});
// Daily cleanup at midnight
runner.addFuncCron("0 0 * * *", async () => {
await cleanupOldCache();
});
runner.start();
return () => {
runner.stop();
};
}, []);
}7. Error Handling & Logging
import { Runner } from "@devloops/jcron";
const runner = new Runner();
// With error handling
runner.addFuncCron("0 9 * * *", async () => {
try {
await riskyOperation();
} catch (error) {
console.error("Task failed:", error);
// Implement retry logic or alerting
}
});
// With custom logging
runner.setLogger({
error: (msg: string, data?: any) => console.error(msg, data),
warn: (msg: string, data?: any) => console.warn(msg, data),
info: (msg: string, data?: any) => console.info(msg, data),
debug: (msg: string, data?: any) => console.debug(msg, data),
});
runner.start();🎨 API Reference
Core Functions
getNext(schedule: Schedule | string, from?: Date): Date
Calculate the next run time for a schedule.
import { getNext } from "@devloops/jcron";
const next = getNext("0 9 * * *");
const nextFromDate = getNext("0 9 * * *", new Date("2024-12-25"));getPrev(schedule: Schedule | string, from?: Date): Date
Calculate the previous run time for a schedule.
import { getPrev } from "@devloops/jcron";
const prev = getPrev("0 9 * * *");isMatch(schedule: Schedule | string, date: Date): boolean
Check if a date matches a schedule.
import { isMatch } from "@devloops/jcron";
const matches = isMatch("0 9 * * *", new Date("2024-12-25 09:00:00"));toString(schedule: Schedule | string, options?: HumanizeOptions): string
Convert a schedule to a human-readable string.
import { toString } from "@devloops/jcron";
const description = toString("0 9 * * *");
// "Daily at 9:00 AM"
const turkish = toString("0 9 * * *", { locale: "tr" });
// "Günlük saat 9:00"Runner Class
The Runner class manages scheduled tasks.
import { Runner } from "@devloops/jcron";
const runner = new Runner();
// Add a function-based cron job
const jobId = runner.addFuncCron("0 9 * * *", () => {
console.log("Task executed");
});
// Add a Schedule-based cron job
runner.addScheduleCron(schedule, callback);
// Control runner
runner.start();
runner.stop();
// Remove a job
runner.remove(jobId);Schedule Class
Create schedules using the Schedule class.
import { Schedule } from "@devloops/jcron";
const schedule = new Schedule({
s: "0", // Seconds (0-59)
m: "0", // Minutes (0-59)
h: "9", // Hours (0-23)
D: "*", // Day of month (1-31, L for last)
M: "*", // Month (1-12 or JAN-DEC)
dow: "1-5", // Day of week (0-7 or SUN-SAT, # for nth, L for last)
Y: "*", // Year (1970-3000)
woy: "*", // Week of year (1-53)
tz: "UTC", // Timezone (IANA timezone)
eod: null, // End of duration (e.g., "E1D")
});Humanize Options
Customize human-readable output.
interface HumanizeOptions {
locale?: string; // Language code (default: 'en')
use24HourTime?: boolean; // Use 24-hour format (default: false)
dayFormat?: "long" | "short" | "narrow";
monthFormat?: "long" | "short" | "narrow" | "numeric";
caseStyle?: "lower" | "upper" | "title";
verbose?: boolean; // Include verbose descriptions
includeTimezone?: boolean; // Include timezone info
includeYear?: boolean; // Include year info
includeWeekOfYear?: boolean; // Include week of year
includeSeconds?: boolean; // Include seconds in time
useShorthand?: boolean; // Use "weekdays"/"weekends" (default: true)
}🚀 Performance
JCRON delivers exceptional performance through mathematical scheduling and smart caching:
| Operation | Performance | Notes |
|---|---|---|
| Simple patterns | ~0.002ms | Basic cron patterns |
| Complex patterns | ~0.008ms | Advanced patterns with nthWeekDay |
| Timezone conversion | 1.68x overhead | With caching (was 41x without) |
| Humanization | ~0.5ms | With locale caching |
| Memory usage | < 50KB | Per Runner instance |
| CPU idle | ~0% | Mathematical scheduling, not polling |
Optimization Highlights
- ✅ Timezone Cache: Reduces overhead from 41x to 1.68x
- ✅ nthWeekDay Cache: 3.2x speedup for nth weekday patterns
- ✅ Validation Optimization: 1.2x improvement
- ✅ EOD Parsing Optimization: 3.3x faster
For detailed benchmarks, see HUMANIZE_FINAL_REPORT.md.
🌍 Supported Locales
JCRON supports humanization in 10+ languages:
| Code | Language | Example |
|---|---|---|
en |
English | "Daily at 9:00 AM" |
tr |
Turkish | "Günlük saat 9:00" |
es |
Spanish | "Diario a las 9:00" |
fr |
French | "Quotidien à 9:00" |
de |
German | "Täglich um 9:00" |
pl |
Polish | "Codziennie o 9:00" |
pt |
Portuguese | "Diário às 9:00" |
it |
Italian | "Giornaliero alle 9:00" |
cz |
Czech | "Denně v 9:00" |
nl |
Dutch | "Dagelijks om 9:00" |
🧪 Testing
# Run all tests
bun test
# Run with coverage
bun test --coverage
# Run specific test suite
bun test tests/01-core-engine.test.ts
# Run linter
npm run lint
# Build and test
npm run build && npm testTest Coverage
- ✅ 175+ passing tests
- ✅ 91.6% coverage
- ✅ Edge cases covered (DST, leap years, month boundaries)
- ✅ Performance benchmarks
📊 Bundle Size
JCRON is optimized for minimal bundle size:
| Format | Size (Gzipped) | Use Case |
|---|---|---|
| ESM | ~45 KB | Modern bundlers |
| CJS | ~46 KB | Node.js |
| UMD | ~48 KB | Browsers |
| UMD Min | ~22 KB | CDN usage |
Tree-shaking enabled for all formats.
🛠️ Build System
JCRON uses a modern build system with multiple output formats:
# Build all formats
npm run build
# Build specific format
npm run build:rollup # ESM, CJS, UMD
npm run build:types # TypeScript declarations
# Watch mode
npm run build:watch
# Analyze bundle size
npm run size
npm run analyzeFor detailed build information, see BUILD_SYSTEM.md.
🤝 Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Development Setup
# Clone the repository
git clone https://github.com/meftunca/jcron.git
cd jcron/node-port
# Install dependencies
bun install
# Run tests
bun test
# Build
npm run build📄 License
MIT © AI Assistant (Ported from Go)
🙏 Acknowledgments
- Inspired by the robust Go library jcron
- Built with TypeScript, Rollup, and modern tooling
- Community-driven with contributions from developers worldwide
📞 Support
- 📖 Documentation
- 🐛 Issue Tracker
- 💬 Discussions
- 📧 Email: support@devloops.com
Made with ❤️ by the JCRON Team