@typescript-calendar-lib/cli
v0.5.3
Published
Terminal calendar renderer with themes and ANSI color schemes
Downloads
2,237
Maintainers
Readme
@typescript-calendar-lib/cli
Render month, year, or date-range calendars as plain text — with optional ANSI colors, themes, and color schemes. Includes a command-line binary.
Installation
pnpm add @typescript-calendar-lib/cli
# or
npm install @typescript-calendar-lib/cli
# or
bun add @typescript-calendar-lib/cliRendering API
calendar(options: CalendarOptions): string
Render a single month:
import { calendar } from "@typescript-calendar-lib/cli";
console.log(calendar({ year: 2026, month: 9 })); September 2026
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30calendarYear(options: CalendarYearOptions): string
Render a full year as a 4 columns × 3 rows grid:
console.log(calendarYear({ year: 2026 }));calendarRange(options: CalendarRangeOptions): string
Render every month from from to to (inclusive), each on its own block:
console.log(calendarRange({
from: new Date(2026, 5, 1),
to: new Date(2026, 8, 30),
}));Options
All options from @typescript-calendar-lib/core are supported, plus these CLI-specific extras:
| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| theme | ThemeName \| CliTheme | "default" | Visual theme ("default" | "modern") or custom theme object |
| colorScheme | ColorSchemeName \| CliPalette | "default" | Color scheme, active when color: true |
| today | Date | new Date() | Reference date for "today" coloring |
| cellData | (date: Date) => unknown | — | Resolve per-cell data; passed to renderCell |
| renderCell | (day, date, state, data?) => string | — | Custom cell text; replaces the day cell verbatim |
| showWeekNumbers | boolean | false | Print a 2-char week-number column at the start of each row. weekStart: "monday" → ISO 8601 week; "sunday" → week-containing-Jan-1 week (US cal -w convention) |
CLI Binary
The package ships a typescript-calendar-lib binary:
typescript-calendar-lib # current month
typescript-calendar-lib 2026 # current month of 2026
typescript-calendar-lib 2026 9 # September 2026
typescript-calendar-lib --year # current year as a 4×3 grid
typescript-calendar-lib 2026 --year # 2026 as a 4×3 grid
typescript-calendar-lib --range 2026-01-01 2026-03-31 # months in a date rangeOptions
--theme <name> Look: default | modern (default: default)
--color-scheme <name> Colors: default | ocean | forest | sunset | mono
--color Enable ANSI colors (auto-detected for TTY)
--no-color Disable ANSI colors
--locale <lang> Language: en | ja | es | de | fr | ko | zh (default: en)
--week-start <day> First weekday: sunday | monday (default: sunday)
--highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)
--highlight-style <style> Highlight style: bracket | reverse (default: bracket)
--today <YYYY-MM-DD> Override today (marks the date, defaults year/month)
--year Render the whole year as a 4×3 grid
--range <FROM> <TO> Render months from FROM to TO (YYYY-MM-DD)
-v, --version Show version
-h, --help Show this helpColor detection
Colors are enabled automatically when stdout is a TTY, and disabled when piped or redirected. --color and --no-color override the detection; NO_COLOR and FORCE_COLOR environment variables are also respected (explicit flags always win).
Example with modern theme and ocean color scheme:
typescript-calendar-lib 2026 9 --theme modern --color-scheme ocean --colorLocalized, Monday-start, with a highlighted date:
typescript-calendar-lib 2026 9 --locale ja --week-start monday --highlight 2026-09-08Themes
ThemeName
type ThemeName = "default" | "modern";"default"— plain text, space-separated cells, no frame"modern"— box-drawing frame (┌───┬───┐style)
CliTheme
Custom themes are plain objects:
import type { CliTheme } from "@typescript-calendar-lib/cli";
const myTheme: CliTheme = {
cellWidth: 4,
separator: " | ",
frame: null, // or a FrameChars object for bordered layout
};| Property | Type | Description |
| :--- | :--- | :--- |
| cellWidth | number | Width of each date cell |
| separator | string | Separator between cells |
| frame | FrameChars \| null | Frame characters, or null for no frame |
FrameChars
interface FrameChars {
topLeft: string;
topRight: string;
bottomLeft: string;
bottomRight: string;
h: string; // horizontal line
v: string; // vertical line
j: string; // header/body intersection (┬, ┼)
footJ: string; // bottom intersection (┴)
}The built-in "modern" theme uses ┌ ┐ └ ┘ ─ │ ┬ ┴.
THEMES
const THEMES: Record<ThemeName, CliTheme>;resolveTheme(theme?)
Resolves a ThemeName | CliTheme to a CliTheme (defaults to "default").
Color Schemes
ColorSchemeName
type ColorSchemeName = "default" | "ocean" | "forest" | "sunset" | "mono";"default"— colors range (yellow) and highlight (reverse) only"ocean"— cyan/blue palette"forest"— green palette"sunset"— magenta/orange palette"mono"— grayscale
CliPalette
Each field is an ANSI foreground color code (or background code for highlight). undefined means "no coloring":
interface CliPalette {
title?: number;
weekday?: number;
day?: number;
weekend?: number;
today?: number;
highlight?: number; // used with highlightStyle: "reverse"
range?: number;
frame?: number;
dim?: number;
}A custom palette can be passed directly:
calendar({
year: 2026,
month: 9,
color: true,
colorScheme: { title: 36, range: 33, today: 33 },
});COLOR_SCHEMES and resolveColorScheme(scheme?)
Predefined schemes and the resolver (defaults to "default").
Examples
Highlight today
calendar({
year: 2026,
month: 9,
highlight: new Date(2026, 8, 8),
highlightStyle: "bracket", // [8]
});Reverse-video highlight requires color: true:
calendar({
year: 2026,
month: 9,
highlight: new Date(2026, 8, 8),
highlightStyle: "reverse",
color: true,
});Range coloring
calendar({
year: 2026,
month: 9,
range: { from: new Date(2026, 8, 1), to: new Date(2026, 8, 15) },
color: true,
});When a date is both highlighted and in range, the highlight takes precedence.
Per-cell data & custom cells
cellData attaches your own data to dates; renderCell replaces the day-cell rendering. cellData is called once per real cell, and returning undefined means "no data":
calendar({
year: 2026,
month: 9,
cellData: (date) => (date.getDate() === 15 ? "★" : undefined),
renderCell: (day, _date, _state, data) =>
data !== undefined ? `[${day}]` : String(day),
});renderCell receives (day, date, state, data):
state—getCalendarCellState(date)result (isWeekend,isToday,isHighlight,isInRange,dayOfWeek)data— the resolvedcellDatavalue for that date (undefinedwhen none)
The returned string replaces the cell verbatim — no padding, colorization, or highlight/range styling is applied, so you control cell width and any ANSI codes yourself. A bare String(day) in a wide renderCell can shift the column alignment of that row.
Week numbers
showWeekNumbers adds a 2-char week-number column at the start of each row. With weekStart: "monday" the number is the ISO 8601 week of the row's week-start date:
calendar({
year: 2026,
month: 9,
weekStart: "monday",
showWeekNumbers: true,
}); September 2026
Mon Tue Wed Thu Fri Sat Sun
36 1 2 3 4 5 6
37 7 8 9 10 11 12 13
38 14 15 16 17 18 19 20
39 21 22 23 24 25 26 27
40 28 29 30With weekStart: "sunday" it uses the convention where the week containing Jan 1 is week 1. Week numbers also render in framed themes (modern), where separator and frame lines get a week segment.
Plain text output
By default (color: false) the output contains no ANSI escape codes, so it's safe to pipe into files or other tools:
typescript-calendar-lib 2026 9 > september.txtColors are disabled automatically when stdout is not a TTY, so piping works without extra flags.
Exports
import {
calendar,
calendarRange,
calendarYear,
COLOR_SCHEMES,
resolveColorScheme,
resolveTheme,
THEMES,
} from "@typescript-calendar-lib/cli";
import type {
CalendarOptions,
CalendarRangeOptions,
CalendarYearOptions,
CliPalette,
CliTheme,
ColorSchemeName,
FrameChars,
RenderMonthOptions,
ThemeName,
} from "@typescript-calendar-lib/cli";License
MIT
