npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@openworkers/croner-wasm

v0.3.1

Published

WebAssembly bindings for the croner cron expression parser

Downloads

483

Readme

croner-wasm

WebAssembly bindings for the croner cron expression parser.

Features

  • ✅ Parse and validate cron expressions
  • ✅ Get human-readable descriptions
  • ✅ Calculate next occurrences
  • ✅ Support for seconds (6-field format)
  • ✅ Quartz scheduler extensions (L, W, #)
  • ✅ Zero dependencies (pure WASM)
  • ✅ Works in Node.js, browsers, and bundlers

Installation

npm install @openworkers/croner-wasm
# or
bun add @openworkers/croner-wasm

Usage

Node.js

import { WasmCron } from '@openworkers/croner-wasm';

// Parse a cron expression
const cron = new WasmCron('0 * * * *');

// Get human-readable description
console.log(cron.describe());
// => "At minute 0 past every hour."

// Get next run time
const next = cron.nextRun();
console.log(next);
// => Date object

// Get multiple next runs
const nextRuns = cron.nextRuns(5);
console.log(nextRuns);
// => Array of 5 Date objects

Browser (ES Modules)

import init, { WasmCron } from '@openworkers/croner-wasm';

// Initialize WASM module (required in browser)
await init();

// Parse a cron expression
const cron = new WasmCron('0 * * * *');
console.log(cron.describe());

Validation

import { WasmCron } from '@openworkers/croner-wasm';

// Validate without creating an instance
if (WasmCron.validate('0 * * * *')) {
  console.log('Valid cron pattern!');
}

// Validate with seconds option
if (WasmCron.validate('0 * * * *', { seconds: 'disallowed' })) {
  console.log('Valid 5-field pattern!');
}

if (!WasmCron.validate('0 * * * * *', { seconds: 'disallowed' })) {
  console.log('6-field pattern rejected with disallowed seconds');
}

// Try-catch for parsing
try {
  const cron = new WasmCron('invalid pattern');
} catch (error) {
  console.error('Invalid cron:', error);
}

Parse and Describe

import { parseAndDescribe } from '@openworkers/croner-wasm';

const result = parseAndDescribe('0 0 * * FRI');
console.log(result);
// => { pattern: "0 0 * * FRI", description: "At 00:00 on Friday" }

Seconds Configuration

You can control whether seconds are allowed, required, or disallowed:

// Optional seconds (default) - accepts both 5 and 6 fields
const cron1 = new WasmCron('0 * * * *');
const cron2 = new WasmCron('0 * * * * *');

// Disallow seconds - only 5-field patterns allowed
const cron3 = new WasmCron('0 * * * *', { seconds: 'disallowed' });
// new WasmCron('0 * * * * *', { seconds: 'disallowed' }); // ❌ Throws error

// Require seconds - only 6-field patterns allowed
const cron4 = new WasmCron('0 * * * * *', { seconds: 'required' });
// new WasmCron('0 * * * *', { seconds: 'required' }); // ❌ Throws error

Advanced Usage

const cron = new WasmCron('*/5 * * * *', { timezone: 'UTC' });

// Get pattern
console.log(cron.pattern());
// => "*/5 * * * *"

// Check if pattern has seconds
console.log(cron.hasSeconds());
// => false

const cronWithSeconds = new WasmCron('0/30 * * * * *');
console.log(cronWithSeconds.hasSeconds());
// => true

// Get next run from now
const next = cron.nextRun();

// Get next run from specific date
const from = new Date('2024-01-01T00:00:00Z');
const nextFromDate = cron.nextRun(from);

// Get multiple next runs
const nextRuns = cron.nextRuns(10);          // From now
const nextRunsFrom = cron.nextRuns(10, from); // From specific date

// Check if a date matches the pattern
const matches = cron.isMatch(new Date());

Supported Cron Formats

5-field format (minute hour day month weekday):

0 * * * *        # Every hour
*/5 * * * *      # Every 5 minutes
0 0 * * FRI      # Every Friday at midnight
0 9-17 * * MON-FRI  # Every hour from 9-5, Mon-Fri

6-field format (second minute hour day month weekday):

0/30 * * * * *   # Every 30 seconds
*/5 * * * * *    # Every 5 seconds
0 0 * * * *      # Every hour (at 0 seconds)

Quartz extensions:

0 0 L * *        # Last day of the month
0 0 15W * *      # Nearest weekday to the 15th
0 0 * * 5L       # Last Friday of the month
0 0 * * 5#3      # Third Friday of the month

API Reference

WasmCron Class

Constructor

  • new WasmCron(pattern: string, options?: { timezone?: string, seconds?: 'optional' | 'required' | 'disallowed' }) - Parse a cron expression (throws on invalid)
    • seconds: 'optional' (default) - Accept both 5 and 6-field patterns
    • seconds: 'required' - Only accept 6-field patterns (with seconds)
    • seconds: 'disallowed' - Only accept 5-field patterns (no seconds)

Static Methods

  • WasmCron.validate(pattern: string, options?: { seconds?: 'optional' | 'required' | 'disallowed' }): boolean - Validate a pattern

Instance Methods

  • describe(): string - Get human-readable description
  • pattern(): string - Get the original pattern
  • hasSeconds(): boolean - Check if pattern uses seconds (6-field format)
  • nextRun(from?: Date): Date | null - Get next occurrence (from now or specified date)
  • nextRuns(count: number, from?: Date): Date[] - Get N next occurrences (from now or specified date)
  • isMatch(date: Date): boolean - Check if date matches pattern

Functions

  • parseAndDescribe(pattern: string): { pattern: string, description: string } - Parse and describe in one call

Package Exports

This package supports multiple environments:

{
  "exports": {
    ".": {
      "node": "./dist/node/croner_wasm.js",
      "browser": "./dist/croner_wasm.js",
      "default": "./dist/bundler/croner_wasm.js"
    }
  }
}
  • Node.js: Uses CommonJS build automatically
  • Browser: Uses ES modules with WASM
  • Bundlers (webpack, rollup, vite): Uses optimized build

Building from Source

Prerequisites

  • Rust (install via rustup)
  • wasm-pack: cargo install wasm-pack

Build Commands

# Build all targets (Node.js, browser, bundlers)
bun run build:all

# Or build individually
bun run build           # Web only
bun run build:node      # Node.js only
bun run build:bundler   # Bundlers only

# Run tests
bun run test            # Rust tests
bun run test:wasm       # WASM tests in browser

File Size

  • WASM binary: ~119 KB (optimized)
  • JS glue code: ~12 KB
  • Total: ~131 KB

License

MIT

Credits

Built on top of croner by Hexagon.