← Back to fullcalendar/fullcalendar

How to Deploy & Use fullcalendar/fullcalendar

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

  1. 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'
    
  2. Tree Shaking: Ensure your bundler (Webpack, Vite, Rollup) is configured for tree-shaking to eliminate unused plugins.

  3. 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: false if encountering window/document errors during SSR
  • Angular: Ensure HttpClientModule is imported if using event sources with HTTP requests
  • Vue/Nuxt: Wrap in <ClientOnly> tags or use process.client checks 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 build at 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 initialView matches an available plugin view name (e.g., 'dayGridMonth', 'timeGridWeek')

Drag & drop not working

  • Ensure @fullcalendar/interaction is installed and included in the plugins array:
    plugins: [interactionPlugin, dayGridPlugin]
    

TypeScript type errors

  • Install @fullcalendar/core as a dev dependency if using TypeScript:
    npm install --save-dev @fullcalendar/core
    
  • Ensure "moduleResolution": "node" is set in your tsconfig.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 validRange if 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 handleWindowResize option set to true (default)

Angular: Change detection not firing

  • Wrap calendar callbacks in NgZone.run():
    this.zone.run(() => {
      // handle event drop logic
    })