Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Data Display

Gantt

Data Display

Gantt React component for Tailwind CSS v4

FolderJSON Viewer
Live props
Content
title
locale
State
defaultZoom
loading
skeletonCount6
Appearance
tone
color
radius
showDependencies
showToday
showWeekends
Layout
rowHeight44px
listWidth320px
maxHeight520px
showList
toolbar
weekStartsOn-1
Behavior
editable
progressEditable
snap
responsive
Code
import { Gantt } from "@/components/ui/gantt"

<Gantt />
  1. Home
  2. Components
  3. Data Display
  4. Gantt
Pro

Gantt React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React Gantt chart: project tasks as bars you drag and resize, with progress, dependency arrows, milestones, groups and a phone task list.

Drag a bar to move it and drag its edges to resize it; it snaps to whole days (or weeks) on release, a pill above it shows the new dates and the original stays behind faded until you let go. Near the timeline's edge the view scrolls along. With progressEditable a small handle under the bar sets the progress. Click or tap a bar, or a name in the task list, for its details: dates, progress and Save, in a popover on a desktop and a bottom sheet on a phone. Arrows join dependent tasks and turn dashed red when a task starts before its predecessor ends. Chevrons fold groups; drag the task list's edge to widen it. The zoom switches between days, weeks and months and keeps the date in the middle in place; Today and Fit scroll for you. On touch, press and hold a bar to pick it up. Keyboard: Tab lands on one task; Up / Down, Page Up / Page Down, Home / End move between tasks; Enter opens the details; Alt+Left / Right moves a task by one snap step, Alt+Shift+Left / Right changes its end; Left / Right fold and unfold a group; t scrolls to today; Escape cancels a drag. Below 512px of width the chart becomes a list of tasks with mini bars.

Gantt is a Pro React component in the React data display components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add gantt, together with Avatar, Badge, Button, Date Picker, Empty State and 13 more and the npm packages date-fns, @tanstack/react-virtual, motion and lucide-react.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add gantt

Gantt is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import Gantt from @/components/ui/gantt.

import { useState } from "react"
import { Gantt, type GanttTask } from "@/components/ui/gantt"
// also exported: computeSummary(tasks) (span and weighted progress of every parent),
// findDependencyViolations(tasks) (tasks starting before a predecessor ends), topoSortTasks(tasks) (predecessors first)

const START: GanttTask[] = [
  { id: "analysis", name: "Analysis", start: new Date(2026, 8, 22), end: new Date(2026, 9, 3) },
  {
    id: "workshop",
    name: "Requirements workshop",
    parentId: "analysis",
    start: new Date(2026, 8, 22),
    end: new Date(2026, 8, 25),
    progress: 1,
    assignee: { name: "Liam Walker" },
  },
  {
    id: "specs",
    name: "Specifications",
    parentId: "analysis",
    start: new Date(2026, 8, 28),
    end: new Date(2026, 9, 3),
    progress: 0.4,
    dependencies: ["workshop"],
  },
  { id: "go-live", name: "Go-live", start: new Date(2026, 10, 3), end: new Date(2026, 10, 3), milestone: true, dependencies: ["specs"] },
]

export function ProjectPlan() {
  const [tasks, setTasks] = useState(START)
  return (
    <Gantt
      title="Acme CRM rollout"
      tasks={tasks}
      locale="en-US"
      onTaskChange={(task, change) =>
        setTasks((list) => list.map((t) => (t.id === task.id ? { ...t, ...change } : t)))
      }
      labels={{ fit: "Fit all", week: (n) => `Week ${n}` }}
    />
  )
}

Props

  • tasks*
    GanttTask[]

    { id, name, start, end (inclusive), progress? 0 to 1, parentId?, dependencies? (finish to start), milestone?, assignee? { name, avatar? }, tone?, color?, status? { label, tone? }, readOnly? }. Order is display order within each parent; a task with children is a group whose span and progress are computed.

  • titledefault ""
    ReactNode

    A heading at the start of the toolbar, like the project's name.

  • defaultZoomdefault "week"
    "day" | "week" | "month"

    Starting zoom while uncontrolled: day is 40px a day with day headers, week 20px a day with week numbers, month 6px a day with month names. Pair zoom with onZoomChange to control it.

  • zoom
    "day" | "week" | "month"

    The controlled zoom; the toolbar's segmented control and Fit call onZoomChange.

  • onZoomChange
    (zoom: GanttZoom) => void

    Fires when the zoom control, Fit or the API changes the zoom.

  • tonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    The default bar color; a task's own tone or color wins.

  • colordefault ""
    string

    Any CSS color for the bars; replaces the tone. Leave empty to use the tone.

  • radiusdefault "md"
    "none" | "sm" | "md" | "lg"

    Corner radius of the panel: 0 / 12 / 16 / 24px.

  • rowHeightdefault 44
    number

    Row height in px. Bars stay 28px tall and keep a 44px touch target.

  • listWidthdefault 320
    number

    Width of the task list in px (at least 200). People can drag its edge, or focus the edge and use the arrow keys. From 512 to 1023px the list keeps only the names, at most 220px (and 40% of the width).

  • maxHeightdefault 520
    number

    Height in px after which the body scrolls, with sticky headers and a sticky task list. 0 grows with the rows.

  • showListdefault true
    boolean

    The task list beside the timeline. Off, group bars carry their names.

  • toolbardefault true
    boolean

    The row with the title, the zoom, Today and Fit.

  • listColumnsdefault "["assignee", "start", "progress"]"
    ("assignee" | "start" | "end" | "duration" | "progress" | "status")[]

    Columns after the name, shown from 1024px of width.

  • editabledefault true
    boolean

    Bars move and resize by drag, by Alt+arrows and from the details. Off, the details only show the task.

  • progressEditabledefault false
    boolean

    A handle under each bar to drag its progress, in steps of 5%.

  • snapdefault "day"
    "day" | "week"

    What a drag, a resize and Alt+arrows snap to.

  • showDependenciesdefault true
    boolean

    Arrows from each predecessor's end to its task's start; dashed red when the task starts too early.

  • showTodaydefault true
    boolean

    Today's line across the timeline, its day in the header and the Today button.

  • showWeekendsdefault true
    boolean

    Shades the locale's weekend days in the day and week zooms.

  • loadingdefault false
    boolean

    Skeleton rows in place of the tasks.

  • skeletonCountdefault 6
    number

    How many skeleton rows show while loading.

  • responsivedefault true
    boolean

    Task details open in a bottom sheet below 768px instead of a popover.

  • localedefault ""
    string

    Dates, week numbers, month and weekday names, the first day of the week and the weekend. Empty follows the app.

  • onTaskChange
    (task: GanttTask, change: GanttTaskChange) => (void | false | Promise<unknown>)

    A move, a resize, a progress drag or a details save, with { start, end, progress? }. The bar keeps the new place optimistically; return false or reject to spring it back. Dependents are not shifted for you.

  • onTaskClick
    (task: GanttTask) => void

    Replaces the built-in details popover and sheet.

  • columnWidthdefault "{ day: 40, week: 20, month: 6 }"
    Partial<Record<GanttZoom, number>>

    Pixels per day for each zoom.

  • range
    { start: Date; end: Date }

    The visible dates; it grows to include every task. Default: the tasks' span plus 7 days on each side.

  • weekStartsOndefault -1
    0 | 1 | 2 | 3 | 4 | 5 | 6 | -1

    First day of a week column and of the date pickers: 0 Sunday, 1 Monday ... 6 Saturday; -1 follows the locale (Monday in en-GB, Sunday in en-US).

  • groupsExpanded
    string[]

    Controlled ids of the open groups; pair it with onGroupsExpandedChange.

  • defaultGroupsExpanded
    string[]

    Open groups while uncontrolled. Default: every group.

  • onGroupsExpandedChange
    (ids: string[]) => void

    Fires when a group folds or unfolds.

  • emptyState
    ReactNode

    Shown when there are no tasks. Default: an EmptyState with labels.empty ("No tasks yet").

  • now
    Date | number

    Where today's line sits. Default: the current time, updated every minute.

  • setApi
    (api: GanttApi) => void

    Receives { scrollToToday(), scrollToTask(id), setZoom(zoom), fit() } after mount.

  • toolbarActions
    ReactNode

    Extra buttons at the end of the toolbar.

  • labels
    Partial<GanttLabels>

    Every string, English by default (DEFAULT_GANTT_LABELS): task, assignee, start, end, date, duration(days, formatted), durationColumn, progress, status, today, fit, zoom, zoomDay, zoomWeek, zoomMonth, week(n), range(start, end), project(range), completed(percent), assignedTo(name), moved(task, range), resized(task, range), progressChanged(task, percent), violation(task, predecessor), failed(task), milestone, group(count, formatted), details, save, cancel, close, expand, collapse, resizeList, timeline, noAssignee, empty, emptyDescription, loading.

  • classNames
    Partial<Record<GanttSlot, string>>

    Extra classes for toolbar, title, body, listHeader, listRow, timelineHeader, grid, row, bar, barProgress, barLabel, milestone, summary, dependencies, today, details, mobile and mobileRow.

Parts

  • DEFAULT_GANTT_LABELS

    constant

    The English strings of the chart (column headers, zoom buttons, announcements, the details dialog). Spread it and override a few to translate. Type: GanttLabels.

  • computeSummary

    function

    The span and duration-weighted progress of every group task, computed from its children, the same numbers the chart draws. Use it for a project header or a report. Signature: (tasks: GanttTask[]) => Map<string, { start: Date; end: Date; progress: number }>.

  • findDependencyViolations

    function

    Lists the tasks that start on or before their predecessor's last day (finish to start), for a warning banner or a save check. Signature: (tasks: GanttTask[]) => GanttViolation[].

  • topoSortTasks

    function

    Orders tasks so every predecessor comes before the tasks that depend on it; a cycle keeps the remaining tasks in their original order. Signature: (tasks: GanttTask[]) => GanttTask[].

  • GanttTask

    type

    One row: id, name, start, end (inclusive), progress 0-1, parentId for groups, dependencies, milestone, assignee, tone or color, status and readOnly.

  • GanttTaskChange

    type

    { start: Date; end: Date; progress?: number }, what onTaskChange receives after a drag, a resize or a progress edit.

  • GanttApi

    type

    The handle setApi receives: scrollToToday(), scrollToTask(id), setZoom(zoom) and fit().

  • GanttViolation

    type

    { task: GanttTask; predecessor: GanttTask }, one broken finish-to-start dependency.

  • GanttLabels

    type

    The shape of DEFAULT_GANTT_LABELS, the type of the labels prop.

Examples

Month zoom

A six month marketing plan with groups, a milestone and brand tones.

Dependency violation

Client data import starts before Specifications ends: a dashed red arrow, a warning in the list and an announcement.

Editable progress

progressEditable adds a handle under each bar; progress snaps to 5%.

Read-only status view

editable={false} with status badges in the list, for reports.

200 tasks

Generated construction sites; rows virtualize above 150 visible tasks.

Phone

The list with mini bars and the details sheet, at 390px.

Dependencies

date-fns@tanstack/react-virtualmotionlucide-reactavatarbadgebuttondate-pickerempty-statepopoverprogresssegmented-controlslidertooltipuse-controllable-stateuse-localeuse-long-pressdate-utilsrelative-timemotiontonesui-config

Files

  • components/ui/gantt.tsx

FAQ

Is the React Gantt component free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Gantt?

Run npx wingo-ui@latest add gantt. It also adds the Wingo UI items it builds on (Avatar, Badge, Button, Date Picker, Empty State and 13 more) and the npm packages date-fns, @tanstack/react-virtual, motion and lucide-react. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/gantt.

How does Gantt behave on phones?

Task details open in a bottom sheet below 768px instead of a popover. The responsive prop controls this and is on by default.

See also

SchedulerCalendar ViewTimelineKanbanDate Picker

More React data display components

JSON ViewerLog ViewerMarkdownPresenceTagTree View
All 23 React data display components

Articles using this component

  • React Gantt Chart: Drag, Progress and Dependencies

    Component guides · Oct 19, 2026 · 10 min read

PreviousFolderNext JSON Viewer
Acme CRM rolloutConstruct Group · EIN 56-7891234
TaskStart%
September 2026
October 2026
November 2026
W3709/13
W3809/20
W3909/27
W4010/04
W4110/11
W4210/18
W4310/25
W4411/01
W4511/08
W4611/15
Analysis09/2260%
Requirements workshop09/22100%
Specifications09/2640%
Screen design09/2960%
Setup10/066%
Client data import10/060%
Invoicing integration10/0610%
Roles and permissions10/130%
Training10/200%
Admin session10/200%
Sales session10/210%
Go-live11/03
Post-launch support11/040%
Project: 09/22 to 11/14/202622%

last change: none · editable true · progressEditable false · snap day · responsive true