Lightweight Gantt chart for RevoGrid.
@revolist/gantt turns a regular RevoGrid data grid into a lightweight Gantt timeline. It renders task rows, date columns, a two-level timeline header, task bars, progress fills, milestone markers, and finish-to-start dependency lines while keeping the data model close to larger scheduling systems.
The package is designed for teams that want a fast, embeddable, grid-native Gantt chart without bringing in a full project management engine. It is a good fit for project timelines, delivery plans, roadmap views, implementation schedules, release tracking, and simple task dependency visualization.
Use @revolist/gantt when you need a lightweight JavaScript Gantt chart or TypeScript Gantt chart that behaves like a data grid. Common use cases include:
Need full project scheduling, resource planning, calendars, baselines, critical path, advanced dependencies, import/export, and Scheduler features? Those capabilities are available in the RevoGrid Pro Gantt version.
Most JavaScript Gantt chart libraries are built as standalone widgets. @revolist/gantt takes a different approach: it is a RevoGrid plugin. That means the task table and the timeline live inside the same high-performance grid surface.
This gives you:
@revolist/revogrid-column-date.progressPercent.RevoGrid Gantt is fully virtualized through RevoGrid's row and column rendering engine. Task rows, pinned task columns, and the timeline column stay inside the same high-performance grid surface, so large project plans can scroll smoothly without rendering the entire dataset at once.
@revolist/gantt follows the same framework model as RevoGrid: the core grid is a Web Component, with wrappers and setup guides for major frontend frameworks. Use the Gantt plugin with the RevoGrid integration that matches your app:
This package intentionally focuses on rendering, not scheduling. It shows project work on a timeline and keeps the implementation small enough to embed, test, and extend.
Included:
grid.source.Not included yet:
pnpm add @revolist/gantt @revolist/revogrid @revolist/revogrid-column-date
npm install @revolist/gantt @revolist/revogrid @revolist/revogrid-column-date
Import the plugin and stylesheet:
import { defineCustomElements } from '@revolist/revogrid/loader';
import { GanttPlugin } from '@revolist/gantt';
import '@revolist/gantt/dist/gantt.css';
defineCustomElements();
<revo-grid id="project-grid"></revo-grid>
import { GanttPlugin, type DependencyEntity, type TaskEntity } from '@revolist/gantt';
const tasks: TaskEntity[] = [
{
id: 'task-1',
parentId: null,
name: 'Design API',
type: 'task',
startDate: '2026-05-04',
endDate: '2026-05-08',
progressPercent: 60,
},
{
id: 'task-2',
parentId: null,
name: 'Build timeline',
type: 'task',
startDate: '2026-05-11',
endDate: '2026-05-20',
progressPercent: 25,
},
{
id: 'task-3',
parentId: null,
name: 'Release',
type: 'milestone',
startDate: '2026-05-22',
endDate: '2026-05-22',
progressPercent: 0,
},
];
const dependencies: DependencyEntity[] = [
{
id: 'dependency-1',
predecessorTaskId: 'task-1',
successorTaskId: 'task-2',
type: 'finish-to-start',
},
{
id: 'dependency-2',
predecessorTaskId: 'task-2',
successorTaskId: 'task-3',
type: 'finish-to-start',
},
];
const grid = document.querySelector<HTMLRevoGridElement>('#project-grid')!;
grid.source = tasks;
grid.gantt = {
id: 'project-plan',
name: 'Project Plan',
version: '1',
timeZone: 'UTC',
updatedAt: new Date().toISOString(),
zoomPreset: 'day-week',
visuals: {
showDependencies: true,
showTaskLabels: true,
},
};
grid.ganttDependencies = dependencies;
grid.plugins = [GanttPlugin];
Tasks are supplied through grid.source. The plugin does not require a separate task store and does not mutate the original task objects.
export interface TaskEntity {
readonly id: string;
readonly parentId: string | null;
readonly name: string;
readonly type: 'summary' | 'task' | 'milestone';
readonly startDate: string;
readonly endDate: string;
readonly progressPercent: number;
readonly [key: string]: unknown;
}
Required task fields:
id: Stable task identifier.parentId: Parent task id or null.name: Text shown in the task table and optional bar label.type: task, summary, or milestone.startDate: ISO date or ISO date-time string.endDate: ISO date or ISO date-time string.progressPercent: Number from 0 to 100.Additional fields are preserved, so application-specific task data can stay in the same row objects.
Dependencies are supplied through grid.ganttDependencies.
export interface DependencyEntity {
readonly id: string;
readonly predecessorTaskId: string;
readonly successorTaskId: string;
readonly type:
| 'finish-to-start'
| 'start-to-start'
| 'finish-to-finish'
| 'start-to-finish';
readonly lagDays?: number;
}
Only finish-to-start dependencies are rendered in the current version. Other dependency types are accepted by the TypeScript shape and ignored by the renderer so the data model can evolve without breaking consumers.
Dependency paths are rendered as a non-interactive SVG layer inside the RevoGrid data slot. This keeps arrows aligned with virtualized rows and timeline bars while leaving grid selection, editing, and focus behavior under RevoGrid control.
Configure the plugin through grid.gantt.
grid.gantt = {
id: 'release-plan',
name: 'Release Plan',
version: '1',
timeZone: 'UTC',
updatedAt: '2026-05-10T00:00:00Z',
zoomPreset: 'day-week',
visuals: {
showDependencies: true,
showTaskLabels: true,
},
};
GanttPluginConfigexport interface GanttPluginConfig {
readonly id: string;
readonly name: string;
readonly version: string;
readonly timeZone: string;
readonly updatedAt: string;
readonly zoomPreset?: 'day-week' | 'week-month' | 'month-quarter';
readonly visuals?: {
readonly showDependencies?: boolean;
readonly showTaskLabels?: boolean;
};
}
Configuration fields:
id: Project or plan id.name: Project or plan name.version: Application-defined version string.timeZone: Time zone identifier for the plan.updatedAt: ISO update timestamp.zoomPreset: Timeline density. Defaults to day-week.visuals.showDependencies: Set to false to hide dependency lines without clearing ganttDependencies.visuals.showTaskLabels: Set to false to hide labels next to bars.@revolist/gantt includes three timeline presets:
| Preset | Best for | Header style |
|---|---|---|
day-week |
Detailed daily project schedules | Month row + day cells |
week-month |
Medium-range roadmap timelines | Month row + week cells |
month-quarter |
Long-range planning | Quarter row + month cells |
The generated timeline covers the task range and enforces a minimum range of two years so horizontal planning stays consistent even with a small initial task set.
GanttPlugin is a regular RevoGrid plugin.
On mount it:
columns, source, columnTypes, resize state, and inline positioning.@revolist/revogrid-column-date.columnType: 'gantt'.On destroy it restores the original grid configuration.
import {
GanttPlugin,
createGanttColumnType,
createTimelineScale,
projectGanttRows,
createGanttBarLayout,
createDependencyLayouts,
type GanttPluginConfig,
type TaskEntity,
type DependencyEntity,
type TimelineZoomPreset,
} from '@revolist/gantt';
Primary exports:
GanttPlugin: RevoGrid plugin class.GanttPluginConfig: Public Gantt configuration.TaskEntity: Task row shape.DependencyEntity: Dependency row shape.TimelineZoomPreset: Supported zoom preset union.createGanttColumnType: RevoGrid column type factory for timeline cells.createTimelineScale: Pure date-to-pixel timeline helper.projectGanttRows: Projects task rows into renderable Gantt rows.createGanttBarLayout: Computes task bar geometry.createDependencyLayouts: Computes SVG paths for supported dependency links.Import the bundled CSS:
import '@revolist/gantt/dist/gantt.css';
Package styles are authored in src/styles.scss and emitted as dist/gantt.css during the Vite library build. The stylesheet defines timeline headers, grid background lines, task bars, milestones, progress fills, labels, and dependency paths. It is intentionally small and can be overridden with normal CSS selectors.
Useful selectors:
.rg-gantt-header {}
.rg-gantt-cell {}
.rg-gantt-bar {}
.rg-gantt-bar--summary {}
.rg-gantt-bar--milestone {}
.rg-gantt-bar-progress {}
.rg-gantt-bar-label {}
.rg-gantt-dependency {}
Because tasks live in grid.source, normal RevoGrid data updates can drive the Gantt timeline.
await grid.setDataAt({
row: 0,
col: 1,
colType: 'colPinStart',
rowType: 'rgRow',
val: '2026-06-01',
});
When task dates change, the plugin reprojects rows and updates task bar positions.
pnpm i
pnpm test
pnpm build
pnpm test:e2e
Run the local example:
pnpm dev
MIT