Installation & Usage
ApexGantt is a JavaScript Gantt chart library. It renders interactive project timelines with tasks, subtasks, dependencies, progress tracking, and drag-and-drop scheduling.
Installation
npm
npm install apexgantt
import ApexGantt from 'apexgantt'
CDN
<script src="https://cdn.jsdelivr.net/npm/apexgantt"></script>
When loaded via CDN, ApexGantt is available as a global variable. Since 3.20.0, window.ApexGantt also carries every runtime export of the package (ColumnKey, ColumnList, GanttEvents, TaskType, Orientation, DataParser, DEFAULT_GANTT_MESSAGES, LightTheme, DarkTheme, getTheme, renderers and escapeHtml), so script-tag pages can read them as ApexGantt.ColumnKey and so on. Before 3.20.0 only ColumnKey, ColumnList, renderers and escapeHtml were attached.
License
ApexGantt is included in the Premium plan and above, and there is no free tier. Without a valid key the chart renders with a trial watermark. Set your license key once at application start:
import ApexGantt from 'apexgantt'
ApexGantt.setLicense('YOUR-LICENSE-KEY')
Calling it before the first new ApexGantt(...) avoids a one-frame watermark; since 3.17.0 a later call also removes the watermark from charts already on the page. From 3.20.0 the key's plan must be Premium or higher. The key is validated client-side; no network request is made. See Setting the License for purchase and environment variable patterns.
Creating your first chart
Provide a container element and a configuration object. Each task needs an id and a name, and a bar needs startTime and endTime.
<div id="gantt" style="height: 400px;"></div>
import ApexGantt from 'apexgantt'
ApexGantt.setLicense('YOUR-LICENSE-KEY')
const gantt = new ApexGantt(document.getElementById('gantt'), {
inputDateFormat: 'YYYY-MM-DD', // the dates below are ISO; the default is 'MM-DD-YYYY'
series: [
{
id: 'phase-1',
name: 'Phase 1: Research',
startTime: '2024-03-01',
endTime: '2024-03-15',
progress: 100,
},
{
id: 'task-1',
name: 'User interviews',
startTime: '2024-03-01',
endTime: '2024-03-08',
parentId: 'phase-1',
progress: 100,
},
{
id: 'task-2',
name: 'Competitive analysis',
startTime: '2024-03-06',
endTime: '2024-03-14',
parentId: 'phase-1',
progress: 80,
},
{
id: 'phase-2',
name: 'Phase 2: Design',
startTime: '2024-03-15',
endTime: '2024-04-05',
progress: 40,
},
{
id: 'task-3',
name: 'Wireframes',
startTime: '2024-03-15',
endTime: '2024-03-25',
parentId: 'phase-2',
progress: 90,
},
{
id: 'task-4',
name: 'Visual design',
startTime: '2024-03-22',
endTime: '2024-04-05',
parentId: 'phase-2',
progress: 10,
},
],
})
gantt.render()
This renders a two-level hierarchy: two summary rows (Phase 1 and Phase 2) each containing subtasks. The parentId field links a task to its parent by id. A parent draws a summary bar that spans its children, so its own dates are not used for the bar.
Rows are sorted by start date by default, so the task list does not always follow your array order. Pass sortBy: [] to keep the array order.
The chart is 500px tall unless you set height. Since 3.20.0, when height is not set and the container already has a height of its own (like the 400px above), the chart fills the container and follows its size. Before 3.20.0 the 500px default applied regardless, so set height to match the container.
Task fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier within the chart |
name | string | Yes | Label shown in the task list column |
startTime | string | Yes, except on parent rows | Task start date, in inputDateFormat ('MM-DD-YYYY' by default). Optional in the TypeScript types since 3.20.0 |
endTime | string | Yes, except on milestones | Task end date, inclusive at day resolution |
type | 'task' | 'milestone' | No | 'milestone' draws a diamond at startTime and needs no endTime. Since 3.20.0 the types accept the plain string 'milestone' as well as TaskType.Milestone |
progress | number | No | Completion percentage, 0-100 |
parentId | string | No | id of the parent task; creates a hierarchy. A parent row may omit its dates |
dependency | string | { taskId, type, lag } | No | The one predecessor this task depends on. Add more with gantt.addDependency() |
Since 3.20.0 a task with no endTime and no type renders as a milestone at startTime. An explicit type: 'task' with no endTime still throws. Before 3.20.0 any task without endTime threw unless it had type: 'milestone'.
Date format
Dates are parsed with inputDateFormat, using dayjs tokens. The default is 'MM-DD-YYYY'. Set it to match your data:
const gantt = new ApexGantt(el, {
inputDateFormat: 'YYYY-MM-DD',
series: [...],
})
ISO dates under the default format still draw, because parsing falls back to a lenient read, but the edit dialog shows empty date fields and edited or dragged dates are written back as MM-DD-YYYY.
To enable sub-day scheduling, include time tokens:
inputDateFormat: 'YYYY-MM-DD HH:mm'
Rendering and cleanup
render() paints synchronously and returns the chart's root element:
const root = gantt.render()
Call destroy() when you remove the chart from the DOM, such as when a framework component unmounts:
gantt.destroy()
Inside a shadow root
From 3.19.0, ApexGantt works inside a shadow root, such as a custom element or a Lit component: its styles, dropdowns and keyboard focus stay inside the root it renders in. Create it on an element inside the root and call destroy() when the element leaves the page.
Next steps
- Creating a Basic Gantt Chart for a deeper walkthrough
- Options reference for all configuration options
- Methods reference for programmatic control (add/remove tasks, undo/redo, zoom)
- React, Vue, Angular integration guides