Installation
Theme
Mode

Data viz

Gantt

A planning surface, not just a picture. An editable task table is welded to a scrollable timeline of draggable bars — summary roll-ups, milestone diamonds, and finish-to-start dependency arrows you can draw and delete. Dates snap to whole days; every edit happens in place.

$npx shadcn@latest add @orbit/gantt

Overview

Live component — drag a bar along the timeline, pull its edges, click a name to rename, or drag a bar's end dot onto another row to link it. Click an arrow to remove the dependency, zoom the day columns, or hide table columns from the Columns menu.

Orbit · Q3 roadmap — controlled, with a callback readout
Orbit · Q3 roadmapJun 1Aug 2
Task
Who
Start
Days
Progress
Dependencies
Jun 1
12
SC
None
PN
None
SC
User int…Competit…
Synthesi…
Jun 13
20
AR
Kickoff …
AR
Wirefram…
JL
Hi-fi mo…
Design r…
Jul 4
26
MS
Design s…
DP
Design s…
SC
Frontend…Backend …
QA & pol…
✓ 100%
✓ 100%
70%
Kickoff approved
50%
15%
0%
Design sign-off
0%
0%
0%
Launch
DiscoveryDesignBuildMilestoneDrag bars to move · edges to resize · the end dots to link · click an arrow to remove
Change readout

Drag a bar, pull an edge, or draw a wire — callbacks land here.

Anatomy

Two halves, one grid: a fixed task table on the left and a horizontally-scrolling timeline on the right share the same 46px row height, so every task lines up with its bar no matter how far you scroll the dates. Weekends shade, months band the 58px header, and a primary rule marks today.

62%
Task bar
Spans its start→end days; the solid fill shows percent complete, the track the remainder. Drag to move, pull either edge to reschedule.
Summary roll-up
A slim bracket that spans a phase's child tasks — a quick read of where a whole workstream begins and ends.
Launch
Milestone
A zero-duration marker for a date that matters — a sign-off, a launch. Rendered as a diamond and draggable like any bar.

Interactions

Plan by direct manipulation — no dialogs. Dates snap to whole days as you drag; durations and names commit on Enter or blur.

Move a bar
Drag the body left or right; start and end shift together and snap to whole days.
Resize an edge
Grab the left or right edge to change just the start or the end — its duration in the table updates live.
Link a dependency
Hover or select a bar and drag one of its end dots onto another row to draw a finish-to-start arrow.
Edit in the table
Click a task name or its Days value to type a new one. Enter commits, Escape cancels.

Dependencies

An arrow runs from a predecessor's end into its successor's start. The arrows are live — they bend and follow as you drag either bar, so a slip downstream is obvious at a glance. Forward links elbow just before the successor; a link that has to run backwards routes along the row boundary, splitting cells instead of crossing bars — try dragging Retro writeup around.

Draw from an end dot · click a wire to delete it
Release 1.4Jun 1Jun 28
Task
Who
Start
Days
Progress
Dependencies
AR
None
MS
Design
SC
Build
PN
QA pass
80%
30%
0%
0%
01
Hover or select a bar — link dots appear just off both ends.
02
Drag from a dot; a dashed line tracks your cursor across the rows. The front dot picks a predecessor, the back dot a successor.
03
Release over another bar to link it. Click any arrow (or a table chip's ×) to remove the dependency.

Milestones

Reserve diamonds for dates whose slip changes the plan — sign-offs, launches, gates. They sit between phases, accept dependencies on both sides, and drag along the timeline like any bar.

Launch gatesJun 1Jun 24
Task
Who
Start
Days
Progress
Dependencies
JL
None
Design r…
MS
Design s…
Implemen…
✓ 100%
Design sign-off
40%
Launch

Props

PropTypeDefaultDescription
tasks / defaultTasksGanttTask[]Controlled / uncontrolled task rows, in display order. Tasks carry { id, name, kind?, color?, start, end, progress?, assignee?, dependencies? } — start/end are day indices from startDate (inclusive), dependencies list predecessor ids.
onTasksChange(tasks) => voidFires with the full next list on every edit — bar move/resize, rename, duration, start date, progress, dependency add/remove, and Add task.
onTaskMove(id, start, end) => voidFires when a bar drag/resize (or arrow-key move) commits, with the new day range.
onDependencyCreate(dep: GanttDependency) => voidA wire was drawn: { from: predecessorId, to: successorId }.
onDependencyRemove(dep: GanttDependency) => voidA wire (or table chip) was deleted.
onSelectTask(task) => voidA row or bar was selected (click, Enter or Space).
startDateDateJun 1 2026The date at day index 0.
totalDaysnumber63Timeline length in days.
todayDateDraws the today rule when inside the timeline. Omit to hide; pass a fixed date for deterministic demos.
defaultDayWidthnumber30Initial day-column width in px; the toolbar zoom steps it between 16 and 54.
titleReactNodeToolbar title, next to the auto-derived date range.
legendGanttLegendItem[]Footer phase swatches ({ label, color }). The footer — with the milestone key and interaction hint — renders only when set.
showToolbar / showAddTaskbooleantrueHide the toolbar row / just its Add task button.
createTask(tasks) => GanttTaskFactory for the Add task button — mint real ids here. Default appends a 5-day task after the last row.
editablebooleantruefalse renders read-only: no drag, resize, linking or cell editing.
…restHTMLAttributesForwarded to the root <div>, including ref and className.

Usage

A Gantt earns its keep when work has real sequence and duration. For a simple list of dated items with no dependencies, a calendar or table is lighter.

Do

Group work into phases

Summary rows give readers a scannable spine before they dive into individual tasks.

Don’t

Track hundreds of rows here

Past ~40 rows a Gantt becomes a wall. Filter to a team or phase, or switch to a table.

Do

Reserve milestones for decisions

Sign-offs, launches, gates — dates whose slip changes the plan. Not every deliverable.

Don’t

Encode status in bar color

Color maps to phase here. Use the progress fill — or a status badge in the table — for state.

Keyboard & accessibility

Bars are focusable with an arrow-key alternative to drag, and each committed move is announced via a polite live region. Table edits are plain inputs — Enter commits, Escape cancels — and Escape also backs out of a drag, a wire, or an open popover. Rows carry table semantics; bars are labelled with their task, dates and percent complete.

DragMove a bar; edges resize; end dots draw a dependency wire
← →Move the focused bar a day at a time
Shift + ← →Resize the focused bar's end a day at a time
Enter / SpaceSelect the focused bar
EnterCommit a name or duration edit
EscCancel an edit, drag, wire or popover