DEV Community

Cover image for I built a headless timeline/Gantt for React — would love some feedback
Ruslan Kriklivyy
Ruslan Kriklivyy

Posted on

I built a headless timeline/Gantt for React — would love some feedback

I needed a scheduling view for a project of mine, wanted it to stay fast with a lot of items and to look exactly like the rest of the app, so I ended up building the component myself. It turned into a library.

Roadline — a headless, virtualized timeline/Gantt component for React. MIT, no runtime dependencies.

Drag a bar to move it, drag its edges to resize, scroll to pan, ctrl/cmd + wheel to zoom. An item with no duration renders as a milestone.

What's in it:

  • Virtualized on both axes, with items indexed by time, so large boards stay smooth
  • Headless — Sidebar, Header, Body, Grid, Dependencies, Marker are separate pieces you render or skip, and bars are render props. The default theme is an optional stylesheet built on CSS variables
  • Dependency arrows between tasks (FS, SS, FF, SF)
  • Nested items with roll-up bars, not just groups
  • Any IANA time zone per instance, DST-correct
  • Keyboard editing with screen reader announcements
  • Fully controlled: the hook owns the viewport, you own the data. onItemMove is a request — nothing moves until your array does
  • 15 kB gzip for the React package, React 18 and 19, ESM + CJS, works in the Next.js App Router

Worth knowing before you try it: it's at 0.2.0, so pin the version — I may still change things. It targets modern browsers only (ResizeObserver, PointerEvent, Intl.DateTimeFormat.formatToParts, none polyfilled). And headless means a custom look costs you a bit more code than a batteries-included Gantt would.

Docs in the repo cover getting started, the API, recipes, theming, and there's a migration guide if you're coming from react-calendar-timeline.

I'd really appreciate feedback — especially on how the dragging and zooming feel in the demo, and whether the API shape makes sense to you. Happy to answer anything in the comments.

Top comments (3)

Collapse
 
swapnoneel123 profile image
Swapnoneel Saha

the controlled viewport and request style onitemmove are good choices for a headless component. i would document one common flow for optimistic updates and one for rejected moves, because scheduling apps often need server validation. a small performance example with item count and scroll behavior would also help users judge when virtualization becomes useful.

Collapse
 
kriklivyy22 profile image
Ruslan Kriklivyy

Thanks! I'll add two onItemMove examples (optimistic update + rejected move with rollback) and a perf note with item counts and scroll behavior so it's clear when virtualization starts to matter

Collapse
 
swapnoneel123 profile image
Swapnoneel Saha

those examples should make the controlled api much easier to evaluate. the rollback case is especially useful because it shows that onitemmove is a request and not a hidden state change. a short note on how to keep the viewport stable after a rejected move would also help.