Installation
Install shadcn-scheduler — own the full source, use the npm package, or pick individual modules.
Installation
shadcn-scheduler gives you three installation paths. The key difference is ownership and bundle size.
Option 1 — shadcn registry (recommended — you own the code)
Install only what you need
Pick the preset that matches your use case. Each one copies only the files that domain actually needs — no bloat from views or engines you'll never use.
| Preset | Use case | Views included | Install command |
|---|---|---|---|
| Full bundle | Everything | All views | npx shadcn@latest add https://shadcn-scheduler.vercel.app/registry.json |
| Roster | Workforce shift scheduling | Day, Week, Month, Year, List | npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-roster.json |
| TV / EPG | TV guide, programme scheduling | Timeline | npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-tv.json |
| Conference | Event & session scheduling | Day, Week, Month, List | npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-conference.json |
| Festival | Music festival lineups | Timeline | npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-festival.json |
| Healthcare | Ward & staff rotas | Day, Week, Month, List | npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-healthcare.json |
| Gantt | Project & sprint planning | Week, Day, List | npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-gantt.json |
| Venue | Room & space bookings | Timeline | npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-venue.json |
What gets copied
Grid-based presets (Roster, Conference, Healthcare, Gantt) copy:
- Core primitives —
types.ts,constants.ts,context.tsx,config.ts - Grid engine —
GridView.tsx, drag engine, geometry, day/week/month/year views - Domain config — the preset labels and defaults for your use case
Timeline-based presets (TV, Festival, Venue) copy:
- Core primitives — same as above
- Timeline engine —
TimelineView.tsx(horizontal scroll, resources as rows) - Domain config — the preset labels and defaults for your use case
The full bundle copies all of the above plus every domain config.
Example — TV / EPG only
npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-tv.jsonCopies ~32 files into components/scheduler/. You import from your own folder:
import { Scheduler, createSchedulerConfig } from '@/components/scheduler'
const config = createSchedulerConfig({ preset: 'tv', snapMinutes: 15 })
export default function EPGPage() {
return (
<div className="h-[600px]">
<Scheduler
categories={channels}
employees={channelEmployees}
shifts={programmes}
onShiftsChange={setProgs}
initialView="timeline"
config={config}
/>
</div>
)
}Example — Workforce Roster only
npx shadcn@latest add https://shadcn-scheduler.vercel.app/r/scheduler-roster.jsonimport { Scheduler, createSchedulerConfig } from '@/components/scheduler'
const config = createSchedulerConfig({ preset: 'roster', initialScrollToNow: true, snapMinutes: 30 })Why this matters: You can edit GridView.tsx, add fields to types.ts, change the drag behaviour — anything you want. No fork, no patch file, no fighting a third-party package. And you only copy what you actually use.
Option 2 — npm package (all presets, single install)
If you prefer not to own the source, use the npm package:
npm install @sushill/shadcn-schedulerimport { Scheduler, createSchedulerConfig } from '@sushill/shadcn-scheduler'
// TV preset:
const tvConfig = createSchedulerConfig({ preset: 'tv' })
// Roster preset:
const rosterConfig = createSchedulerConfig({ preset: 'roster', initialScrollToNow: true })Option 3 — Modular packages (tree-shakeable)
The @shadcn-scheduler/* monorepo lets you install only the packages you actually use. No dead code.
Install the foundation
npm install @shadcn-scheduler/core @shadcn-scheduler/shellAdd only the views you need
# Month calendar
npm install @shadcn-scheduler/view-month
# Year heatmap
npm install @shadcn-scheduler/view-year
# Tabular list view
npm install @shadcn-scheduler/view-list
# Grid views (day, week, timeline, kanban)
npm install @shadcn-scheduler/view-day @shadcn-scheduler/view-week
npm install @shadcn-scheduler/view-timeline @shadcn-scheduler/view-kanbanAdd only the plugins you need
npm install @shadcn-scheduler/plugin-audit # action history
npm install @shadcn-scheduler/plugin-recurrence # recurring shifts
npm install @shadcn-scheduler/plugin-export # CSV / ICS / PDF export
npm install @shadcn-scheduler/plugin-markers # draggable deadline lines
npm install @shadcn-scheduler/plugin-dependencies # SVG dependency arrows
npm install @shadcn-scheduler/plugin-histogram # utilisation chart
npm install @shadcn-scheduler/plugin-availability # availability overlaysOr use a domain preset config
npm install @shadcn-scheduler/preset-tv
npm install @shadcn-scheduler/preset-healthcare
npm install @shadcn-scheduler/preset-conferenceOr install the fat bundle (same API as Option 2)
npm install @shadcn-scheduler/schedulerMinimal usage example
'use client'
import { SchedulerProvider } from '@shadcn-scheduler/shell'
import { MonthView } from '@shadcn-scheduler/view-month'
import type { SchedulerConfig } from '@shadcn-scheduler/core'
const config: SchedulerConfig = { snapMinutes: 30 }
export default function App() {
return (
<SchedulerProvider categories={categories} employees={employees} config={config}>
<MonthView date={new Date()} shifts={shifts} setShifts={setShifts} onAddShift={handleAdd} />
</SchedulerProvider>
)
}→ Full modular packages reference | → Try the demo
Requirements
- React 18+
- Tailwind CSS 3 or 4
- shadcn/ui CSS variables (or add them manually — see below)
Peer dependencies
Grid-based presets (Roster, Conference, Healthcare, Gantt) need:
npm install @tanstack/react-virtual react-resizable-panels @radix-ui/react-context-menu @radix-ui/react-popover @radix-ui/react-tabs @radix-ui/react-toggle-group @radix-ui/react-checkbox @radix-ui/react-slot lucide-react react-day-picker class-variance-authority clsx tailwind-mergeTimeline-based presets (TV, Festival, Venue) need a smaller set:
npm install @tanstack/react-virtual @radix-ui/react-popover @radix-ui/react-tabs @radix-ui/react-checkbox @radix-ui/react-slot lucide-react react-day-picker class-variance-authority clsx tailwind-mergeTailwind configuration
Add the scheduler to your Tailwind content array:
// tailwind.config.ts
export default {
content: [
'./app/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
// If using npm package, also add:
'./node_modules/@sushill/shadcn-scheduler/dist/**/*.{js,mjs}',
],
}CSS variables
The scheduler reads standard shadcn/ui CSS variables. If you're already on shadcn/ui — nothing extra needed.
If you're not on shadcn/ui, add these to your global CSS:
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.7% 15.9%;
--border: 240 5.9% 90%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--border: 240 3.7% 15.9%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
}Verify the install
import { Scheduler } from '@/components/scheduler' // registry
// import { Scheduler } from '@sushill/shadcn-scheduler' // npm Option 2
// import { Scheduler } from '@shadcn-scheduler/scheduler' // npm Option 3 fat bundle
export default function Test() {
return (
<div className="h-[500px]">
<Scheduler
categories={[{ id: 'c1', name: 'Team', kind: 'category', colorIdx: 0 }]}
employees={[{ id: 'e1', name: 'Alex', kind: 'employee', categoryId: 'c1', colorIdx: 0 }]}
shifts={[]}
onShiftsChange={() => {}}
initialView="week"
/>
</div>
)
}If you see a weekly grid — you're set.