A Canvas-Based React Timeline Editor
A high-performance modular framework combining headless state, React interaction layers, and a 60fps canvas renderer. Build professional video, audio, or animation timelines that stay butter smooth under any workload.
Built for Professional Grade Editing
Engineered to overcome web rendering bottlenecks, keeping interaction physics snappy and rendering layouts precise.
Canvas Rendering Engine
Drawn using a 2D HTML5 canvas context in a background worker. Keeps the main DOM tree completely flat, bypassing reflow paint storms during scrubbing, zooming, and playback.
Frame-Accurate Edits
Native implementation of linear track layouts, spatial search indexes, snapping lines, in/out marker ranges, and professional slip/slide/trim calculations.
React Or Your Own UI Surface
Use our pre-bundled React hooks, provider states, and delegated hit-testing interaction layers, or write custom CSS/DOM interfaces around the headless engine core.
Modular & Lightweight
A monorepo structure separating state logic, React bindings, canvas drawing pipeline, and math utilities. Import only the sub-packages your application requires.
Designed for Developers
Get up and running in minutes. Simply construct a timeline engine, wrap your application in the provider context, and drop in ready-made canvas renderers and drag interaction nodes.
import { CanvasRenderer, Timeline, TimelineEngine, TimelineProvider, fromSeconds, type Track,} from '@techsquidtv/canvas-timeline';import '@techsquidtv/canvas-timeline/styles.css';import { useMemo } from 'react';
const tracks: Track[] = [32 collapsed lines
{ id: 'video', kind: 'visual', name: 'Video', height: 48, clips: [ { id: 'intro', sourceId: 'intro.mov', timelineStart: fromSeconds(1), timelineEnd: fromSeconds(5.5), sourceStart: fromSeconds(0), label: 'Intro', }, ], }, { id: 'audio', kind: 'audio', name: 'Audio', height: 48, clips: [ { id: 'score', sourceId: 'score.wav', timelineStart: fromSeconds(0), timelineEnd: fromSeconds(15), sourceStart: fromSeconds(0), label: 'Score', }, ], },];
function App() { const engine = useMemo( () => new TimelineEngine({ duration: fromSeconds(15), playheadTime: fromSeconds(2), tracks, }), [] );
return ( <TimelineProvider engine={engine}> <div className="timeline-shell"> <div className="timeline-stage"> <Timeline.Root className="timeline-fill"> <CanvasRenderer /> <Timeline.PlayheadArea /> <Timeline.PlayheadGrabber /> <Timeline.ClipInteractionLayer /> </Timeline.Root> </div> <div className="timeline-scrollbar-row"> <Timeline.ViewportScrollbar> <Timeline.ViewportScrollbarThumb> <Timeline.ViewportScrollbarHandle side="start" /> <Timeline.ViewportScrollbarHandle side="end" /> </Timeline.ViewportScrollbarThumb> </Timeline.ViewportScrollbar> </div> </div> </TimelineProvider> );}The Package Ecosystem
Discrete, lightweight packages designed to fit your exact integration needs.
core
Headless state manager, playhead clock transport, spatial interval indexing, snapping, and command-stack history.
react
State contexts, drag & trim pointer handles, zoom/scroll integrations, playheads, and keyboard/accessible keybindings.
renderer
HTML5 Canvas drawing pipeline. Renders dense tracks, clips, grids, markers, and waveforms at 60fps inside an Offscreen Canvas worker.
utils
RationalTime arithmetic (numerator/denominator) to prevent float-rounding micro-drift in high-frequency playhead or zoom operations.
Open source sponsorship
Made possible by Canvas Timeline sponsors
Sponsorship helps fund maintenance, docs, examples, and the editor roadmap. Sponsor data is pulled from GitHub Sponsors at build time and limited to public GitHub profile data.
No public Canvas Timeline sponsors yet.
Become the first sponsor