Install the schedule with its two peers and hand it plain data: lanes, tasks, subtasks and dependencies. It draws them and reports what a planner wants to change.
import { useSchedule } from "@umriss-ui/schedule";
npm install @umriss-ui/schedule @umriss-ui/core @umriss-ui/charts
The command brings its two peers along: core for the formats and the wording, charts for the time scale and the operating calendar (ADR-0022). React 19 or newer is a peer as well and stays the application's own. The stylesheets load themselves - each package's script imports its own, so there is nothing to import by hand; @umriss-ui/schedule/styles.css stays exported for setups that link stylesheets themselves.
The plan is plain data (ADR-0023). A lane is a person, a vehicle or a room, declared in JSX by its id. A task is an id, a colour and a name; a subtask is a main time on one lane, belonging to a task, with an optional lead-in and lead-out; a dependency joins two subtasks of one task with a lag. Times are epoch milliseconds.
The schedule reports, the application decides. It draws the data it is given and changes none of it: a drag ends in an intent reported to onIntent, and only the application's own state update moves a bar. Without intents the schedule is read-only - see Move and lane.
Two people, one project, one dependency: lanes in JSX, the rest as plain arrays handed to Subtasks and Dependencies.
import { useSchedule } from "@umriss-ui/schedule";
import type { Dependency, Subtask, Task } from "@umriss-ui/schedule";
const at = (hours: number, minutes = 0) => new Date(2026, 2, 17, hours, minutes).getTime();
const min = (n: number) => n * 60_000;
const tasks: Task[] = [{ id: "portal", name: "Member portal", color: "light-dark(#7c3aed, #a98bfa)" }];
const subtasks: Subtask[] = [
{ id: "design", task: "portal", lane: "noah", from: at(9), to: at(11), leadOut: min(15) },
{ id: "build", task: "portal", lane: "arjun", from: at(12), to: at(15, 30), leadIn: min(30) },
];
const dependencies: Dependency[] = [{ id: "handover", from: "design", to: "build", lag: min(15) }];
export default function SmallestSchedule() {
const { Schedule, Lane, Subtasks, Dependencies } = useSchedule({ initialView: { domain: [at(8), at(16)] } });
return (
<Schedule ariaLabel="Tuesday, design and build" height={150}>
<Lane id="noah" label="Noah Fischer" />
<Lane id="arjun" label="Arjun Mehta" />
<Dependencies data={dependencies} />
<Subtasks data={subtasks} tasks={tasks} />
</Schedule>
);
}
The keys of First schedule apply here.
From ScheduleProps — the full table stands on First schedule.
| Name | Type | Default | Description |
|---|---|---|---|
height | number | 400 | Height in CSS pixels, both bands included. The width is the host's. |
children | ReactNode | — | Lane, Dependencies and Subtasks, in the order they are to stand and
be drawn. |
| Name | Type | Default | Description |
|---|---|---|---|
ariaLabelrequired | string | — | What the schedule shows, for a screen reader: "Plan of week 38". |
From LaneProps — the full table stands on Lanes.
From SubtasksProps — the full table stands on Subtasks.
From Subtask — the full table stands on Subtasks.
| Name | Type | Default | Description |
|---|---|---|---|
idrequired | string | — | The caller's identity of the subtask. |
taskrequired | string | — | The id of the task it belongs to. |
lanerequired | string | — | The id of the lane it sits on. |
fromrequired | number | — | Start of the main time. |
torequired | number | — | End of the main time. |
leadIn | number | — | Duration of the lead-in before the main time; none is zero. |
leadOut | number | — | Duration of the lead-out after the main time; none is zero. |
From Task — the full table stands on Subtasks.
From DependenciesProps — the full table stands on Dependencies.
| Name | Type | Default | Description |
|---|---|---|---|
datarequired | readonly Dependency[] | — | The dependencies, as the caller holds them. |
From Dependency — the full table stands on Dependencies.
| Name | Type | Default | Description |
|---|---|---|---|
idrequired | string | — | The caller's identity of the dependency. |
fromrequired | string | — | The id of the subtask it leaves. |
torequired | string | — | The id of the subtask it arrives at. |
lagrequired | number | — | The least time between the two anchors; zero where the successor may begin as soon as the predecessor ends. |
From ScheduleOptions — the full table stands on View.
| Name | Type | Default | Description |
|---|---|---|---|
initialView | ScheduleView | — | The view to start from, read once when the hook first runs; a different
value on a later render is ignored, as React ignores a changed
defaultValue. To go to a view later, call setView. The schedule
remembers none: where a view is kept is the application's decision. |