Config Reference
Every option you can pass to generateRecurringDates, getRecurringDates, or useRecurringDates.
STARTS_ONrequiredstring—The start date of the recurrence range. Parsed using the value of FORMAT. Must be a valid date string matching the chosen format.
Example
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-01-2025",
FREQUENCY: "D",
});ENDS_ONrequiredstring—The end date of the recurrence range. Must be on or after STARTS_ON. Parsed using the value of FORMAT.
Example
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-03-2025", // generate through March
FREQUENCY: "W",
WEEK_DAYS: ["MON"],
});FREQUENCY"D" | "W" | "M" | "Y""D"Controls how often dates recur. "D" = Daily, "W" = Weekly, "M" = Monthly, "Y" = Yearly.
Example
// Daily
generateRecurringDates({ STARTS_ON: "01-01-2025", ENDS_ON: "07-01-2025", FREQUENCY: "D" });
// Weekly
generateRecurringDates({ STARTS_ON: "01-01-2025", ENDS_ON: "31-01-2025", FREQUENCY: "W", WEEK_DAYS: ["MON"] });
// Monthly
generateRecurringDates({ STARTS_ON: "01-01-2025", ENDS_ON: "31-12-2025", FREQUENCY: "M", MONTH_DATES: [1] });
// Yearly
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-12-2027",
FREQUENCY: "Y",
MONTH_NAMES: ["JAN"],
WEEK_ORDINALS: ["FIRST"],
WEEK_DAYS: ["MON"],
});INTERVALnumber1Skip N cycles between occurrences. For example, INTERVAL: 2 with weekly frequency means every other week. INTERVAL: 3 with monthly means every third month.
Example
// Every other week on Monday
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-03-2025",
FREQUENCY: "W",
INTERVAL: 2,
WEEK_DAYS: ["MON"],
});
// Every 3 months on the 1st
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-12-2025",
FREQUENCY: "M",
INTERVAL: 3,
MONTH_DATES: [1],
});WEEK_DAYS("SUN" | "MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT")[]["MON"]Array of ISO weekday codes to include. Used with FREQUENCY: "W" (weekly) and FREQUENCY: "Y" (yearly ordinal patterns).
Example
// Every Mon, Wed, Fri
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-01-2025",
FREQUENCY: "W",
WEEK_DAYS: ["MON", "WED", "FRI"],
});
// result.text → "Every week on Monday, Wednesday and Friday"SUNMONTUEWEDTHUFRISATMONTH_DATESnumber[][1]Specific calendar dates within each month (1–31). Used with FREQUENCY: "M". Dates that don't exist in a given month (e.g. 31 in February) are automatically skipped.
Example
// 1st and 15th of every month
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-12-2025",
FREQUENCY: "M",
MONTH_DATES: [1, 15],
});
// result.text → "Every month on 1st and 15th"WEEK_ORDINALS("FIRST" | "SECOND" | "THIRD" | "FOURTH" | "FIFTH" | "LAST")[]["FIRST"]Which occurrence of the weekday within the month to target. Used with FREQUENCY: "Y" to build ordinal patterns like "the last Friday of December".
Example
// Last Monday of January every year
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-12-2027",
FREQUENCY: "Y",
MONTH_NAMES: ["JAN"],
WEEK_ORDINALS: ["LAST"],
WEEK_DAYS: ["MON"],
});
// result.text → "Every year on last Monday of January"FIRSTSECONDTHIRDFOURTHFIFTHLASTMONTH_NAMES("JAN"|"FEB"|"MAR"|"APR"|"MAY"|"JUN"|"JUL"|"AUG"|"SEP"|"OCT"|"NOV"|"DEC")[]["JAN"]Which months to include in a yearly recurrence. Used with FREQUENCY: "Y". Combine with WEEK_ORDINALS and WEEK_DAYS to describe the exact day.
Example
// First Monday of March and September every year
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-12-2027",
FREQUENCY: "Y",
MONTH_NAMES: ["MAR", "SEP"],
WEEK_ORDINALS: ["FIRST"],
WEEK_DAYS: ["MON"],
});JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDECEXCLUDE_DATESstring[][]Dates to remove from the generated output. Each entry must be a valid date string matching FORMAT. Useful for skipping holidays or one-off exceptions.
Example
generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-01-2025",
FREQUENCY: "W",
WEEK_DAYS: ["MON"],
EXCLUDE_DATES: ["06-01-2025", "20-01-2025"],
});
// 06 Jan and 20 Jan will NOT appear in result.datesFORMAT"DD-MM-YYYY" | "MM-DD-YYYY" | "YYYY-MM-DD" | "MM/DD/YYYY" | "DD/MM/YYYY" | "MMM DD YYYY""DD-MM-YYYY"Date format applied to both input parsing (STARTS_ON, ENDS_ON, EXCLUDE_DATES) and the output dates array. Pick one format and use it consistently throughout the config.
Example
// ISO format
generateRecurringDates({
STARTS_ON: "2025-01-01",
ENDS_ON: "2025-03-31",
FREQUENCY: "W",
WEEK_DAYS: ["TUE", "THU"],
FORMAT: "YYYY-MM-DD",
});
// result.dates → ["2025-01-07", "2025-01-09", ...]
// Human-readable format
generateRecurringDates({
STARTS_ON: "Jan 01 2025",
ENDS_ON: "Mar 31 2025",
FREQUENCY: "M",
MONTH_DATES: [1],
FORMAT: "MMM DD YYYY",
});
// result.dates → ["Jan 01 2025", "Feb 01 2025", "Mar 01 2025"]DD-MM-YYYY31-01-2025MM-DD-YYYY01-31-2025YYYY-MM-DD2025-01-31MM/DD/YYYY01/31/2025DD/MM/YYYY31/01/2025MMM DD YYYYJan 31 2025TIMEZONEstringundefinedOptional IANA timezone identifier. When provided, date generation respects that timezone's calendar day boundaries. Omitting it (or passing null / undefined) falls back to local time. Any identifier accepted by Intl.DateTimeFormat is valid — e.g. 'America/New_York', 'Europe/London', 'Asia/Kolkata', 'UTC'.
Example
// Schedule weekly meetings in New York time
generateRecurringDates({
STARTS_ON: "01-03-2025",
ENDS_ON: "31-03-2025",
FREQUENCY: "W",
WEEK_DAYS: ["MON", "WED", "FRI"],
TIMEZONE: "America/New_York",
});
// Auto-detect the current user's timezone
import { getUserTimezone } from "recurring-dates";
generateRecurringDates({ ..., TIMEZONE: getUserTimezone() });
// Invalid timezone → error object, no exception thrown
// { dates: [], error: "Invalid timezone: 'Bad/Zone' ..." }Return Value
On Success
{ text: string, dates: string[] } — text is a human-readable description (e.g. "Every week on Monday and Thursday"). dates is a sorted array of date strings in the specified format.
On Validation Error
{ dates: [], error: string } — The error field contains a descriptive validation message. The text field is omitted.
Validation Rules
- Both STARTS_ON and ENDS_ON are required.
- Dates must be valid according to FORMAT.
- STARTS_ON must be before or equal to ENDS_ON.
- Weekly frequency requires at least one WEEK_DAYS entry.
- Monthly frequency requires at least one MONTH_DATES entry.
- Yearly frequency requires MONTH_NAMES, WEEK_ORDINALS, and WEEK_DAYS.
- All EXCLUDE_DATES must be valid according to FORMAT.
- TIMEZONE must be a valid IANA timezone identifier when provided.