npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-gantt-nl

v0.1.0

Published

A lightweight, zero-dependency React Gantt chart with native baseline support

Downloads

33

Readme

react-gantt-nl

A lightweight, zero-dependency React Gantt chart with native baseline support.

Features

  • Native Baseline Support - Baseline bars are first-class citizens, not overlays
  • Drag & Resize - Intuitive task scheduling with drag and resize
  • Dependencies - Support for FS, SS, FF, SF dependency types
  • Grouping - Hierarchical task structure with collapsible groups
  • Critical Path - Visual highlighting for critical tasks
  • Milestones - Diamond-shaped milestone markers
  • Customizable - Theming, custom columns, custom tooltips
  • TypeScript - Full TypeScript support
  • Zero Dependencies - Only requires React

Installation

npm install react-gantt-nl
# or
yarn add react-gantt-nl
# or
pnpm add react-gantt-nl

Quick Start

import { Gantt, GanttTask } from 'react-gantt-nl';

const tasks: GanttTask[] = [
  {
    id: '1',
    name: 'Foundation Work',
    type: 'task',
    start: new Date('2024-01-01'),
    end: new Date('2024-01-15'),
    progress: 50,
    // Baseline dates - renders gray bar below current schedule
    baselineStart: new Date('2024-01-01'),
    baselineEnd: new Date('2024-01-10'),
  },
  {
    id: '2',
    name: 'Framing',
    type: 'task',
    start: new Date('2024-01-16'),
    end: new Date('2024-01-30'),
    progress: 0,
    dependencies: ['1'],
  },
];

function App() {
  return (
    <Gantt
      tasks={tasks}
      config={{
        viewMode: 'week',
        showBaseline: true,
      }}
      onTaskDateChange={(event) => {
        console.log('Task moved:', event.task.name);
        console.log('New dates:', event.newStart, event.newEnd);
      }}
    />
  );
}

Baseline Support

Unlike other Gantt libraries where baselines are an afterthought, react-gantt-nl treats baseline dates as first-class citizens:

const task: GanttTask = {
  id: '1',
  name: 'My Task',
  type: 'task',
  // Current schedule
  start: new Date('2024-01-10'),
  end: new Date('2024-01-25'),
  progress: 30,
  // Original baseline (renders as gray bar below)
  baselineStart: new Date('2024-01-01'),
  baselineEnd: new Date('2024-01-15'),
};

The baseline bar automatically:

  • Uses the same coordinate system as task bars (perfect alignment)
  • Extends the date range if baseline dates fall outside current schedule
  • Shows variance in the tooltip

Task Types

// Regular task
{ type: 'task', ... }

// Milestone (diamond shape)
{ type: 'milestone', ... }

// Group/Summary (bracket style, aggregates children)
{ type: 'group', ... }

Dependencies

const dependencies: GanttDependency[] = [
  { fromId: '1', toId: '2', type: 'finish-to-start' },  // Task 1 must finish before Task 2 starts
  { fromId: '3', toId: '4', type: 'start-to-start' },   // Both start together
  { fromId: '5', toId: '6', type: 'finish-to-finish' }, // Both finish together
];

<Gantt tasks={tasks} dependencies={dependencies} />

Configuration

<Gantt
  tasks={tasks}
  config={{
    viewMode: 'week',        // 'day' | 'week' | 'month'
    rowHeight: 40,           // Height of each row
    headerHeight: 50,        // Height of timeline header
    showTaskList: true,      // Show left panel
    taskListWidth: 360,      // Width of left panel
    showBaseline: true,      // Show baseline bars
    showDependencies: true,  // Show dependency arrows
    showTodayMarker: true,   // Show today line
    showWeekends: true,      // Highlight weekends
    allowDrag: true,         // Allow dragging tasks
    allowResize: true,       // Allow resizing tasks
    locale: 'en-US',         // Date formatting locale
    firstDayOfWeek: 1,       // 0 = Sunday, 1 = Monday
    datePadding: 7,          // Days padding around tasks
  }}
/>

Theming

<Gantt
  tasks={tasks}
  theme={{
    primary: '#2563eb',
    background: '#ffffff',
    backgroundAlt: '#f9fafb',
    text: '#0f172a',
    textMuted: '#64748b',
    border: '#e5e7eb',
    taskBar: '#525252',
    taskProgress: '#171717',
    baseline: '#9ca3af',
    critical: '#dc2626',
    // ... see GanttTheme type for all options
  }}
/>

Dark Mode

import { Gantt, darkTheme } from 'react-gantt-nl';

<Gantt tasks={tasks} theme={darkTheme} />

Custom Columns

const columns: GanttColumn[] = [
  {
    id: 'name',
    header: 'Task',
    width: 200,
  },
  {
    id: 'assignee',
    header: 'Assignee',
    width: 100,
    accessor: (task) => task.payload?.assignee || '-',
  },
  {
    id: 'status',
    header: 'Status',
    width: 80,
    render: (task) => (
      <span className={`status-${task.progress === 100 ? 'done' : 'active'}`}>
        {task.progress === 100 ? 'Done' : 'Active'}
      </span>
    ),
  },
];

<Gantt tasks={tasks} columns={columns} />

Event Handlers

<Gantt
  tasks={tasks}
  onTaskDateChange={(event) => {
    // Called when task is dragged or resized
    const { task, newStart, newEnd, isResize } = event;
    updateTaskDates(task.id, newStart, newEnd);
  }}
  onTaskClick={(event) => {
    // Called when task is clicked
    openTaskDetails(event.task.id);
  }}
  onTaskDoubleClick={(event) => {
    // Called when task is double-clicked
    openTaskEditor(event.task.id);
  }}
  onGroupToggle={(taskId, isExpanded) => {
    // Called when group is expanded/collapsed
  }}
/>

API Reference

GanttTask

| Property | Type | Required | Description | |----------|------|----------|-------------| | id | string | Yes | Unique identifier | | name | string | Yes | Display name | | type | 'task' | 'milestone' | 'group' | Yes | Task type | | start | Date | Yes | Start date | | end | Date | Yes | End date | | progress | number | Yes | Progress (0-100) | | baselineStart | Date | No | Baseline start date | | baselineEnd | Date | No | Baseline end date | | parentId | string | No | Parent task ID for grouping | | dependencies | string[] | No | IDs of predecessor tasks | | isCritical | boolean | No | On critical path | | isDisabled | boolean | No | Disable interactions | | color | string | No | Custom bar color | | payload | object | No | Custom data |

GanttDependency

| Property | Type | Required | Description | |----------|------|----------|-------------| | fromId | string | Yes | Source task ID | | toId | string | Yes | Target task ID | | type | DependencyType | Yes | Dependency type | | lag | number | No | Lag in days |

DependencyType

  • finish-to-start - Predecessor must finish before successor starts
  • start-to-start - Both start together
  • finish-to-finish - Both finish together
  • start-to-finish - Predecessor start triggers successor finish

License

MIT