Skip to content
Connect an agent
Other diagram kinds

Gantt charts

A Gantt chart draws a plan on a time axis: tasks as bars, milestones as diamonds, and lines for what waits for what. Use it for a project plan, a roadmap, a release schedule, or any work where order and dates matter. It is for anyone, human or AI agent, who writes diagram source.

TL;DR

QuestionAnswer
What is it for?A schedule. One row for each task or milestone, in bands by section, on a time axis with two rows of labels, and a line from each task to the work that waits for it.
What is the first line?gantt "Launch plan" start=2026-01-05 unit=week today=2026-02-11 weekends=skip
How are dates written?As YYYY-MM-DD, always a calendar day. A length is 10d, 2w, or 1mo. There is no time of day.
Is today marked?Only when you write today=. A picture must be the same every time it is drawn, so Plotwork has no clock.
What are the limits?300 rows, 60 sections, 3660 days, and an axis no wider than 6000px. Past one, the source is refused with E140. More than 40 rows draws a warning.
How is it drawn?Bars carry their label inside when it fits and beside them when it does not. The colors come from the theme, in light and dark, and no color is ever written in the source.
Does Mermaid convert?Yes. A gantt chart becomes a Plotwork Gantt chart. See From Mermaid.

Ask your agent

text
Use Plotwork to draw a Gantt chart of a product launch plan. Research takes two weeks, then the product brief takes one week. Design and build run side by side after the brief. The web app waits for the visual design and the API, and it is the critical task. Add a milestone for the beta and one for the public launch. Skip weekends, and mark 11 February 2026 as today.
text
Use Plotwork to draw a two year roadmap in quarters, with Platform, Product, and Growth sections and a milestone for general availability.

Example

Product launch plan: 10 tasks and 2 milestones in 4 sections, from 2026-01-05 to 2026-04-14. A fourteen week plan from research to launch, with design and build running side by side.

The language

Like the other kinds, a Gantt chart has one statement on each line. Everything is key=value, labels are in double quotes, ids are words, and a line that starts with # is a comment.

The header

Plotwork
gantt "Launch plan" start=2026-01-05 unit=week today=2026-02-11 weekends=skip holidays=2026-04-03 desc="A fourteen week plan."
OptionValueMeaning
Title"Text" after ganttThe name of the chart. It is not painted. It is the accessible name of the picture.
start=A dateThe first day the axis must show. It can only widen the axis, never cut a task.
end=A dateThe last day the axis must show. It must not be before start= (E329).
unit=auto, day, week, month, quarter, yearThe step of the axis. The default is auto, which follows the span of the plan.
today=A dateDraws the today marker on that day. A day off the axis draws nothing and warns (W310).
weekends=show, shade, skipshow, the default, treats weekends like any other day. shade tints them. skip tints them and leaves them out when counting d and w lengths.
holidays=Dates, separated by commasDays off. They are tinted, and left out when counting lengths, whatever weekends= says. At most 400.
desc="Text"The plain-language description of the chart. desc "Text" on a line of its own does the same.

Sections

Plotwork
section "Design" tone=violet {  task ux "UX flows" start=2026-01-05 duration=2w}

A section is a band of rows with its name in a tab on the left. Close it with } on a line of its own. Sections do not nest (E330). tone= colors the band and the bars inside it, unless a bar chooses its own tone. Rows written outside every section go in a band with no tab. A chart that has both kinds of row warns (W314).

Tasks

Plotwork
task ui "Visual design" after=ux,api duration=3w status=active tone=violet
OptionValueMeaning
IdA wordRequired, and unique across tasks and milestones. Letters, digits, _ and -, starting with a letter or _.
Label"Text"Required.
start=A dateThe first day of the work. Use this or after=, never both (E324). One of them is required (E322).
after=Ids, separated by commasThe task starts the day after the last of these ends. A milestone counts as ending on its day. An id may be written further down the source.
duration=10d, 2w, 1moHow long the work lasts, the first day included. Use this or end=, never both (E324). One of them is required (E323).
end=A dateThe last day of the work, included. It must not be before the start (E326).
status=planned, active, done, criticalplanned is the default. critical can be added to one of the others: status=critical,done.
tone=A toneThe color family. A critical task is red unless it chooses a tone.

Milestones

Plotwork
milestone beta "Beta" after=web status=criticalmilestone ga "Launch" at=2026-03-02

A milestone is a point in time, drawn as a diamond with its label and its date. It takes at= (a day) or after= (it sits where the last of these ends), status= (planned, done, or critical), and tone=. A start=, a duration=, or an end= is an error (E327), because a milestone takes no time.

How dates work

RuleDetail
A date is a calendar dayIt is a day and never an instant, so no clock, time zone, or locale can change a picture. Years run from 1900 to 2200.
A task covers whole days, the first and the last includedstart=2026-01-05 duration=10d covers the 5th to the 14th. end=2026-01-14 says the same.
A task that follows another starts the next dayafter=a starts the day after the last day of a. With several ids, it follows the last to finish.
A milestone sits on the boundary of its dayA milestone after a task is drawn where the task's bar ends. Its date is the day after the last day of work.
d counts days, w counts seven days, mo counts calendar months1mo from 2026-01-31 ends on 2026-02-28. A length is never less than a day.
weekends=skip and holidays= count working days5d is five working days and 1w is five. A week of work that crosses a weekend is drawn across it. Months stay calendar months.
A task never starts on a day offWith days skipped, a task that follows another starts on the next working day. A written start= on a day off moves the same way and warns (W311). A milestone with at= stays where you put it.
Dependencies are checkedA name that is not a task is E131, with the nearest id in the hint. A circle is E325, reported once with the ids around it.

A longer plan

A plan of several years reads better in quarters. This one sets start= and end= so the axis shows both years, uses at= for a milestone with a fixed day, and gives each section its own tone.

Two year roadmap: 7 tasks and 1 milestone in 3 sections, from 2026-01-12 to 2027-08-11. A roadmap drawn in quarters.

What is drawn

PartHow
AxisTwo rows above the bands. The upper row names months (over days and weeks) or years (over months and quarters), and the lower row holds day numbers, week starts, months, quarters, or years. A label that does not fit its cell is left out.
BandsA tinted band for each section, with its name in a tab on the left. A long name wraps onto up to three lines and is cut with an ellipsis past the widest tab (W203).
RowsOne row for each task or milestone, in the order written. The order you write is the order a reader sees.
Planned workA tinted bar with a tone outline.
Work in progressA solid bar in the tone, with its label in the surface color.
Finished workA card with a check mark and a quiet label.
Critical workRed, unless the task chooses a tone.
LabelsInside the bar when they fit, and to the right of it when they do not, with the picture widened to make room. A label past 360px is cut and warns (W203).
MilestonesA diamond, hollow until it is done, then the label and the date in short form, such as Mar 2.
DependenciesOne rounded line with an arrowhead, from the earlier bar to the start of the later one, drawn under the bars.
TodayA pill named Today above the first band and a thin line from it through every band.
Days offWeekends, when shaded or skipped, and holidays are tinted in the bands. Nothing is tinted when a day is narrower than 5px.

Limits and warnings

LimitValueOver it
Tasks and milestones300E140 before any layout, with a hint to split by phase or team
Sections60E140
Span of the plan3660 daysE140
Width of the axis6000px at the step asked forE140, with the coarser steps in the hint
Days off400E140
Tasks and milestones, for a warning40W200
Width of the pictureAbout 1100pxW202

A chart of 300 rows is read, laid out, and drawn in about 100ms, and a chart of twenty rows takes a few milliseconds.

CodeWhen it firesFix
E320A date that is not a real YYYY-MM-DD day, or is outside 1900 to 2200.Write a real day, such as 2026-03-02.
E321A length that is not a whole number and a unit. 10, 0d, 1y, 2M, and hours are the usual causes.Write 10d, 2w, or 1mo. The hint names the right form.
E322A task or milestone with no start=, at=, or after=.Say when it starts.
E323A task with no duration= or end=.Say how long it lasts or when it ends.
E324Options that cannot be used together: start= and after=, duration= and end=, at= and after=, or two progress words.Keep one of the pair.
E325A circle of dependencies. The message names the ids around it.Remove one after= in the circle.
E326A task that ends before it starts. The hint gives the day it starts on.Move end= or start=.
E327A milestone with a start=, duration=, or end=.Use at= or after=.
E328A chart with no tasks or milestones.Add a task.
E329An end= before the start= of the header.Swap or correct the two.
E330A section inside a section.Close the first section before the second.
E131A name in after= that is not a task or milestone.Fix the id. The hint names the nearest one.
E140The chart is over a hard limit.Split the plan by phase or team.
W310today= is off the axis, so no marker is drawn.Move today= or widen the axis with start= and end=.
W311A written start= fell on a day off and moved to the next working day.Write the working day, or accept the move.
W312A task ended before today and is not done.Mark it done, or move the dates.
W313A task is marked done and starts after today.Check the status or today=.
W314Rows outside a section next to rows inside one.Put every row in a section, or none.
W200More than 40 rows.Split the plan.
W202The picture is wider than about 1100px.Use a coarser unit=, or shorten labels.
W203Text was cut with an ellipsis.Shorten the label or the section name.

The shared syntax codes also apply: E100, E101, E110, E121, E130, E133, E134, E135, and E136 cover syntax, an unterminated string, an unknown statement or tone, a repeated id, an unclosed block, an unknown option, and a bad value.

From Mermaid

The gantt type of Mermaid is read by convert_mermaid and by sync_markdown with convertMermaid. The converter first reads the settings that apply to the whole chart, so every date is read in its dateFormat, then reads the sections and tasks in order. It works out each task's dates the way Mermaid does before it writes anything.

This chart has a week-long task, and excludes weekends:

Mermaid
gantt  title Website refresh  dateFormat YYYY-MM-DD  excludes weekends  section Build  Design :done, design, 2026-03-02, 2w  Build :active, build, after design, 10d  Ship :crit, ship, after build, 3d  Live :milestone, live, after ship, 0d

It converts to this Plotwork. The two weeks became fourteen working days, because Mermaid counts a week as seven working days when weekends are excluded, and the converter reports that (M235):

Plotwork
gantt "Website refresh" weekends=skip
section "Build" {  task design "Design" start=2026-03-02 duration=14d status=done  task build "Build" after=design duration=10d status=active  task ship "Ship" after=build duration=3d status=critical  milestone live "Live" after=ship}

What is kept

MermaidPlotwork
title, front matter title:, accTitle, accDescrThe title and desc=. A title line wins over the front matter.
dateFormat with a year, a month, and a day in numbers (YYYY, YY, MM, M, DD, D, X, x)Read, and written as YYYY-MM-DD.
section Namesection "Name" { and }.
Task :tags, id, start, endA task. The three shapes Mermaid reads are kept: end only, start and end, and id with start and end.
after a b cafter=a,b,c
A length such as 3d or 2wduration=3d or duration=2w
1M, 1yduration=1mo, duration=12mo
An end dateend= on the day before it, because Mermaid leaves the end day out. With inclusiveEndDates it is the same day.
milestone tagA milestone
done, active, critstatus=done, status=active, status=critical, which combine
excludes weekends, or Saturday and Sundayweekends=skip
excludes 2024-03-29holidays=2024-03-29
tickInterval 1day, 1week, 1monthunit=day, unit=week, unit=month
A task with no idAn id made from its name

What changes or is dropped

MermaidWhat happensCode
A task with no startIt follows the task before it (after=). When that is a milestone, the day the milestone sits on is written as start=. A first task with no start stops the conversion.M131
A length with a fraction, 0d on a task, or hours, minutes, or secondsRounded to whole days, and at least one. A week with weekends excluded is written in days.M235
until idend= on the day before that task starts. The task no longer moves with the other one.M237
A milestone with a lengthA milestone on the middle day of that length, or after= for a length of zero.M234
vertDropped, and the task kept.M236
excludes another weekday, or includesDropped.M231
A tickInterval that is not a day, a week, or a monthDropped.M232
axisFormatDropped. Plotwork writes its own labels.M230
todayMarker with a styleDropped. Plotwork has no clock, so write today= on the header.M233
topAxis, weekday, weekend, displayModeDropped. Plotwork chooses the layout.M238
clickDropped.M201
%%{init}%% and front matter config:Dropped.M200
HTML and line breaks in a nameTurned into plain text.M205
An id that is not valid, such as 1stRenamed.M206
An empty sectionDropped.M216

What stops the conversion

MermaidWhyCode
A dateFormat with a time of day, or hours and minutes in the lengthsPlotwork schedules in whole days.M130
A task after an id that is not in the chart, or a circleIts dates cannot be worked out.M131
A dateFormat with a month name, a weekday, or no yearThe dates cannot be read.M132
More than 300 tasksOver the limit.M102
A line that is not a task, or a date not in the dateFormatThe line cannot be read.M110

With lenient set, the converter skips an unreadable line, or a task that cannot be placed and the tasks that depend on it, and reports it (M218).

See also

DocWhy
Writing diagramsThe language for flow, sequence, and schema diagrams, and the options every kind shares
Examples to copyFinished diagrams with the prompt that gets an agent to write each one
Migrating from MermaidHow every Mermaid type converts, and what the diagnostic codes mean
Git graphsBranches, commits, merges, and tags
Class diagramsClasses, members, and the relations between them
State diagramsStates, transitions, and regions
TimelinesEvents in time order
User journeysTasks scored by how a person feels
Mind mapsA topic and its branches
Language referenceEvery word of the language, one page for each topic
Diagram kindsEvery kind, its header, and what it draws