FullCalendar Deployment & Usage Guide
Prerequisites
For End Users (Installing in Projects):
- Node.js 16+ (LTS recommended)
- npm, yarn, or pnpm (any package manager)
For Contributors (Building from Source):
- Node.js 16+
- PNPM (required - the project will not build with npm/yarn)
npm install -g pnpm - Git
Installation
Option A: Using FullCalendar in Your Project
Install the core package and required plugins:
npm install @fullcalendar/core @fullcalendar/interaction @fullcalendar/daygrid
Additional view plugins (install as needed):
npm install @fullcalendar/timegrid @fullcalendar/list @fullcalendar/multimonth
Framework Connectors (choose one if using a framework):
# React
npm install @fullcalendar/react
# Vue 3
npm install @fullcalendar/vue3
# Angular
npm install @fullcalendar/angular
# Vue 2 (legacy)
npm install @fullcalendar/vue
Option B: CDN (Standard Bundle)
For quick prototyping or static sites, use the Standard Bundle:
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/main.min.css' rel='stylesheet' />
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js'></script>
Option C: Development/Contribution Setup
Clone the monorepo and install dependencies:
git clone https://github.com/fullcalendar/fullcalendar.git
cd fullcalendar
pnpm install
Note: The project uses PNPM workspaces. Using npm or yarn will result in dependency resolution errors.
Configuration
Basic Calendar Setup
Create a calendar instance with plugins and options:
import { Calendar } from '@fullcalendar/core'
import interactionPlugin from '@fullcalendar/interaction'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
const calendarEl = document.getElementById('calendar')
const calendar = new Calendar(calendarEl, {
plugins: [
interactionPlugin,
dayGridPlugin,
timeGridPlugin
],
initialView: 'dayGridMonth',
editable: true,
selectable: true,
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
events: [
{ title: 'Meeting', start: new Date() }
]
})
calendar.render()
Framework-Specific Configuration
React:
import FullCalendar from '@fullcalendar/react'
import dayGridPlugin from '@fullcalendar/daygrid'
export default function CalendarComponent() {
return (
<FullCalendar
plugins={[dayGridPlugin]}
initialView="dayGridMonth"
/>
)
}
Vue 3:
<template>
<FullCalendar :options="calendarOptions" />
</template>
<script setup>
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
const calendarOptions = {
plugins: [dayGridPlugin],
initialView: 'dayGridMonth'
}
</script>
Build & Run
Development Mode (Watch & Rebuild)
Build packages and watch for changes:
pnpm run dev
This compiles TypeScript and watches for file changes across all packages in the monorepo.
Production Build
Create optimized distribution files:
pnpm run build
Output will be in each package's dist/ directory (e.g., packages/core/dist/).
Testing
Run headless tests:
pnpm run test
Run tests interactively (opens browser):
pnpm run test:dev
Linting
pnpm run lint
Clean Build Artifacts
pnpm run clean
Deployment
As a Dependency in Production Apps
-
Bundle Optimization: Import only the plugins you need to minimize bundle size:
// Good - minimal bundle import { Calendar } from '@fullcalendar/core' import dayGridPlugin from '@fullcalendar/daygrid' // Avoid - imports entire standard bundle unnecessarily import { Calendar } from 'fullcalendar' -
Tree Shaking: Ensure your bundler (Webpack, Vite, Rollup) is configured for tree-shaking to eliminate unused plugins.
-
CSS Import: Import required CSS:
import '@fullcalendar/core/index.css' import '@fullcalendar/daygrid/index.css'
CDN Deployment
For static sites or simple implementations:
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/main.min.css' rel='stylesheet' />
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.10/index.global.min.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const calendarEl = document.getElementById('calendar')
const calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth'
})
calendar.render()
})
</script>
</head>
<body>
<div id='calendar'></div>
</body>
</html>
Framework Deployment
When deploying apps using framework connectors:
- React/Next.js: Use dynamic imports with
ssr: falseif encountering window/document errors during SSR - Angular: Ensure
HttpClientModuleis imported if using event sources with HTTP requests - Vue/Nuxt: Wrap in
<ClientOnly>tags or useprocess.clientchecks for Nuxt SSR
Publishing (Maintainers Only)
To publish new versions to npm (requires appropriate permissions):
pnpm run build
# Version bump and publish handled via changesets or manual lerna/pnpm commands
# See CONTRIBUTING.md for specific release procedures
Troubleshooting
Build Issues
Error: "Cannot find module '@fullcalendar/core'" during development
- Ensure you ran
pnpm install(not npm install) - Run
pnpm run buildat least once to generate dist files - Check that you're in the root of the monorepo when running install
PNPM Lockfile Conflicts
pnpm install --frozen-lockfile
# If conflicts persist:
rm -rf node_modules pnpm-lock.yaml
pnpm install
Runtime Issues
"No available view plugins" error
- Verify you've imported and registered view plugins (dayGridPlugin, timeGridPlugin, etc.)
- Check that
initialViewmatches an available plugin view name (e.g., 'dayGridMonth', 'timeGridWeek')
Drag & drop not working
- Ensure
@fullcalendar/interactionis installed and included in the plugins array:plugins: [interactionPlugin, dayGridPlugin]
TypeScript type errors
- Install
@fullcalendar/coreas a dev dependency if using TypeScript:npm install --save-dev @fullcalendar/core - Ensure
"moduleResolution": "node"is set in yourtsconfig.json
Events not displaying
- Verify date formats match ISO 8601 or Java Date objects
- Check browser console for parsing errors
- Ensure event dates fall within the
validRangeif configured
Framework-Specific Issues
React: "window is not defined" (SSR)
import dynamic from 'next/dynamic'
const FullCalendar = dynamic(() => import('@fullcalendar/react'), { ssr: false })
Vue: Calendar not resizing
- Call
calendar.updateSize()after the container becomes visible (e.g., in a tab or modal) - Or use the
handleWindowResizeoption set totrue(default)
Angular: Change detection not firing
- Wrap calendar callbacks in
NgZone.run():this.zone.run(() => { // handle event drop logic })