chroncraft
v0.3.0
Published
Next-generation JavaScript date/time library - lightweight, fast, and tree-shakeable
Maintainers
Readme
chroncraft
Next-generation JavaScript date/time library - lightweight, fast, and tree-shakeable
Why chroncraft?
chroncraft is a modern date/time library designed to replace legacy solutions like Moment.js and overcome performance limitations in date-fns. It combines ultra-lightweight bundle size with cutting-edge optimizations.
Key Features
- Ultra-lightweight: < 5KB minified + gzipped for core functionality
- Tree-shakeable: 100% ES module support with granular imports
- High Performance: 2-3x faster than date-fns for common operations
- Type-safe: Full TypeScript support with strict mode
- Immutable: All date objects are immutable by default
- Zero Dependencies: No external runtime dependencies
- SIMD Optimized: Automatic SIMD acceleration for batch operations
- Timezone Support: Lazy-loaded timezone handling
- Temporal Compatible: Temporal API compatibility layer
Installation
npm install chroncraftyarn add chroncraftpnpm add chroncraftQuick Start
import { createDate, format, addDays } from 'chroncraft';
// Create a date
const date = createDate('2025-01-15T10:30:00Z');
// Format it
format(date, 'YYYY-MM-DD'); // '2025-01-15'
format(date, 'MMM DD, YYYY'); // 'Jan 15, 2025'
// Arithmetic
const future = addDays(date, 5); // 2025-01-20
const past = addDays(date, -5); // 2025-01-10
// Comparison
import { isBefore, diff } from 'chroncraft';
const date1 = createDate('2025-01-15');
const date2 = createDate('2025-01-20');
isBefore(date1, date2); // true
diff(date1, date2, 'day'); // 5API Reference
Core Functions
createDate(input?: DateInput): ChronoDate
Creates an immutable ChronoDate from various inputs.
createDate(); // Current date/time
createDate('2025-01-15'); // From ISO string
createDate(1705334400000); // From timestamp
createDate(new Date()); // From native Datenow(): ChronoDate
Returns the current date and time.
const current = now();isValid(input: unknown): boolean
Checks if a value can be converted to a valid date.
isValid('2025-01-15'); // true
isValid('invalid'); // falseFormatting
format(date: ChronoDate, formatStr: string): string
Formats a date according to the specified format string.
Format Tokens:
| Token | Description | Example |
|-------|-------------|---------|
| YYYY | 4-digit year | 2025 |
| YY | 2-digit year | 25 |
| MMMM | Full month name | January |
| MMM | Short month name | Jan |
| MM | 2-digit month | 01 |
| M | Month number | 1 |
| DD | 2-digit day | 15 |
| D | Day number | 15 |
| HH | 24-hour (2-digit) | 13 |
| H | 24-hour | 13 |
| hh | 12-hour (2-digit) | 01 |
| h | 12-hour | 1 |
| mm | 2-digit minute | 05 |
| ss | 2-digit second | 09 |
| SSS | Milliseconds | 123 |
| A | AM/PM | PM |
| a | am/pm | pm |
Presets:
import { FORMAT_PRESETS } from 'chroncraft';
format(date, 'ISO'); // ISO 8601
format(date, 'ISO_DATE'); // YYYY-MM-DD
format(date, 'SHORT'); // M/D/YYYY
format(date, 'MEDIUM'); // MMM D, YYYY
format(date, 'LONG'); // MMMM D, YYYYLiteral Text:
format(date, '[Today is] MMMM D, YYYY');
// 'Today is January 15, 2025'Parsing
parseISO(isoString: string): ChronoDate
Parses an ISO 8601 formatted string.
parseISO('2025-01-15'); // Date only
parseISO('2025-01-15T10:30:00Z'); // With time
parseISO('2025-01-15T10:30:00.123Z'); // With milliseconds
parseISO('2025-01-15T10:30:00+05:30'); // With timezoneArithmetic
import {
addDays,
addMonths,
addYears,
addHours,
addMinutes,
addSeconds,
addDuration,
subtractDays,
} from 'chroncraft';
const date = createDate('2025-01-15T10:00:00Z');
addDays(date, 5); // Add 5 days
addMonths(date, 2); // Add 2 months
addYears(date, 1); // Add 1 year
addHours(date, 3); // Add 3 hours
// Complex duration
addDuration(date, {
days: 5,
hours: 3,
minutes: 30,
}); // 2025-01-20T13:30:00Z
subtractDays(date, 5); // Subtract 5 daysComparison
import {
isBefore,
isAfter,
isSame,
isBetween,
diff,
min,
max,
} from 'chroncraft';
const date1 = createDate('2025-01-15');
const date2 = createDate('2025-01-20');
isBefore(date1, date2); // true
isAfter(date2, date1); // true
isSame(date1, date2, 'month'); // true
isBetween(date1, date1, date2); // true
// Calculate difference
diff(date1, date2, 'day'); // 5
diff(date1, date2, 'hour'); // 120
// Min/max
min(date1, date2); // date1
max(date1, date2); // date2Timezone Support
import { toTimezone, getTimezoneOffset } from 'chroncraft/timezone';
const utcDate = createDate('2025-01-15T10:00:00Z');
// Convert to different timezone
const istDate = await toTimezone(utcDate, 'Asia/Kolkata');
const pstDate = await toTimezone(utcDate, 'PST');
const customDate = await toTimezone(utcDate, '+05:30');
// Get timezone offset
getTimezoneOffset('PST'); // -480 (minutes)Temporal API Compatibility
import { PlainDate, PlainTime, PlainDateTime } from 'chroncraft/temporal';
// Use Temporal-like API
const date = PlainDate.from('2025-01-15');
const time = PlainTime.from('10:30:00');
const dateTime = PlainDateTime.from('2025-01-15T10:30:00Z');
// Convert to ChronoDate
const chronoDate = date.toChronoDate();Batch Operations (SIMD Optimized)
import { formatBatch, addDurationBatch } from 'chroncraft/simd';
const dates = [date1, date2, date3, date4];
// Format multiple dates (automatically uses SIMD if available)
const formatted = formatBatch(dates, 'YYYY-MM-DD');
// Add duration to multiple dates
const future = addDurationBatch(dates, { days: 5 });Tree-Shaking
chroncraft is fully tree-shakeable. Import only what you need:
// Minimal bundle (~3KB)
import { createDate, format } from 'chroncraft';
// With parsing (~4KB)
import { createDate, format, parseISO } from 'chroncraft';
// With timezone (~7KB)
import { createDate, format } from 'chroncraft';
import { toTimezone } from 'chroncraft/timezone';Performance
chroncraft is designed for performance:
| Operation | chroncraft | date-fns | Improvement | |-----------|---------|----------|-------------| | Format | ~3.2M ops/sec | ~1.1M ops/sec | 2.9x faster | | Parse | ~2.8M ops/sec | ~1.2M ops/sec | 2.3x faster | | Arithmetic | ~5.1M ops/sec | ~2.4M ops/sec | 2.1x faster | | Comparison | ~8.5M ops/sec | ~4.2M ops/sec | 2.0x faster |
Benchmarks run on Node.js 18+ with Apple M1
Bundle Size Comparison
| Library | Size (minified + gzipped) | |---------|---------------------------| | chroncraft (core) | 4.2 KB | | date-fns | 13.4 KB | | Moment.js | 71.5 KB | | Luxon | 23.2 KB | | Day.js | 6.8 KB |
Browser Support
- Chrome/Edge: Latest 2 versions
- Firefox: Latest 2 versions
- Safari: Latest 2 versions
- Node.js: 18+
TypeScript
chroncraft is written in TypeScript and provides full type definitions out of the box.
import type { ChronoDate, Duration, Unit } from 'chroncraft';
const date: ChronoDate = createDate('2025-01-15');
const duration: Duration = { days: 5, hours: 3 };
const unit: Unit = 'day';Migration Guides
From Moment.js
// Moment.js
moment().format('YYYY-MM-DD');
moment().add(5, 'days');
moment('2025-01-15').isBefore('2025-01-20');
// chroncraft
format(now(), 'YYYY-MM-DD');
addDays(now(), 5);
isBefore(createDate('2025-01-15'), createDate('2025-01-20'));From date-fns
// date-fns
import { format, addDays, isBefore } from 'date-fns';
format(new Date(), 'yyyy-MM-dd');
addDays(new Date(), 5);
isBefore(new Date('2025-01-15'), new Date('2025-01-20'));
// chroncraft
import { format, addDays, isBefore, createDate } from 'chroncraft';
format(createDate(), 'YYYY-MM-DD');
addDays(createDate(), 5);
isBefore(createDate('2025-01-15'), createDate('2025-01-20'));Contributing
Contributions are welcome! Please read our Contributing Guide for details.
License
MIT © Ian Pinto
Acknowledgments
- Inspired by Moment.js, date-fns, Day.js, and the Temporal proposal
- Built with TypeScript, tsup, and Vitest
- Performance optimizations inspired by SIMD.js and WebAssembly
