Moltenship Time

Introduction

A React 19 calendar built on the Temporal API, with views you copy and own.

Moltenship Time handles the hard parts of a calendar: dates, time zones, navigation, calendar state, fast event lookups, and saving changes. Your events stay in the shape your app already uses, and Time reads them through a small adapter. The week, day, month, and agenda views are source files you copy into your app, so you can change how they look and behave.

Live, in your time zone. Drag to move, resize or create events.

To see every view with more data, try the live demo, a Google Calendar-style app built from the same views.

Pre-1.0

Time is in active development and not published to npm yet. Everything on these pages works today, but expect breaking changes before 1.0.

What it looks like

This is the render part of the Quick start. Calendar comes from createCalendar, and meetings is a plain array of your own records.

calendar.tsx
const viewLabels = { week: "Week", day: "Day", month: "Month", agenda: "Agenda" };
const viewSwitcherOptions = Calendar.views.map(({ name }) => ({
  value: name,
  label: viewLabels[name],
}));

function CalendarViewSwitcher() {
  const view = Calendar.useCalendarSelector((state) => state.view);
  const { setView } = Calendar.useCalendarActions();
  return <ViewSwitcher value={view} onValueChange={setView} options={viewSwitcherOptions} />;
}

export const weekRules = { firstDay: 1, minimalDays: 4, weekend: [6, 7] } as const;

export function TeamCalendar({ meetings }: { readonly meetings: readonly Meeting[] }) {
  return (
    <Calendar.Root
      events={meetings}
      defaultAnchorDate={Temporal.PlainDate.from("2026-10-08")}
      defaultTimeZone="Europe/Berlin"
      locale="en-US"
      weekRules={weekRules}
    >
      <Calendar.Frame className="flex h-[640px] flex-col rounded-xl border">
        <CalendarToolbar calendar={Calendar}>
          <CalendarViewSwitcher />
        </CalendarToolbar>
        <Calendar.Viewport className="min-h-0 flex-1">
          <Calendar.ActiveView />
        </Calendar.Viewport>
      </Calendar.Frame>
    </Calendar.Root>
  );
}

Who it's for

Time is for React developers building scheduling screens (bookings, rooms, shifts, team calendars) who want to:

  • keep their existing event data and API,
  • style the calendar with their own design system, or start from shadcn/ui,
  • get time zones and daylight saving time right without writing that math themselves.

What you get today

  • Built-in views. Week, day, month, and agenda, in the style of Google Calendar, built on shadcn/ui and Tailwind CSS. A theme with calendar tokens and an event color palette comes with them.
  • Your data, read through an adapter. You describe how to read an ID, title, and time range from your records. TypeScript keeps your record and ID types all the way through.
  • Three kinds of time. Timed events use Temporal.Instant, all-day events use Temporal.PlainDate, and floating events use Temporal.PlainDateTime. No Date objects.
  • Time zone and DST handling. Days that are 23 or 25 hours long and skipped or repeated hours are handled for you.
  • Editing. Moves, resizes, creates, and deletes arrive as changes for you to save. They show as pending while they save, roll back if saving fails, and pass through policies you choose. See Interactions. The built-in views support dragging, resizing, and creating events with the mouse, a pen, or touch.
  • Controlled or uncontrolled state. The visible date, view, time zone, selection, and focus can each be owned by the calendar or by your app.
  • Headless parts. Root, previous/next/today buttons, Title, and ActiveView render plain elements, and custom views are a strategy plus a component.
  • Server rendering. During server rendering, Time doesn't read the clock, the host time zone, or window, so the server and the browser render the same markup from the same props.
Edit on GitHub

Last updated on

On this page