Data Model
Gantt works with two main representations of task and link data:
- Serialized: JSON-compatible shapes with string dates, used in server responses, persisted JSON, and DataProcessor exchange
- Runtime: client-side objects with
Datefields and computed$-prefixed properties, returned by methods like gantt.getTask() and gantt.getLink()
When you provide data to Gantt (rather than read it back), date fields may be either a Date or a string. The TaskInput type captures this lenient input shape, so you don't have to commit to Task or SerializedTask for data you author or hold in application state.
The canonical top-level payload passed to gantt.parse() is GanttData.
Core runtime and serialized types are exported from @dhx/gantt. Wrapper packages re-export and consume these types in their public APIs, but the exact prop surface differs by wrapper.
Data Lifecycle
Data flows through two transformations:
- Loading: serialized task and link data is passed to
gantt.parse()organtt.load(). Gantt parses date strings intoDateobjects and adds computed$-prefixed properties, producing runtimeTaskandLinkobjects. - Saving: when changes are sent to the server via DataProcessor, dates are serialized back to strings and temporary
$-prefixed fields are stripped.
See Data Loading and Server-Side Integration for behavior details.
SerializedTask
The JSON-compatible task shape. Date fields are strings, so this object can be safely passed through JSON.stringify() / JSON.parse().
interface SerializedTask {
id?: string | number;
start_date?: string;
end_date?: string;
duration?: number;
text?: any;
type?: string;
parent?: string | number;
progress?: number;
open?: boolean;
auto_scheduling?: boolean;
unscheduled?: boolean;
constraint_date?: string;
constraint_type?: string;
deadline?: string;
color?: string;
textColor?: string;
progressColor?: string;
bar_height?: number;
row_height?: number;
hide_bar?: boolean;
baselines?: SerializedBaseline[];
calendar_id?: string | number;
editable?: boolean;
readonly?: boolean;
render?: string;
resource?: string[];
rollup?: boolean;
target?: string;
[customProperty: string]: any;
}
For a meaningful scheduled task in serialized JSON, provide one valid scheduling combination:
start_date+durationstart_date+end_dateduration+end_date
If unscheduled: true, dates can be omitted.
For detailed property descriptions, see Task Properties.
SerializedLink
interface SerializedLink {
id: string | number;
source: string | number;
target: string | number;
type: string;
lag?: number;
readonly?: boolean;
editable?: boolean;
[customProperty: string]: any;
}
For detailed property descriptions, see Link Properties.
Runtime Task and Link
After loading, Gantt stores tasks as runtime Task objects.
Main differences from SerializedTask:
- task date fields such as
start_date,end_date,constraint_date, anddeadlineare JavaScriptDateobjects - computed
$-prefixed fields are added and maintained on the client
Common runtime-only task fields:
| Property | Type | Description |
|---|---|---|
$index | number | Global vertical position in the visible list |
$level | number | Nesting depth in the task hierarchy |
$open | boolean | Whether the branch is currently expanded |
$source | Array | IDs of links going out of the task |
$target | Array | IDs of links coming into the task |
$has_child | boolean | Whether the task has child tasks |
The runtime Link object has the same field set as SerializedLink, but it is the client-side object returned by methods like gantt.getLink().
For the full runtime lists, see Task Properties and Link Properties.
TaskInput
When you provide task data to Gantt - gantt.parse(), gantt.addTask(), the tasks config/prop, or your own application store - use TaskInput. It is the lenient input shape: date fields accept either a Date or a string, and every field (including id) is optional, since Gantt generates an id when one is not supplied.
type TaskInput = Partial<SerializedTask> | Partial<Task>;
Use TaskInput for data you author or hold in application state. Use Task (runtime, Date dates, $-prefixed fields) when reading Gantt's own objects via methods like gantt.getTask(), and SerializedTask (string dates only) for JSON you exchange with a server.
// Application-owned task data handed to Gantt - either date form is accepted:
const tasks: TaskInput[] = [
{ id: 1, text: "Task #1", start_date: new Date(2026, 3, 1), duration: 5 },
{ id: 2, text: "Task #2", start_date: "2026-04-02", duration: 3 }
];
Storing application state as TaskInput[] is preferable to typing it as SerializedTask[] or Task[]: it avoids mismatches when your seed data uses Date objects but the type expects strings (or vice versa). Pick Task / SerializedTask only for the specific boundaries where the date representation is fixed.
Supporting Types
Baseline and SerializedBaseline
interface Baseline {
id: string | number;
task_id: string | number;
start_date: Date;
duration: number;
end_date: Date;
[customProperty: string]: any;
}
interface SerializedBaseline {
id?: string | number;
task_id?: string | number;
start_date?: string;
duration?: number;
end_date?: string;
[customProperty: string]: any;
}
ResourceAssignment and SerializedResourceAssignment
interface ResourceAssignment {
id: string | number;
task_id: string | number;
resource_id: string | number;
value: number | string;
delay: number;
start_date: Date;
end_date: Date;
duration: number;
mode: string;
[customProperty: string]: any;
}
interface SerializedResourceAssignment {
id?: string | number;
task_id: string | number;
resource_id: string | number;
value?: number | string;
mode?: string;
delay?: number;
start_date?: string;
duration?: number;
end_date?: string;
[customProperty: string]: any;
}
ResourceItem
interface ResourceItem {
id: string | number;
text?: string;
parent?: string | number;
open?: boolean;
unit?: string | number;
default_value?: string | number;
[customProperty: string]: any;
}
See Inbuilt Baselines and Resource Management for feature-specific details.
GanttData
The object passed to gantt.parse():
type GanttData =
| {
data: (SerializedTask | Task)[];
tasks?: undefined;
links?: (SerializedLink | Link)[];
resources?: Partial<ResourceItem>[];
assignments?: (SerializedResourceAssignment | ResourceAssignment)[];
baselines?: (SerializedBaseline | Baseline)[];
collections?: Record<string, Array<Record<string, unknown>>>;
}
| {
tasks: (SerializedTask | Task)[];
data?: undefined;
links?: (SerializedLink | Link)[];
resources?: Partial<ResourceItem>[];
assignments?: (SerializedResourceAssignment | ResourceAssignment)[];
baselines?: (SerializedBaseline | Baseline)[];
collections?: Record<string, Array<Record<string, unknown>>>;
};
Both tasks and data keys are accepted for the task array. tasks is preferred in new code.
gantt.parse({
tasks: [
{ id: 1, text: "Project #1", start_date: "2026-04-01", duration: 18 },
{ id: 2, text: "Task #1", start_date: "2026-04-02", duration: 8, parent: 1 }
],
links: [
{ id: 1, source: 1, target: 2, type: "0" }
]
});
Legacy Compatibility Aliases
Older API docs and typings still use several compatibility names:
DataToLoad1,DataToLoad2: deprecated keyed variants ofGanttDataNewTask: legacy alias ofTaskInput(defined asTaskInput | string | {}), kept for backward compatibility. PreferTaskInputin new code.NewResourceItem: deprecated compatibility alias forPartial<ResourceItem>NewAssignmentItem: deprecated compatibility alias forSerializedResourceAssignment | ResourceAssignment
These names are kept for backward compatibility, but GanttData, TaskInput, SerializedTask, SerializedLink, Task, and Link are the canonical concepts used in this guide.
Date Rules
- When exchanging JSON with the server, use strings for date fields
- If you build a JavaScript object directly and pass it to
gantt.parse(), runtime task and assignment objects may containDate - After loading, Gantt stores task dates as
Dateobjects in runtimeTask - Since v9.1.3, Gantt automatically detects ISO 8601 date strings
For details and examples, see Data Loading - Loading Task Dates.
Custom Properties
All data types support custom properties via [customProperty: string]: any. Custom properties are preserved on the client side after loading and can be used in templates, columns, editors, and backend storage.
gantt.parse({
tasks: [
{
id: 1,
text: "Task #1",
start_date: "2026-04-01",
duration: 10,
priority: "high",
owner: "John"
}
],
links: []
});
const task = gantt.getTask(1);
console.log(task.priority); // "high"
Task Order
Gantt displays tasks in the order they appear in the tasks array. The position of each item in the array - together with the parent hierarchy - is the only thing that determines the visual order on the client. The runtime $index property is calculated from this array position and is not persisted.
This means the data source controls the display order. If users can reorder tasks via drag-and-drop, the data source needs a way to remember the new order so that subsequent loads return tasks in the correct sequence.
The standard approach is a numeric sortorder column in the backend storage. The data source sorts tasks by this column before returning them. sortorder is a backend-only concept - Gantt does not read or interpret it on the client. It travels as a custom property if included in the payload, but has no built-in effect.
When a user reorders a task on the UI, Gantt populates the target property on the task object sent to the server via DataProcessor. The value indicates where the task was moved relative to its siblings:
target="taskId"- place this task before the task with the given idtarget="next:taskId"- place this task after the task with the given id
The backend uses this value to recalculate sortorder for the affected tasks.
For the full implementation pattern - database schema, initial values, and reorder logic - see Storing the Order of Tasks in the Server-Side Integration guide. For client-side drag-and-drop configuration, see Reordering Tasks.