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

FieldTypeRequiredDescription
idstringYesUnique identifier within the chart
namestringYesLabel shown in the task list column
startTimestringYes, except on parent rowsTask start date, in inputDateFormat ('MM-DD-YYYY' by default). Optional in the TypeScript types since 3.20.0
endTimestringYes, except on milestonesTask 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
progressnumberNoCompletion percentage, 0-100
parentIdstringNoid of the parent task; creates a hierarchy. A parent row may omit its dates
dependencystring | { taskId, type, lag }NoThe 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