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

leo-gantt-svelte5

v0.1.0

Published

A Gantt chart component built with **Svelte 5**. Designed for deep resource nesting, and fluid time-navigation.

Downloads

7

Readme

Svelte 5 High-Performance Gantt Engine

A Gantt chart component built with Svelte 5. Designed for deep resource nesting, and fluid time-navigation.

🚀 Key Features

  • Virtual 2D Rendering: Horizontal (Time) and Vertical (Resource) virtualization to keep the DOM lean and the framerate high (60 FPS) even with 5,000+ tasks.
  • Context & Focus Navigation: An interactive top-level Navigator (mini-map) used for panning and dynamic zooming of the main view.
  • Nested Resource Groups: Accordion-style resource rows with infinite nesting support and fixed row assignments.
  • Stateless "Dumb" Component: Fully controlled via props. No internal data state; it reflects the provided state and emits events.
  • Dependency Tracking: Built-in SVG-based dependency line rendering between tasks.
  • Tailwind CSS Integrated: Utility-first styling for easy customization of task bars, rows, and grid lines.
  • Theming Support: Fully customizable theme with built-in light and dark modes.

🛠 Tech Stack

  • Framework: Svelte 5 (utilizing Runes: $state, $derived, $props).
  • Logic: TypeScript (pure functional approach).
  • Styling: Tailwind CSS.
  • Testing:
    • Vitest: Unit tests for time-math and tree-flattening logic.
    • Storybook: Component isolation and visual state testing.
    • Playwright: E2E testing for drag/zoom and virtualization performance.

🏗 Project Structure

  • src/lib/logic/ – The "Brain": Pure TS functions for date-to-pixel conversion, virtualization offsets, and tree transformations.
  • src/lib/components/ – The "View": Svelte 5 components focused on rendering SVG and HTML structures.
  • src/lib/handlers/ – The "Controllers": A standard library of event handlers for zooming, scrolling, and expanding groups that users can plug into the component.
  • src/lib/types/ – TypeScript interfaces and types.

🚦 Getting Started

Installation

npm install

Basic Usage

Import the GanttChart component and provide the necessary data:

<script lang="ts">
  import { GanttChart } from 'svelte-gantt';
  import type { Task, FlattenedItem, Dependency } from 'svelte-gantt';

  let tasks: Task[] = [
    { id: 't1', rowId: 'r1', start: new Date('2024-01-01'), end: new Date('2024-01-05'), label: 'Task 1' }
  ];
  
  let rows: FlattenedItem[] = [
    { id: 'r1', label: 'Row 1', type: 'row', level: 0, parentId: null, isVisible: true }
  ];

  let dependencies: Dependency[] = [];

  let viewStart = new Date('2024-01-01');
  let viewEnd = new Date('2024-01-31');
  let scrollTop = 0;

  function handleScroll(top: number) {
    scrollTop = top;
  }
</script>

<div class="h-[500px] w-full">
  <GanttChart
    {tasks}
    {rows}
    {dependencies}
    {viewStart}
    {viewEnd}
    {scrollTop}
    containerHeight={500}
    containerWidth={800}
    onScroll={handleScroll}
  />
</div>

🧩 Components

GanttChart

The main component for rendering the Gantt chart.

Props:

  • tasks: Array of Task objects.
  • rows: Array of FlattenedItem objects (representing the visible rows).
  • dependencies: Array of Dependency objects.
  • viewStart: Start date of the visible time range.
  • viewEnd: End date of the visible time range.
  • scrollTop: Current vertical scroll position (controlled by parent).
  • selectedTaskId: ID of the currently selected task (optional).
  • containerHeight: Height of the chart container in pixels.
  • containerWidth: Width of the chart container in pixels.
  • rowHeight: Height of each row in pixels (default: 40).
  • taskHeight: Height of each task bar in pixels (default: 24).
  • sidebarWidth: Width of the sidebar in pixels (default: 250).
  • theme: GanttTheme object for styling (optional).

Callbacks:

  • onTaskClick(id: string): Fired when a task is clicked.
  • onRowToggle(id: string): Fired when a group row is toggled (expanded/collapsed).
  • onScroll(top: number): Fired when the chart is scrolled vertically.

Navigator

A timeline selector component for zooming and panning.

Props:

  • totalStart: Start date of the entire dataset.
  • totalEnd: End date of the entire dataset.
  • viewStart: Start date of the currently visible range.
  • viewEnd: End date of the currently visible range.
  • containerWidth: Width of the navigator container.
  • height: Height of the navigator (default: 40).
  • theme: GanttTheme object for styling (optional).

Callbacks:

  • onRangeChange(start: Date, end: Date): Fired when the selected time range changes.

🎨 Theming

The library supports theming via the GanttTheme interface. You can customize colors, dimensions, and styles.

Built-in Themes

  • GANTT_THEME: The default light theme.
  • GANTT_THEME_DARK: A built-in dark theme.

Custom Theme

You can create a custom theme by extending the default theme or creating a new object that matches the GanttTheme interface.

import { GANTT_THEME, type GanttTheme } from 'svelte-gantt';

const myTheme: GanttTheme = {
  ...GANTT_THEME,
  colors: {
    ...GANTT_THEME.colors,
    taskDefault: '#ff5733', // Custom task color
    background: 'bg-gray-50',
  }
};

Pass the custom theme to the components:

<GanttChart theme={myTheme} ... />
<Navigator theme={myTheme} ... />

📦 Data Structures

Task

interface Task {
  id: string;
  rowId: string;
  start: Date;
  end: Date;
  label: string;
  color?: string;
}

FlattenedItem (Row)

interface FlattenedItem {
  id: string;
  label: string;
  type: 'row' | 'group';
  level: number;
  parentId: string | null;
  isExpanded?: boolean;
  isVisible: boolean;
}

Dependency

interface Dependency {
  from: string;
  to: string;
}