A tiny, fast, and modern date utility library for JavaScript/TypeScript with zero dependencies.
- 🪶 Lightweight - Zero dependencies, minimal bundle size
- 🌍 i18n Support - Locale-aware formatting with
IntlAPI - ⏰ UTC First - All operations work in UTC by default, avoiding timezone pitfalls
- 🎯 Two APIs - Choose between tree-shakeable functions or chainable object API
- 📦 Tree-shakeable - Import only what you need
- 🦕 Deno Native - Built for Deno, works everywhere
- ✅ Fully Tested - Comprehensive test coverage
- Features
- Installation
- Quick Start
- Configuration
- API Reference
- Performance
- Why Chronal?
- Design Principles
- Browser Support
- Contributing
- License
// Functional API (tree-shakeable)
import { addTime, formatDate, subtractTime } from "jsr:@chronal/core";
// Chainable API
import { chronal } from "jsr:@chronal/core/chainable";npm install chronal// Functional API (tree-shakeable)
import { addTime, formatDate, subtractTime } from "chronal";
// Chainable API
import { chronal } from "chronal/chainable";- Functional API (tree-shakeable): ~2.3 KB gzipped for typical imports (5 functions)
- Chainable API: ~4.8 KB gzipped (includes all functionality)
Choose the functional API for libraries and performance-critical code, or the chainable API for better developer experience in applications.
Chronal offers two ways to work with dates:
Perfect for minimal bundle size (~2.3 KB gzipped) - import only what you need:
import {
addTime,
endOf,
formatDate,
fromNow,
isToday,
parseDate,
startOf,
subtract,
} from "chronal";
const date = new Date("2024-06-15T14:35:22Z");
// Format dates
formatDate(date, "YYYY-MM-DD"); // '2024-06-15'
formatDate(date, "YYYY-MM-DD HH:mm:ss"); // '2024-06-15 14:35:22'
formatDate(date, "DD/MM/YYYY [at] HH:mm"); // '15/06/2024 at 14:35'
// Parse dates
parseDate("15/06/2024", "DD/MM/YYYY"); // Date object for June 15, 2024
// Add/subtract time
addTime(date, { days: 5, hours: 2 }); // 2024-06-20T16:35:22Z
subtract(date, { months: 1, days: 10 }); // 2024-05-05T14:35:22Z
// Start/End of period
startOf(date, "month"); // 2024-06-01T00:00:00.000Z
endOf(date, "day"); // 2024-06-15T23:59:59.999Z
// Relative time
fromNow(new Date(Date.now() - 300000)); // "5 minutes ago"
// Date checks
isToday(new Date()); // true
// Generate date ranges
datesUntil(new Date("2024-01-01"), new Date("2024-01-05"));
// [2024-01-01, 2024-01-02, 2024-01-03, 2024-01-04, 2024-01-05]Perfect for developer experience with convenient method chaining (~4.8 KB gzipped):
import { chronal } from "chronal/chainable";
// Create and chain operations
const date = chronal("2024-06-15T14:35:22Z")
.add({ months: 1, days: 5 })
.startOf("month")
.format("YYYY-MM-DD");
console.log(date); // "2024-07-01"
// Create with timezone - all operations use this timezone by default
const spDate = chronal("2024-06-15T14:30:00", { tz: "America/Sao_Paulo" });
spDate.format("YYYY-MM-DD HH:mm"); // Uses São Paulo time
spDate.startOf("day"); // Start of day in São Paulo
spDate.add({ days: 1 }); // Timezone is preserved
// All methods available
const result = chronal("2024-01-15")
.add({ days: 10 })
.subtract({ hours: 2 })
.format("MMMM DD, YYYY"); // "January 25, 2024"
// Query methods
chronal("2024-06-15").isLeapYear(); // true
chronal().isToday(); // true
chronal("2024-01-01").fromNow(); // "1 year ago"
// Get values
chronal("2024-06-15").get("month"); // 5 (0-indexed)
chronal("2024-06-15").quarter(); // 2
chronal("2024-06-15").daysInMonth(); // 30
// Generate date ranges
chronal("2024-01-01")
.until(new Date("2024-01-31"), { weeks: 1 })
.map((c) => c.format("YYYY-MM-DD"));
// ["2024-01-01", "2024-01-08", "2024-01-15", "2024-01-22", "2024-01-29"]Choose what fits your needs:
- Use functional API for maximum tree-shaking (smaller bundles)
- Use chainable API for better DX and readable code
- Mix both styles in the same project!
Set the default configuration for all date operations.
Parameters:
config(object) - Configuration object with optional properties:locale(string) - The locale code (e.g., 'en-US', 'pt-BR', 'fr-FR')timezone(string) - The default IANA timezone (e.g., 'UTC', 'America/Sao_Paulo')
Example:
import { formatDate, months, setChronalConfig, chronal } from "chronal";
// Default is 'en-US' and 'UTC'
formatDate(new Date("2024-06-15"), "MMMM"); // 'June'
// Change default locale
setChronalConfig({ locale: "pt-BR" });
formatDate(new Date("2024-06-15"), "MMMM"); // 'junho'
months(); // ['janeiro', 'fevereiro', 'março', ...]
// Change default timezone
setChronalConfig({ timezone: "America/Sao_Paulo" });
// You can still override per call
formatDate(new Date("2024-06-15"), "MMMM", { locale: "fr-FR" }); // 'juin'When using the chainable API, you can set a timezone for a specific instance. This timezone will be used for all operations on that instance:
import { chronal } from "chronal";
// Create instance with timezone
const spDate = chronal("2024-06-15T14:30:00", { tz: "America/Sao_Paulo" });
// All operations use the instance timezone
spDate.format("YYYY-MM-DD HH:mm"); // Uses São Paulo time (UTC-3)
spDate.startOf("day"); // Start of day in São Paulo
spDate.endOf("month"); // End of month in São Paulo
// Timezone is preserved across operations
const nextDay = spDate.add({ days: 1 });
nextDay.timezone; // "America/Sao_Paulo"
// Override timezone for specific operation
spDate.format("HH:mm", { tz: "UTC" }); // Use UTC instead
// Generated dates preserve timezone
const dates = spDate.until(new Date("2024-06-20"));
dates[0].timezone; // "America/Sao_Paulo"Benefits:
- ✅ Set timezone once, use everywhere in the chain
- ✅ Prevents accidental timezone mixing
- ✅ Clean API - no need to pass timezone to every method
- ✅ Can still override per method when needed
The chronal object provides a chainable API for convenient date manipulation.
Creates a Chronal instance with chainable methods.
Parameters:
date(Date | string | number, optional) - Initial date (defaults to current date)options(object, optional) - Configuration options:tz(string) - IANA timezone for this instance (e.g., 'America/Sao_Paulo')
Returns: Chronal instance with optional timezone
Examples:
// Create with current time
const now = chronal();
// Create from string
const date = chronal("2024-06-15");
// Create with timezone - all operations will use this timezone
const spDate = chronal("2024-06-15", { tz: "America/Sao_Paulo" });
spDate.format("YYYY-MM-DD HH:mm"); // Uses São Paulo time
spDate.startOf("day").timezone; // "America/Sao_Paulo" (preserved)API Reference:
All chainable methods correspond to functional API functions:
| Chainable Method | Functional API | Description |
|---|---|---|
.add(options) |
addTime(date, options) |
Add time units |
.subtract(options) |
subtract(date, options) |
Subtract time units |
.startOf(unit) |
startOf(date, unit) |
Start of time unit |
.endOf(unit) |
endOf(date, unit) |
End of time unit |
.set(options) |
setUnit(date, options) |
Set specific units |
.clamp(min, max) |
clampDate(date, min, max) |
Clamp between dates |
.format(pattern, opts?) |
formatDate(date, pattern, opts?) |
Format date |
.fromNow(locale?) |
fromNow(date, locale?) |
Relative time from now |
.toNow(locale?) |
toNow(date, locale?) |
Relative time to now |
.diff(date, unit) |
dateDiff(dateLeft, dateRight, unit) |
Difference between dates |
.isAfter(date) |
isAfter(date1, date2) |
Is after date |
.isBefore(date) |
isBefore(date1, date2) |
Is before date |
.isBetween(start, end) |
isBetween(date, start, end) |
Is between dates |
.isEqual(date) |
isEqual(date1, date2) |
Is equal to date |
.isSame(date, unit) |
isSame(date1, date2, unit) |
Is same time unit |
.isToday() |
isToday(date) |
Is today |
.isTomorrow() |
isTomorrow(date) |
Is tomorrow |
.isYesterday() |
isYesterday(date) |
Is yesterday |
.isLeapYear() |
isLeapYear(date) |
Is leap year |
.isValid() |
isValidDate(date) |
Is valid date |
.get(unit) |
getUnit(date, unit) |
Get specific unit value |
.quarter() |
getQuarter(date) |
Get quarter (1-4) |
.daysInMonth() |
daysInMonth(date) |
Days in month |
.week() |
weekOfYear(date) |
Week of year |
.until(end, step?) |
datesUntil(start, end, step?) |
Generate date array |
Example:
import { chronal } from "chronal";
// Create instance
const date = chronal("2024-06-15");
// Chain operations
const result = chronal("2024-01-15")
.add({ months: 6, days: 10 })
.startOf("month")
.add({ days: 5 })
.format("YYYY-MM-DD");
console.log(result); // "2024-07-06"
// Query methods
chronal("2024-06-15").isLeapYear(); // true
chronal().isToday(); // true
chronal("2024-06-15").diff(chronal("2024-07-15"), "days"); // -30
// All methods return new instances (immutable)
const original = chronal("2024-01-01");
const modified = original.add({ months: 1 });
console.log(original.format("MM")); // "01"
console.log(modified.format("MM")); // "02"Formats a date into a string using the specified format pattern.
Parameters:
date(Date) - The date to formatformatString(string) - Format pattern with tokensoptions(object, optional)locale(string) - Locale for internationalization (default: 'en-US')tz(string) - Timezone (default: 'UTC')
Format Tokens:
| Token | Output | Description |
|---|---|---|
YYYY |
2024 | 4-digit year |
YY |
24 | 2-digit year |
MMMM |
June | Full month name |
MMM |
Jun | Short month name |
MM |
06 | 2-digit month |
M |
6 | Month number |
DD |
05 | 2-digit day |
D |
5 | Day of month |
dddd |
Saturday | Full weekday name |
ddd |
Sat | Short weekday name |
HH |
14 | 2-digit hour (24h) |
H |
14 | Hour (24h) |
mm |
35 | 2-digit minute |
m |
35 | Minute |
ss |
22 | 2-digit second |
s |
22 | Second |
Literals: Use square brackets to escape literals: [at] → "at"
Examples:
const date = new Date("2024-06-15T14:35:22Z"); // This is a Saturday
formatDate(date, "YYYY-MM-DD"); // '2024-06-15'
formatDate(date, "DD/MM/YYYY HH:mm"); // '15/06/2024 14:35'
formatDate(date, "MMMM D, YYYY"); // 'June 15, 2024'
formatDate(date, "dddd, MMMM D, YYYY"); // 'Saturday, June 15, 2024'
formatDate(date, "ddd, MMM D"); // 'Sat, Jun 15'
formatDate(date, "YYYY-MM-DD [at] HH:mm"); // '2024-06-15 at 14:35'
// With locale
formatDate(date, "dddd, MMMM D, YYYY", { locale: "pt-BR" }); // 'sábado, junho 15, 2024'
formatDate(date, "ddd, D [de] MMM", { locale: "es-ES" }); // 'sáb, 15 de jun'Parses a date string into a Date object using an optional format pattern.
Parameters:
dateString(string) - The date string to parseformat(string, optional) - Format pattern (e.g., "YYYY-MM-DD", "DD/MM/YYYY")options(object, optional) - Parsing optionstz(string) - IANA timezone (e.g., 'America/Sao_Paulo')
Returns: Date object
Timezone Behavior:
When parsing date strings, parseDate follows these rules:
- Explicit timezone (e.g.,
Zor+03:00) - Always respected, ignoresconfig.timezone - No timezone - Uses
config.timezoneor thetzoption to interpret the string as local time in that timezone
// With explicit UTC marker (Z) - always UTC
parseDate("2026-01-12T02:59:59.999Z"); // UTC time, ignores config
// Without timezone - uses config.timezone
setChronalConfig({ timezone: "America/Sao_Paulo" });
parseDate("2026-01-12T02:59:59.999"); // Interpreted as São Paulo time
parseDate("2026-01-12"); // Midnight in São PauloSupported Tokens:
YYYY- 4-digit yearMM- 2-digit monthDD- 2-digit dayHH- 2-digit hour (24h)mm- 2-digit minutess- 2-digit second
Examples:
// Without format (uses native Date parser)
parseDate("2024-06-15"); // Date object
// With custom format
parseDate("15/06/2024", "DD/MM/YYYY");
parseDate("2024-06-15 14:30:00", "YYYY-MM-DD HH:mm:ss");
parseDate("06/15/2024", "MM/DD/YYYY");
// With timezone
parseDate("2024-06-15", { tz: "America/Sao_Paulo" }); // Parse as São Paulo timeAdds specified time units to a date.
Parameters:
date(Date) - The original dateoptions(object) - Time units to addyears(number)months(number)weeks(number)days(number)hours(number)minutes(number)seconds(number)milliseconds(number)
Returns: New Date object
Examples:
const date = new Date("2024-01-31T12:00:00Z");
addTime(date, { days: 5 }); // 2024-02-05T12:00:00.000Z
addTime(date, { months: 1 }); // 2024-02-29T12:00:00.000Z (handles leap year)
addTime(date, { years: 1, months: 2, days: 3 }); // 2025-04-03T12:00:00.000ZSubtracts specified time units from a date.
Parameters: Same as addTime()
Examples:
const date = new Date("2024-03-31T12:00:00Z");
subtract(date, { days: 5 }); // 2024-03-26T12:00:00.000Z
subtract(date, { months: 1 }); // 2024-02-29T12:00:00.000Z (handles month overflow)Extracts a specific unit from a date.
Parameters:
date(Date) - The date to extract fromunit('year' | 'month' | 'date' | 'day' | 'hour' | 'minute' | 'second')- Note:
'week'is not supported 'date'returns the day of the month (1-31)'day'returns the day of the week (0-6, where 0 is Sunday)
- Note:
Returns: Number
Examples:
const date = new Date("2024-06-15T14:35:22.500Z"); // This is a Saturday
getUnit(date, "year"); // 2024
getUnit(date, "month"); // 5 (0-indexed, June)
getUnit(date, "date"); // 15 (day of month)
getUnit(date, "day"); // 6 (day of week: Saturday)
getUnit(date, "hour"); // 14Sets a specific unit of a date to a new value, returning a new Date object.
Parameters:
date(Date) - The date to modifyunit('year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond')value(number) - The new value
Returns: New Date object
Examples:
const date = new Date("2024-06-15T14:35:22Z");
setUnit(date, "year", 2025); // 2025-06-15T14:35:22Z
setUnit(date, "month", 0); // 2024-01-15T14:35:22Z (January)
setUnit(date, "day", 20); // 2024-06-20T14:35:22ZReturns the start of the specified time unit.
Parameters:
date(Date) - The original dateunit('year' | 'month' | 'day' | 'hour' | 'minute' | 'second')
Examples:
const date = new Date("2024-06-15T14:35:22.500Z");
startOf(date, "year"); // 2024-01-01T00:00:00.000Z
startOf(date, "month"); // 2024-06-01T00:00:00.000Z
startOf(date, "day"); // 2024-06-15T00:00:00.000ZReturns the end (last millisecond) of the specified time unit.
Parameters: Same as startOf()
Examples:
const date = new Date("2024-06-15T14:35:22.500Z");
endOf(date, "year"); // 2024-12-31T23:59:59.999Z
endOf(date, "month"); // 2024-06-30T23:59:59.999Z
endOf(date, "day"); // 2024-06-15T23:59:59.999ZChecks if the first date is after the second date.
const date1 = new Date("2024-01-20T12:00:00Z");
const date2 = new Date("2024-01-15T12:00:00Z");
isAfter(date1, date2); // trueChecks if the first date is before the second date.
isBefore(date2, date1); // trueChecks if two dates are equal (same exact millisecond).
const date1 = new Date("2024-01-15T12:00:00.000Z");
const date2 = new Date("2024-01-15T12:00:00.000Z");
isEqual(date1, date2); // trueChecks if two dates are in the same time unit.
Parameters:
dateLeft(Date)dateRight(Date)unit('year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second')
const date1 = new Date("2024-06-15T14:30:00Z");
const date2 = new Date("2024-06-15T18:45:00Z");
isSame(date1, date2, "day"); // true (same day)
isSame(date1, date2, "hour"); // false (different hours)Checks if a date is between two other dates.
Parameters:
date(Date) - The date to checkstart(Date) - Start of rangeend(Date) - End of rangeinclusivity('[]' | '()' | '[)' | '(]', optional) - Default: '[]'[]- inclusive on both ends()- exclusive on both ends[)- inclusive start, exclusive end(]- exclusive start, inclusive end
const date = new Date("2024-06-15");
const start = new Date("2024-06-01");
const end = new Date("2024-06-30");
isBetween(date, start, end); // true
isBetween(date, start, end, "()"); // true
isBetween(start, start, end, "()"); // false (exclusive)Checks if a date is today (in UTC).
isToday(new Date()); // true
isToday(new Date("2024-01-01")); // falseChecks if a date is tomorrow (in UTC).
const tomorrow = new Date(Date.now() + 86400000);
isTomorrow(tomorrow); // trueChecks if a date is yesterday (in UTC).
const yesterday = new Date(Date.now() - 86400000);
isYesterday(yesterday); // trueChecks if a Date object is valid (not Invalid Date).
isValidDate(new Date("2024-06-15")); // true
isValidDate(new Date("invalid")); // false
isValidDate(new Date(NaN)); // falseReturns how long ago the date was from now, or how long until it in the future.
Returns: String ("5 minutes ago", "in 2 hours", "just now")
const fiveMinutesAgo = new Date(Date.now() - 300000);
fromNow(fiveMinutesAgo); // "5 minutes ago"
const inTwoHours = new Date(Date.now() + 7200000);
fromNow(inTwoHours); // "in 2 hours"Returns the time from now to the date (inverse of fromNow).
const inFiveMinutes = new Date(Date.now() + 300000);
toNow(inFiveMinutes); // "in 5 minutes"
const twoHoursAgo = new Date(Date.now() - 7200000);
toNow(twoHoursAgo); // "2 hours ago"Returns the latest date from the given dates.
const date1 = new Date("2024-01-15T12:00:00Z");
const date2 = new Date("2024-01-20T12:00:00Z");
const date3 = new Date("2024-01-10T12:00:00Z");
maxDate(date1, date2, date3); // 2024-01-20T12:00:00.000ZReturns the earliest date from the given dates.
minDate(date1, date2, date3); // 2024-01-10T12:00:00.000ZFinds the date in an array that is closest to the target date.
Parameters:
target(Date) - The target date to compare againstdates(Date[]) - Array of dates to search
Returns: Date | null
const target = new Date("2024-06-15");
const dates = [
new Date("2024-06-10"),
new Date("2024-06-14"),
new Date("2024-06-20"),
];
closestTo(target, dates); // Returns date for June 14Clamps a date between minimum and maximum bounds.
Parameters:
date(Date) - The date to clampmin(Date) - Minimum allowed datemax(Date) - Maximum allowed date
Returns: Date (either original, min, or max)
const min = new Date("2024-06-01");
const max = new Date("2024-06-30");
clampDate(new Date("2024-06-15"), min, max); // June 15 (within bounds)
clampDate(new Date("2024-05-15"), min, max); // June 1 (clamped to min)
clampDate(new Date("2024-07-15"), min, max); // June 30 (clamped to max)Generates an array of dates between start and end dates with a specified step.
Parameters:
start(Date) - The start date (inclusive)end(Date) - The end date (inclusive)step(object, optional) - Step increment (default:{ days: 1 })years(number)months(number)weeks(number)days(number)hours(number)minutes(number)seconds(number)milliseconds(number)
Returns: Date[] - Array of Date objects
Examples:
const start = new Date("2024-01-01");
const end = new Date("2024-01-05");
// Daily range (default)
datesUntil(start, end);
// [2024-01-01, 2024-01-02, 2024-01-03, 2024-01-04, 2024-01-05]
// Chainable: chronal("2024-01-01").until(new Date("2024-01-05"))
// Weekly range
const weekEnd = new Date("2024-01-31");
datesUntil(start, weekEnd, { weeks: 1 });
// [2024-01-01, 2024-01-08, 2024-01-15, 2024-01-22, 2024-01-29]
// Chainable: chronal(start).until(weekEnd, { weeks: 1 })
// Monthly range
const monthEnd = new Date("2024-06-15");
datesUntil(new Date("2024-01-15"), monthEnd, { months: 1 });
// [2024-01-15, 2024-02-15, 2024-03-15, 2024-04-15, 2024-05-15, 2024-06-15]
// Every 3 days
datesUntil(start, new Date("2024-01-10"), { days: 3 });
// [2024-01-01, 2024-01-04, 2024-01-07, 2024-01-10]
// Hourly range
datesUntil(
new Date("2024-01-01T09:00:00Z"),
new Date("2024-01-01T17:00:00Z"),
{ hours: 2 },
);
// [09:00, 11:00, 13:00, 15:00, 17:00]Note: Month boundaries are handled intelligently. For example, starting on Jan 31 with monthly steps will yield Feb 29 (leap year), Mar 31, Apr 30, etc.
Calculates the difference between two dates in the specified unit.
Parameters:
dateLeft(Date)dateRight(Date)unit('years' | 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds')
Returns: Number (can be negative)
con# `daysInMonth(date)`
### Date Information
#### `daysInMonth(date)`te("2024-01-20T12:00:00Z");
const date2 = new Date("2024-01-15T12:00:00Z");
dateDiff(date1, date2, "days"); // 5
dateDiff(date2, date1, "days"); // -5
dateDiff(date1, date2, "hours"); // 120Returns the number of days in the month of the given date.
Returns: Number (28-31)
daysInMonth(new Date("2024-02-15")); // 29 (leap year)
daysInMonth(new Date("2023-02-15")); // 28
daysInMonth(new Date("2024-04-15")); // 30Checks if the year of the given date is a leap year.
isLeapYear(new Date("2024-01-01")); // true
isLeapYear(new Date("2023-01-01")); // false
isLeapYear(new Date("2000-01-01")); // true (divisible by 400)
isLeapYear(new Date("1900-01-01")); // false (divisible by 100 but not 400)Returns the quarter (1-4) of the year for the given date.
Returns: 1 | 2 | 3 | 4
getQuarter(new Date("2024-01-15")); // 1 (Q1: Jan-Mar)
getQuarter(new Date("2024-04-15")); // 2 (Q2: Apr-Jun)
getQuarter(new Date("2024-07-15")); // 3 (Q3: Jul-Sep)
getQuarter(new Date("2024-10-15")); // 4 (Q4: Oct-Dec)Returns the week number of the year (1-53). Uses Sunday as the start of the week.
weekOfYear(new Date("2024-01-01")); // 1
weekOfYear(new Date("2024-01-08")); // 2
weekOfYear(new Date("2024-12-31")); // 53Returns an array of month names for the specified locale.
Parameters:
locale(string, optional) - Default: 'en-US'format('long' | 'short' | 'narrow', optional) - Default: 'long'
months("en-US", "long"); // ['January', 'February', ...]
months("en-US", "short"); // ['Jan', 'Feb', ...]
months("pt-BR", "long"); // ['janeiro', 'fevereiro', ...]Returns an array of weekday names (Sunday to Saturday) for the specified locale.
Parameters: Same as months()
weekdays("en-US", "long"); // ['Sunday', 'Monday', 'Tuesday', ...]
weekdays("en-US", "short"); // ['Sun', 'Mon', 'Tue', ...]
weekdays("pt-BR", "long"); // ['domingo', 'segunda-feira', 'terça-feira', ...]Key optimizations:
- Format string caching (no repeated regex parsing)
- Fast UTC path (avoids expensive Intl.DateTimeFormat for UTC)
- Optimized padding functions
- Direct string concatenation
- Minimal object allocations (no temporary Date objects where possible)
- Short-circuit comparisons in isSame
- Efficient week and quarter calculations
Chronal offers a modern approach to date manipulation with a focus on simplicity and performance:
- Two APIs in one - Choose functional for tree-shaking or chainable for convenience
- Performance-focused - Optimized for common operations like formatting
- Zero dependencies - Built on native JavaScript APIs
- UTC-first - Reduces timezone-related bugs by defaulting to UTC
- Lightweight - Small bundle size, fully tree-shakeable
- Modern - ES modules, TypeScript support, immutable operations
Functional API (tree-shakeable):
import { addTime, formatDate } from "chronal";
// Bundle: ~2-3KB (only imported functions)Chainable API:
import { chronal } from "chronal";
// Bundle: ~25-30KB (all methods included)Recommendation: Use functional API for libraries and performance-critical apps, chainable API for application code where DX matters more.
Chronal works well alongside other date libraries. Choose the tool that best fits your project's needs.
- UTC First - All operations work in UTC to avoid timezone surprises
- Immutability - Functions always return new Date objects
- Zero Dependencies - Leverages native Intl API for localization
- Performance - Optimized hot paths with caching
- Type Safety - Full TypeScript support
- Small API Surface - Easy to learn, hard to misuse
Chronal works in all modern browsers and JavaScript runtimes that support:
- ES6+ features
Intl.DateTimeFormatAPI- Native Date object
Contributions are welcome! Please feel free to submit a Pull Request.
MIT © André Luiz Gomes Filho