Skip to content
MoltenshipPublic

Latest commit

 

History

197 Commits

Folders and files

Repository files navigation

Moltenship Time

A React 19 calendar built on the Temporal API. Time handles dates, time zones, navigation, calendar state, fast event lookups, and saving changes. Your events stay in the shape your app already uses. Week, day, month, year, and agenda views come as shadcn/ui-style source that you copy into your app and own.

Documentation · Live demo

Status: release candidate. The packages are on npm as a release candidate for 1.0.0. The API can still change before 1.0.0 if the release candidate turns up problems.

Install

pnpm add @moltenship/calendar react react-dom

You need React 19, a runtime with Temporal (Node.js 26+; a polyfill in browsers without it), and TypeScript 6+ with "lib": ["ESNext"].

Example

The smallest calendar, with a hand-written view. The Quick start uses the built-in views instead.

import {
  createCalendar,
  defineCalendarView,
  defineEventAdapter,
  plainDateInterval,
} from "@moltenship/calendar";

interface Meeting {
  id: string;
  title: string;
  start: Temporal.Instant;
  end: Temporal.Instant;
}

const eventAdapter = defineEventAdapter<Meeting>()({
  getId: (meeting) => meeting.id,
  getTitle: (meeting) => meeting.title,
  getInterval: (meeting) => ({ kind: "timed", start: meeting.start, end: meeting.end }),
  getResourceIds: () => [],
});

// A minimal view: the meetings on the visible day.
const dayView = defineCalendarView({
  name: "day",
  strategy: {
    getRange: (date) => plainDateInterval(date, date.add({ days: 1 })),
    navigate: (date, delta) => date.add({ days: delta }),
    getTitle: (range, { locale }) => range.start.toLocaleString(locale, { dateStyle: "full" }),
    project: ({ snapshot, instantRange }) => snapshot.queryTimed(instantRange),
  },
  Renderer: ({ projection }) => (
    <ul>
      {projection.map((meeting) => (
        <li key={meeting.id}>{meeting.title}</li>
      ))}
    </ul>
  ),
});

const Calendar = createCalendar<Meeting>()({ eventAdapter, views: [dayView] });

export function MeetingCalendar({ meetings }: { meetings: readonly Meeting[] }) {
  return (
    <Calendar.Root
      events={meetings}
      defaultAnchorDate={Temporal.PlainDate.from("2026-10-08")}
      defaultTimeZone="Europe/Berlin"
      locale="en-US"
      weekRules={{ firstDay: 1, minimalDays: 4, weekend: [6, 7] }}
    >
      <Calendar.PreviousTrigger>Previous</Calendar.PreviousTrigger>
      <Calendar.Title />
      <Calendar.NextTrigger>Next</Calendar.NextTrigger>
      <Calendar.ActiveView />
    </Calendar.Root>
  );
}

Documentation

Read the docs at time.molten.sh. Good places to start:

The live demo is a Google Calendar-style app built from the same views. Its source is in apps/demo.

To work on the docs, run vp run dev and edit the MDX in apps/showcase/content/docs. Start the demo with vp run demo#dev.

Contributing

The repository uses the Vite+ toolchain (vp) and Node.js 26.

vp install         # install dependencies
vp check           # format, lint, and type-check
vp test            # run the tests
vp run ready       # everything CI runs
vp run ready:full  # the release gate

License

MIT. @moltenship/ics also bundles Unicode CLDR data under the Unicode License v3, so it's MIT AND Unicode-3.0; see its THIRD-PARTY-NOTICES.md.

Releases

Packages

Contributors

Languages