Getting Started
From zero to a working Gantt chart in 5 minutes. Choose your stack below.
Installation
Install from npm or load directly from a CDN.
npm
npm install nimbus-ganttyarn
yarn add nimbus-ganttCDN (UMD)
<script src="https://unpkg.com/nimbus-gantt@latest/dist/nimbus-gantt.umd.js"></script>
<link rel="stylesheet" href="https://unpkg.com/nimbus-gantt@latest/dist/nimbus-gantt.css">Data Format
Nimbus Gantt uses two core data types: GanttTask and GanttDependency.
GanttTask
interface GanttTask {
id: string;
name: string;
start: string; // ISO date: "2026-04-01"
end: string; // ISO date: "2026-04-15"
progress?: number; // 0-100
resource?: string; // assigned resource name
color?: string; // bar color override
milestone?: boolean; // renders as diamond
parent?: string; // task ID for hierarchy
collapsed?: boolean; // collapse children
}GanttDependency
interface GanttDependency {
from: string; // source task ID
to: string; // target task ID
type?: 'FS' | 'FF' | 'SS' | 'SF'; // default: 'FS'
lag?: number; // lag in working days
}Sample Data
const tasks = [
{ id: '1', name: 'Project Kickoff', start: '2026-04-01', end: '2026-04-01', milestone: true },
{ id: '2', name: 'Requirements', start: '2026-04-02', end: '2026-04-08', progress: 100, resource: 'Alice' },
{ id: '3', name: 'Design', start: '2026-04-09', end: '2026-04-15', progress: 60, resource: 'Bob' },
{ id: '4', name: 'Development', start: '2026-04-16', end: '2026-05-06', progress: 0, resource: 'Charlie' },
{ id: '5', name: 'Testing', start: '2026-05-07', end: '2026-05-14', progress: 0, resource: 'Alice' },
{ id: '6', name: 'Go Live', start: '2026-05-15', end: '2026-05-15', milestone: true },
];
const dependencies = [
{ from: '1', to: '2', type: 'FS' },
{ from: '2', to: '3', type: 'FS' },
{ from: '3', to: '4', type: 'FS' },
{ from: '4', to: '5', type: 'FS' },
{ from: '5', to: '6', type: 'FS' },
];Vanilla JavaScript
The simplest way to get started. Create a container element and initialize the Gantt chart.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/nimbus-gantt@latest/dist/nimbus-gantt.css">
</head>
<body>
<div id="gantt" style="width: 100%; height: 600px;"></div>
<script src="https://unpkg.com/nimbus-gantt@latest/dist/nimbus-gantt.umd.js"></script>
<script>
const gantt = new NimbusGantt('#gantt', {
tasks: [
{ id: '1', name: 'Design', start: '2026-04-01', end: '2026-04-10', progress: 80 },
{ id: '2', name: 'Development', start: '2026-04-11', end: '2026-04-25', progress: 20 },
{ id: '3', name: 'Testing', start: '2026-04-26', end: '2026-05-05', progress: 0 },
],
dependencies: [
{ from: '1', to: '2', type: 'FS' },
{ from: '2', to: '3', type: 'FS' },
],
});
// Listen for task changes
gantt.on('taskUpdate', (task) => {
console.log('Task updated:', task.name);
});
</script>
</body>
</html>React
Use the NimbusGanttChart React component for declarative rendering with hooks integration.
import { useState } from 'react';
import { NimbusGanttChart } from 'nimbus-gantt/react';
import { CriticalPath } from 'nimbus-gantt/plugins/critical-path';
import { UndoRedo } from 'nimbus-gantt/plugins/undo-redo';
import 'nimbus-gantt/dist/nimbus-gantt.css';
function ProjectTimeline() {
const [tasks, setTasks] = useState([
{ id: '1', name: 'Design', start: '2026-04-01', end: '2026-04-10', progress: 80 },
{ id: '2', name: 'Development', start: '2026-04-11', end: '2026-04-25', progress: 20 },
{ id: '3', name: 'Testing', start: '2026-04-26', end: '2026-05-05', progress: 0 },
]);
const dependencies = [
{ from: '1', to: '2', type: 'FS' },
{ from: '2', to: '3', type: 'FS' },
];
return (
<NimbusGanttChart
tasks={tasks}
dependencies={dependencies}
plugins={[CriticalPath, UndoRedo]}
height={600}
onTaskUpdate={(updated) => {
setTasks((prev) =>
prev.map((t) => (t.id === updated.id ? updated : t))
);
}}
onTaskClick={(task) => console.log('Clicked:', task.name)}
/>
);
}
export default ProjectTimeline;Salesforce LWC
Load Nimbus Gantt as a static resource and initialize it inside a Lightning Web Component using the loadScript pattern.
1. Upload the static resource
Download nimbus-gantt.umd.js and nimbus-gantt.css from the npm package or GitHub release. Upload both as static resources named NimbusGantt and NimbusGanttCSS.
2. Create the LWC component
// ganttTimeline.js
import { LightningElement, api } from 'lwc';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import GANTT_JS from '@salesforce/resourceUrl/NimbusGantt';
import GANTT_CSS from '@salesforce/resourceUrl/NimbusGanttCSS';
export default class GanttTimeline extends LightningElement {
@api tasks = [];
@api dependencies = [];
ganttInitialized = false;
ganttInstance;
async renderedCallback() {
if (this.ganttInitialized) return;
this.ganttInitialized = true;
try {
await Promise.all([
loadScript(this, GANTT_JS),
loadStyle(this, GANTT_CSS),
]);
const container = this.template.querySelector('.gantt-container');
// NimbusGantt is available on window after loadScript
this.ganttInstance = new window.NimbusGantt(container, {
tasks: this.tasks,
dependencies: this.dependencies,
});
this.ganttInstance.on('taskUpdate', (task) => {
this.dispatchEvent(
new CustomEvent('taskupdate', { detail: task })
);
});
} catch (error) {
console.error('Gantt init error:', error);
}
}
disconnectedCallback() {
if (this.ganttInstance) {
this.ganttInstance.destroy();
}
}
}3. Add the template
<!-- ganttTimeline.html -->
<template>
<div class="gantt-container" style="width: 100%; height: 600px;"></div>
</template>loadScript pattern is the standard way to load third-party libraries in LWC. The UMD build attaches NimbusGantt to the window object automatically.Registering Plugins
Plugins are passed as an array to the constructor (or React component props). They initialize automatically and attach to lifecycle hooks.
import { NimbusGantt } from 'nimbus-gantt';
import { CriticalPath } from 'nimbus-gantt/plugins/critical-path';
import { MonteCarlo } from 'nimbus-gantt/plugins/monte-carlo';
import { DarkTheme } from 'nimbus-gantt/plugins/dark-theme';
import { UndoRedo } from 'nimbus-gantt/plugins/undo-redo';
import { MiniMap } from 'nimbus-gantt/plugins/mini-map';
import { Export } from 'nimbus-gantt/plugins/export';
const gantt = new NimbusGantt('#gantt', {
tasks,
dependencies,
plugins: [
CriticalPath,
MonteCarlo,
DarkTheme,
UndoRedo,
MiniMap,
Export,
],
});
// Access plugin APIs after initialization
const criticalTasks = gantt.getPlugin('CriticalPath').getCriticalTasks();
const simulation = gantt.getPlugin('MonteCarlo').run({ iterations: 10000 });
console.log('P50 completion:', simulation.p50);
console.log('P90 completion:', simulation.p90);Plugin order does not matter
Plugins declare their own dependencies internally. Nimbus Gantt resolves initialization order automatically.
Plugins are tree-shakeable
Each plugin is a separate entry point. Unused plugins are excluded from your bundle by your build tool.
Next Steps
Browse Plugins
Explore all 27 plugins across 6 categories.
GitHub Repository
Source code, issues, and full API documentation.
Product Overview
Feature showcase, architecture, and design philosophy.
Delivery Hub
See Nimbus Gantt in action inside the Salesforce delivery platform.
Try the Live Demo
See all 5 visualization modes, sonification, and phone remote in action.