Mermaid Gantt chart editor
A Gantt chart puts work on a calendar: what runs when, what overlaps, and what cannot start until something else finishes. Reach for one when dates and dependencies are the point. If you only need order and not dates, a flowchart is lighter and will not rot the moment the schedule slips.
A release timeline with dependencies and a milestone
`after a1` is what makes this a Gantt chart rather than a picture of bars — the dependency is declared, so moving the first task moves everything downstream. The milestone marks a fixed date that does not consume time.
gantt
title Release 2.4
dateFormat YYYY-MM-DD
axisFormat %d %b
section Build
API contract :done, a1, 2026-01-06, 10d
Implementation :active, a2, after a1, 20d
Internal QA : a3, after a2, 8d
section Release
Staging soak : b1, after a3, 5d
Go/no-go review :milestone, m1, after b1, 0d
Production rollout :crit, b2, after m1, 3dWorked examples
1. The smallest valid chart
`dateFormat` tells Mermaid how to read the dates you write; `axisFormat` controls how they are displayed. They are different settings and confusing them is the most common Gantt frustration.
gantt
title Sprint 14
dateFormat YYYY-MM-DD
section Work
Build the thing :2026-03-02, 10d2. Task ids and dependencies
Giving a task an id lets later tasks say `after <id>`. Once dependencies are declared you can change a start date in one place and the rest of the chart follows.
gantt
title Data migration
dateFormat YYYY-MM-DD
section Preparation
Schema audit :a1, 2026-02-02, 5d
Write mappings :a2, after a1, 8d
section Execution
Dry run :a3, after a2, 3d
Cutover :a4, after a3, 1d3. Status keywords
`done`, `active` and `crit` change how a bar is drawn. They are the cheapest way to make a chart answer "where are we" rather than just "what is the plan".
gantt
title Q1 platform work
dateFormat YYYY-MM-DD
section Infrastructure
Terraform cleanup :done, t1, 2026-01-05, 12d
Kubernetes upgrade :active, t2, 2026-01-19, 15d
Cost review : t3, after t2, 5d
section Security
Dependency audit :crit, s1, 2026-01-12, 6d4. Milestones
A milestone is a point, not a span — give it `0d`. Use them for the dates that are fixed by something outside the project: a conference, a contract deadline, a freeze.
gantt
title Launch plan
dateFormat YYYY-MM-DD
section Engineering
Feature freeze :milestone, m1, 2026-04-01, 0d
Bug bash : e1, 2026-04-01, 5d
Release branch :milestone, m2, after e1, 0d
section Marketing
Press embargo lifts :milestone, m3, 2026-04-15, 0d5. Excluding weekends
`excludes weekends` stops durations counting Saturday and Sunday, so a 10-day task spans two working weeks instead of ending mid-weekend. This is usually the difference between a chart people trust and one they quietly ignore.
gantt
title Onboarding a new service
dateFormat YYYY-MM-DD
excludes weekends
section Setup
Provision infra :p1, 2026-05-04, 5d
Wire CI/CD :p2, after p1, 5d
section Handover
Runbook + training :p3, after p2, 4dGantt syntax reference
Gantt has the least forgiving grammar of the six types in one respect — the task line — and the most forgiving everywhere else, which is precisely why so many Gantt mistakes are silent.
| Syntax | Meaning |
|---|---|
| gantt | Opens the diagram. |
| title Text | Chart title. |
| dateFormat YYYY-MM-DD | How to PARSE the dates you write. |
| axisFormat %d %b | How to DISPLAY dates on the axis. Different setting from dateFormat. |
| excludes weekends | Skip Saturdays and Sundays when counting durations. |
| section Name | Groups tasks into a labelled row band. |
| Task name :id, 2026-01-01, 10d | Task with explicit start and duration. |
| Task name :id, after other, 10d | Task starting when `other` ends. |
| Task name :done, id, ... | Completed — drawn greyed out. |
| Task name :active, id, ... | In progress — drawn highlighted. |
| Task name :crit, id, ... | Critical — drawn in the accent colour. |
| Name :milestone, id, date, 0d | A point in time rather than a span. |
| 10d / 3w / 2h | Durations in days, weeks, hours. The unit is required. |
Six Gantt mistakes — and only one of them is an error
This is what makes Gantt charts different from the other diagram types here. Reproduced against Mermaid 11.12.2: exactly one of the six below stops the chart rendering. The other five produce a chart that looks perfectly plausible and is wrong, which is far more dangerous — nobody double-checks a diagram that drew successfully.
What you see
Parse error, ending in: Expecting 'taskData', got 'NL'
Why
A task line with no colon. The colon separates the task's display name from its data, and without it there is no data to parse. This is the only Gantt mistake in this list that Mermaid refuses outright.
Fix
Put a colon between the name and the id.
gantt
dateFormat YYYY-MM-DD
section Work
Design a1, 2026-01-01, 5dgantt
dateFormat YYYY-MM-DD
section Work
Design :a1, 2026-01-01, 5dWhat you see
The chart renders but the axis suddenly spans many months
Why
An `after` pointing at a task id that does not exist — usually a typo, or an id that got renamed. Mermaid does not warn; it places the task at an arbitrary point, which stretches the axis to cover it. Two ten-day tasks can end up on an eight-month axis.
Fix
Check that every `after <id>` matches a declared id exactly. A sudden change of axis scale is the tell.
gantt
dateFormat YYYY-MM-DD
section S
Design :a1, 2026-01-01, 10d
Build :a2, after design, 10dgantt
dateFormat YYYY-MM-DD
section S
Design :a1, 2026-01-01, 10d
Build :a2, after a1, 10dWhat you see
A task name is truncated at the first colon
Why
A colon inside the task name. The first colon is the separator, so everything after it is read as task data — `Phase 1: design` renders as a task called just `Phase 1`, and the word design vanishes.
Fix
Keep colons out of task names. Use a dash or put the detail in a section heading.
gantt
dateFormat YYYY-MM-DD
section S
Phase 1: design :a1, 2026-01-01, 10dgantt
dateFormat YYYY-MM-DD
section S
Phase 1 - design :a1, 2026-01-01, 10dWhat you see
A bar collapses to nothing
Why
A duration with no unit. `5` is not five days — the unit is required, and without it the task gets no meaningful length. The chart still draws, with a task that appears to take no time at all.
Fix
Always write the unit: `5d`, `3w`, `2h`.
gantt
dateFormat YYYY-MM-DD
section S
Design :a1, 2026-01-01, 5gantt
dateFormat YYYY-MM-DD
section S
Design :a1, 2026-01-01, 5dWhat you see
Dates land on the wrong day, silently
Why
A date that does not match the declared `dateFormat`. Writing `01/03/2026` under `dateFormat YYYY-MM-DD` does not fail — Mermaid salvages what it can and places the task on 3 January. If you meant 1 March, the chart is now wrong by two months and looks fine.
Fix
Write dates in exactly the format you declared. If you want day/month/year input, declare `dateFormat DD/MM/YYYY`.
gantt
dateFormat YYYY-MM-DD
section S
Design :a1, 01/03/2026, 10dgantt
dateFormat YYYY-MM-DD
section S
Design :a1, 2026-03-01, 10dWhat you see
Durations look right but finish dates are wrong in the real world
Why
No `excludes weekends`. By default a 10-day task means ten calendar days, weekends included, so anything longer than a working week finishes earlier on the chart than it will in practice.
Fix
Add `excludes weekends` near the top, unless the work genuinely runs seven days a week.
gantt
dateFormat YYYY-MM-DD
section S
Migration :a1, 2026-06-01, 10dgantt
dateFormat YYYY-MM-DD
excludes weekends
section S
Migration :a1, 2026-06-01, 10dRendering notes
Measured against Mermaid 11.12.2 as this site runs it. Gantt behaves unlike every other diagram type here.
Gantt is the only type with a fixed render width
Every other diagram on this site grows in whichever direction its content grows. A Gantt chart is always 1,264 pixels wide in its viewBox, whether it has three tasks or forty — only the height changes, from about 172 to 1,060 pixels. The axis is compressed or stretched to fit that fixed width, which is why a chart spanning two years and a chart spanning two weeks look equally dense. If your bars are unreadably thin, the problem is the date range, not the task count.
It used to be the worst hit by the PNG export bug
Because Mermaid emits `width="100%"` and no height, the browser resolved the export size against a default 300×150 box, and Gantt's wide-and-short aspect ratio made that as bad as it gets: a 1,280×148 chart exported as a 600×58 PNG. Export now reads the viewBox, so the same chart comes out at 2,560×296. Worth knowing if you have old exported Gantt PNGs lying around — they are not going to scale up.
PNG export is pixel-exact here
Gantt draws its labels as plain SVG text rather than embedded HTML, so unlike flowchart, class, state and ER diagrams it can be rasterised directly. The exported PNG matches the screen exactly, with no re-render and no typography shift.
The grammar is permissive almost everywhere except the colon
Missing sections, unknown status keywords, dates in the wrong format and durations without units all render. Only a task line without a colon is rejected. That asymmetry is the single most useful thing to know about writing Gantt charts: a chart that renders tells you almost nothing about whether it is correct.
Theme changes colour, never layout
Default and dark themes give an identical viewBox for the same source, so bar positions and the axis cannot shift when the theme changes.
When to use something else
If the dates are guesses, a Gantt chart will present them with a precision they have not earned, and someone will hold you to them. A flowchart showing order without dates is more honest and needs no maintenance when the schedule moves.
If the plan changes weekly, a text-based Gantt in version control is genuinely good — the diff shows what moved — but a chart nobody updates is worse than no chart. Be realistic about which one you are making.
And for anything involving resource levelling, capacity or per-person allocation, this is the wrong tool entirely. Mermaid draws bars on a calendar; it does not know who is doing the work or whether they are already busy.
Other diagram types
Written by Dominik Malsch · Last updated: