V7 Changelog

Upgrade from v6 to v7, which brings a theme system, Tailwind support and a simpler DOM. This major release introduces a formal theme system, 4 new standard themes, plays well with Tailwind, simplifies the DOM structure, adds virtual rendering for large resource timelines, improves performance, accessibility, responsiveness, and print-view. In total, (AT LEAST) 57 tickets were resolved.

This guide assumes you’re upgrading from v6. To upgrade from v5, first follow the v5 → v6 guide and then return to this guide. The two upgrade guides can be stacked with no issue.

Want the code? Browse the documentation

Want the full docs in a non-changelog format? View the docs

Found a bug? Report it on the issue tracker

Related documents:

React#

  • Feature: @fullcalendar/react is no longer a connector around internal Preact rendering. It is now implemented in React itself, including working SSR and StrictMode.
  • Performance: Less flickering during event rerendering for React implementation (#7488)
  • Breaking: React >= 17 support
  • Breaking: FullCalendar.act testing util removed
  • Breaking: dependency changes:
    • temporal-polyfill added as a peer dependency (read more)
    • @fullcalendar/core removed as a peer dependency
    • @fullcalendar/daygrid and many other standard packages removed and moved to @fullcalendar/react/* entrypoints (see migration guide)
    • @fullcalendar/resource-timeline and many other premium packages removed and moved to @fullcalendar/react-scheduler, a new package (see migration guide)
  • Behavior: For the Remix framework previously required a hack to explicitly define the DOM-placement for styles, but this is no longer needed

Shadcn and MUI theme systems are also newly available for React. See below.

Preact#

  • Feature: FullCalendar implemented natively with Preact and finally exposed as packages: @fullcalendar/preact and @fullcalendar/preact-scheduler

Vue#

  • Breaking: Vue 2 support dropped (@fullcalendar/vue)
  • Breaking: Removed support for Vue no-build global-JS by no longer providing a global-JS dist file. See discussion about restoration.
  • Breaking: dependency changes:
    • temporal-polyfill added as a peer dependency (read more)
    • @fullcalendar/core removed as a peer dependency
    • @fullcalendar/daygrid and many other standard packages removed and moved to @fullcalendar/vue3/* entrypoints (see migration guide)
    • @fullcalendar/resource-timeline and many other premium packages removed and moved to @fullcalendar/vue3-scheduler, a new package (see migration guide)

Angular#

  • Breaking: supports Angular 16-21
  • Breaking: dependency changes:
    • temporal-polyfill added as a peer dependency (read more)
    • The @fullcalendar/core peer dependency renamed to fullcalendar
    • @fullcalendar/daygrid and many other standard packages removed and moved to @fullcalendar/angular/* entrypoints (see migration guide)
    • @fullcalendar/resource-timeline and many other premium packages removed and moved to @fullcalendar/angular-scheduler, a new package (see migration guide)

Vanilla JS#

  • Breaking: vanilla JS package renamed from @fullcalendar/core to fullcalendar
  • Breaking: for global script tag users, index.global.js renamed to all/global.js
  • Breaking: dependency changes:
    • temporal-polyfill added as a peer dependency (read more)
    • @fullcalendar/daygrid and many other standard packages removed and moved to fullcalendar/* entrypoints (see migration guide)
    • @fullcalendar/resource-timeline and many other premium packages removed and moved to fullcalendar-scheduler, a repurposed package (see migration guide)

Web Component#

  • Breaking: removed shadow attribute. always uses shadom-DOM now
  • Breaking: for global script tag users, index.global.js renamed to all/global.js
  • Breaking: dependency changes:
    • temporal-polyfill added as a peer dependency (read more)
    • @fullcalendar/core removed as a peer dependency
    • @fullcalendar/daygrid and many other standard packages removed and moved to @fullcalendar/web-component/* entrypoints (see migration guide)
    • @fullcalendar/resource-timeline and many other premium packages removed and moved to @fullcalendar/web-component-scheduler, a new package (see migration guide)

Standard Themes#

  • Feature: 4 new stock themes, viewable on the demos page
  • Feature: dark mode in all themes (#7904) (docs)
  • Feature: nice tab-focus effects on everything
  • Feature: settings to disable outer border on all themes
  • Feature: Does not have one baked-in theme that always needs to be loaded, even if customizations
  • Breaking: FullCalendar no longer bundles its own CSS. Furthermore, the calendar “theme” has been pulled out from the core, as a plugin. Thus, you must import your own stylesheets. This depends on what theme you choose (see stock themes)

View each UI frameworks’ docs for installation instruction.

Classic Theme#

There is a “Classic” theme that maintains the look of the old calendar. Changes from v6:

  • Feature: more spacious look
  • Breaking: Column headers in DayGrid and TimeGrid are no longer bold by default. See migration guide for how to restore.

Shadcn#

MUI#

Bootstrap#

  • Breaking: Bootstrap 4 theme support removed (@fullcalendar/bootstrap4)

Bootstrap 5 support (@fullcalendar/bootstrap5) was omitted from the initial v7.0.0 release and restored in v7.0.2 (#8040) (view docs). Changes from v6:

  • Feature: Better support for Bootstrap’s light/dark color modes via data-bs-theme, thanks to use of Bootstrap’s semantic color variables (#7465)
  • Breaking: bootstrap (5.3.0 or newer) and bootstrap-icons (1.8.0 or newer) are now peer dependencies. You must install them and list them in your package.json (see migration guide)
  • Breaking: The themeSystem setting has been removed, and you must import the theme’s stylesheet, @fullcalendar/bootstrap5/theme.css, along with fullcalendar/skeleton.css (see migration guide)
  • Breaking-Visual: Default line-height is less chunky
  • Breaking-Visual: Default event color is now the Bootstrap theme’s primary color (--bs-primary), a brighter blue in stock Bootstrap. Previously it was FullCalendar’s own blue (#3788d8), regardless of the Bootstrap theme (see migration guide for how to restore)
  • Breaking-Visual: Default background event color is now the Bootstrap theme’s success color (--bs-success), a darker green in stock Bootstrap. Previously it was FullCalendar’s own light green (#8fdf82)

Custom Themes#

  • Feature: Huge selection of className and content-injection settings, consituting a proper theme system
  • Feature: Only flat CSS selectors needed. No intentionally complicated CSS selectors to increase precedence
  • Feature: Tailwind support
  • Breaking: you cannot style an fc-* class-names like .fc-event because FullCalendar’s default DOM no longer includes them. View the CSS migration guide →
  • Breaking: customized CSS variables like --fc-event-bg-color have been refactor/renamed. View the CSS migration guide →
  • Breaking: renamed and modifed many display-hooks with names like *ClassNames, *Content, *DidMount, *WillUnmount. View the JS API migration guide →
  • Breaking: removed Theme class, registered via themeClasses plugin-hook. Was an undocumented API in v6. View the JS API migration guide →

Toolbar#

  • Feature: Infinite control with useCalendarController(). Only for React and Vue.
  • Feature: Toolbar CSS is more robust on smaller screens and more customizable for desired responsive behavior (#4638)
  • Feature: for built-in toolbars, can disable “List” buttons while returning i18n, set listText:false
  • Feature: for built-in toolbars, class-name and mount/unmount hooks on buttons of the toolbar (toolbar render hooks)
  • Feature: for built-in toolbars, control whether a button displays text, an icon, or BOTH, and what position of the icon. buttonDisplay or buttons[].display.
  • Feature: button icons now done with SVG instead of glyphicons. Better for Salesforce LWC and Content Security Policy (CSP). Use buttons[].iconContent setting (more info)
  • Feature: additional styling hooks (toolbarClass, toolbarSectionClass, toolbarTitleClass, etc)
  • Feature: for built-in toolbars, add custom elements via toolbarElements
  • Accessibility: Use aria-label instead of title attribute (#7584)
  • Accessibility: Aria improvement for view-switcher within toolbar (#7809, #6522)
  • Accessibility: Customizable heading hierarchy level via headingLevel (#6972)
  • Behavior: If a button string was added to headerToolbar or footerToolbar, but its text was not defined in customButtons, would display as an empty button (ugly). Now, if no text is defined (in buttons map), will fall back to displaying the button string.
  • Breaking: Huge change in skeleton. Uses flexbox.
  • Breaking: headerToolbar is disabled by default, unlike in v6 when rendered title, prev, next, and today buttons. (see migration guide)
  • Breaking: customButtons renamed to buttons (used for custom and standard buttons)
  • Breaking: buttonText removed in favor of buttons[].text (see migration guide)
  • Breaking: buttonIcons removed in favor of buttons[].iconClass (see migration guide)
  • Breaking: For headerToolbar/footerToolbar, when calendar direction:'rtl', elements within toolbar sections specified as left and right now span right-to-left (are we sure we want to do this!!??)
  • Breaking: (all themes) visually capitalizes button name strings, like “Today” versus old “today”
  • Breaking: Default titleFormat for week views omits day numbers. So now like Jan 2026 or Jan - Feb 2026 instead of Jan 25 – 31, 2026. This is because the day-numbers are presumed displayed in the column headers.
  • Breaking: titleRangeSeparator removed. Range separator is now determined by the Intl API.

Events (General)#

  • Feature: set event color, but only for background events (no normal events). backgroundEventColor
  • Feature: additional class-name settings for background events (more info)
  • Feature: additional class-name settings for styling subparts of a foreground event element (eventBeforeClass, eventInnerClass, eventTimeClass, etc) (more info)
  • Feature: additional class-name settings for targeting specific types of events (“block” events, “list-item” events, etc)
  • Feature: event-related class-name and mount hooks, callbacks given much more data (isInteractive, isShort, etc)
  • Print: background events no longer white-out portions of page for print-view. Instead, rendered with 1px colored borders instead.
  • Performance: Fixed unnecessary event rendering and calling of eventContent when unrelated events change (#3003, #7650)
  • Performance: DayGrid/TimeGrid rendering performance gain (#7677)
  • Accessibility: Non-editable events should not be rendered as anchor tags (#7675)
  • Accessibility: Give role=button to clickable event elements w/o urls (#7567)
  • Accessibility: Event time order different than DOM order, bad for tabbing (#6943)
  • Breaking: Calendar-wide event settings were renamed: eventClassNames -> eventClass, eventBackgroundColor/eventBorderColor -> eventColor, and eventTextColor -> eventContrastColor (see migration guide).
  • Breaking: eventClass (formerly eventClassNames), eventContent, eventDidMount, eventWillUnmount no longer apply to background events.
  • Breaking: Event input + Event API fields were renamed: classNames -> className, backgroundColor/borderColor -> color, and textColor -> contrastColor (see migration guide).
  • Breaking: Event-source fields were renamed: classNames -> className, backgroundColor/borderColor -> color, and textColor -> contrastColor (see migration guide).
  • Breaking: In v6, for list-item events in DayGrid view, the content generated eventContent would clear rendering of the colored dot. In v7, eventContent injects into the “inner” container (aka eventInnerClass) which does not wrap the dot (aka eventBeforeClass). (Learn how to restore old behavior)
  • Breaking: Event API’s .toPlainObject() and .toJSON() methods have modified signatures and return types

Resources (General)#

  • Breaking: Resource input + Resource API fields were renamed: eventClassNames -> eventClass, eventBackgroundColor/eventBorderColor -> eventColor, and eventTextColor -> eventContrastColor (see migration guide).
  • Breaking: The generic resourceLabel* settings have been replaced with more UI-specific settings (link: resourceDayHeader* and link: resourceCell*)
  • Breaking: Resource API’s .toPlainObject() and .toJSON() methods have modified signatures and return types

Calendar Views (General)#

  • Feature: slimmed down HTML skeleton. Removed nested <table>s in favor of Flexbox. Accessibility is maintained and even improved in many instances via role/aria attributes.
  • Feature: class-names for table-like elements across views: tableHeaderClass, tableBodyClass (table render hooks)
  • Breaking: viewClassNames was renamed to viewClass (simple string). See View Render Hooks.
  • Performance: Less layout thrashing (#4906)
  • Accessibility: - Better table semantics for screen readers (#6641, #7656, #7455)
  • Accessibility: - Invalid role attributes on td/th/tr elements inside a table element (#7568)
  • Accessibility: - Certain date/time text should be text-selectable (#5628)
  • Accessibility: - Improve nav-link aria attributes, give role=link (#7567)
  • Accessibility: - All calendar views now pass Axe accessibility testing with the exception of a false-positive scrollbar error, which has a workaround.
  • Behavior: no more console.warn on unknown options

Sizing & Scrollbars#

  • Feature: Improved responsiveness where text-size and date-formatting collapse when a day’s width goes below dayNarrowWidth
  • Feature: Removed the .updateSize() method. No need to call it after the page’s dimensions have been programmatically changed. All sizing/positioning of events and views will stay updated automatically.
  • Bugfix: Layout does not resize to new container width after browser resizing (#6407)
  • Bugfix: Dynamic calendar width doesn’t adjust (#5507)
  • Bugfix: Adjust calendar sizing when scrollbar width changes (or (de)activated) (#5561)
  • Bugfix: Don’t show MacOS/iOS hovering scrollbars in timeline header/left (#5180)
  • Bugfix: Disable hovering scrollbars in header/resourceArea (#6894)
  • Bugfix: Unnecessary scrollbars in day headers (#6047)
  • Breaking: windowResize event removed, no longer fires. To adjust your dimensions in response to the calendar’s dimensions changing, use ResizeObserver.
  • Breaking: handleWindowResize setting removed. Controlled if windowResize should fire.
  • Breaking: windowResizeDelay setting removed. Controlled how often windowResize should fire.
  • Breaking: stickyHeaderDates renamed to tableHeaderSticky
  • Breaking: stickyFooterScrollbar renamed to footerScrollbarSticky
  • Breaking: tableHeaderSticky (formerly stickyHeaderDates) no longer applies to list-view day-headers. Those are now unconditionally sticky, depending on the theme.
  • Feature: possible to target specific nav-links in the UI (more info)
  • Breaking: navLinkClassNames renamed to navLinkClass, accepts only a simple string
  • Feature: new class-name settings moreLinkInnerClass
  • Feature: view-specific more-link class-name hooks: columnMoreLink* (TimeGrid) and rowMoreLink* (DayGrid/Timeline)
  • Feature: more data in moreLink* hooks (ex: numericText, longText, isNarrow)
  • Breaking: moreLinkClassNames was renamed to moreLinkClass (simple string). See More-Link Render Hooks.
  • Breaking: dayPopoverFormat was renamed to popoverFormat.
  • Accessibility: Improve +more link popover-like aria attributes (#7567)
  • Accessibility: Tabbable popover close button (#7157)
  • Accessibility: Navigate popover items with keyboard (#6624)

Week number#

  • Breaking: The generic weekNumber* settings have been replaced with view-specific names: DayGrid uses inlineWeekNumber*, and TimeGrid uses weekNumberHeader*.
  • Bugfix: date given to week-number hooks was never zoned. Similar to dayHeaderContent ticket (in “Staging”) but for weekNumberContent.

All-Day#

  • Breaking: The generic allDay* settings have been replaced with UI-specific names: TimeGrid uses allDayHeader*. (In List view, all-day text now uses list event* hooks.)

Time Slots#

  • Feature: new class-name slotHeaderInnerClass
  • Feature: new class-name slotHeaderRowClass for the row containing slot headers (slot header row render hooks)
  • Feature: slotHeader* hooks (previously slotLabel* hooks) have more data (ex: isMajor, isNarrow, etc)
  • Feature: slotLane* hooks have more data (ex: isMajor, isMinor)
  • Breaking: slot “label” settings were renamed to slot “header”: slotLabelClassNames -> slotHeaderClass, slotLabelContent -> slotHeaderContent, slotLabelDidMount -> slotHeaderDidMount, and slotLabelWillUnmount -> slotHeaderWillUnmount (see Slot Header Render Hooks). Class-names must be simple strings.
  • Breaking: slotLabelInterval was renamed to slotHeaderInterval
  • Breaking: slotLabelFormat was renamed to slotHeaderFormat
  • Breaking: slotLaneClassNames was renamed to slotLaneClass (simple string), and slotLaneContent was removed (no replacement). See Slot Lane Render Hooks.

Now-Indicator#

  • Feature: new class-name nowIndicatorDotClass for “dot” next to their now indicator line (dot render hooks)
  • Breaking: in v6, the nowIndicator* settings represented BOTH the “arrow”, which appeared in the time axis, and the “line”, which appeared over a day. One would differentiate based on info.isAxis (now removed). In v7, there are distinct settings for each (header, line, and dot)

Misc Background Fills#

  • Feature: styling hook for date-span highlight (highlightClass) (highlight render hooks)
  • Feature: styling hook for non-business-hours (nonBusinessHoursClass) (business hours render hooks)
  • Feature: styling hook for space-filling element (fillerClass) (filler render hooks). Used in all-day section to offset scrollbar width in timed section. Used in Resource Timeline view when resource-rows don’t fill entire height.
  • Accessibility: Add aria-current="date" for “today” highlight (#7502)

DayGrid View#

  • Feature: dayCellFormat for controlling number in cell
  • Feature: Improved responsiveness where text-size and date-formatting collapse when a day’s width goes below dayNarrowWidth
  • Feature: eventSlicing setting, which controls whether DayGrid can can put fragments of multi-day events with +more links. Defaults to true (same behavior as v6).
  • Feature: More class-name styling hooks (ex: dayHeaderDividerClass, dayCellTopClass, etc) (see Day Header Render Hooks, Day Header Row Render Hooks, Day Header Divider Render Hooks, Day Row Render Hooks, Day Cell Render Hooks)
  • Feature: new row-level class-name hooks for day-grid structure (dayHeaderRowClass, dayRowClass)
  • Feature: More data given to dayCell* hooks (ex: .isMajor, .isNarrow, etc)
  • Feature: More data given to inlineWeekNumber* hooks: (ex: .textParts, .isNarrow, etc)
  • Bugfix: “More” button (events) on smartphones not responsive (#2991)
  • Bugfix: Day number in day cells are hidden by vertical scrollbar (#6798)
  • Bugfix: Better dayGrid row height, height:'auto', and +more link behavior (#6033)
  • Bugfix: Day cells are not always equal height with calendar height:'auto' (#5762)
  • Bugfix: Events not rendered when container is resized (#7555)
  • Bugfix: Events overflow below day cell with dayMaxEvents:true and showNonCurrentDates:false (#6749)
  • Bugfix: Events times are cutoff with eventDisplay:'block' when there is not enough space for the title (#6457)
  • Bugfix: Compressed space between events in dayGrid when month-start title (#7184)
  • Bugfix: resourceDayGrid-views with no resources shows blank resource row (#7377)
  • Bugfix & Breaking-API: The moreLinkClick date was always UTC, not adjusted by timezone plugins (#7314). It now stays consistent with the current timeZone setting.
  • Breaking-Visual: When height:'auto', day cells now maintain aspectRatio whereas prior, they maintained a min-height of about 3.5em (#7900)
  • Breaking-Visual: Disabled days (via validRange) now display text in DayGrid header cells. Still no content within body cells.
  • Breaking-Visual: The weekNumbers:true setting no longer displays week numbers in dayGridDay view, dayGridWeek view, or any dayGrid-based view with only one row
  • Accessibility: Disabled day cells have broken ARIA references (#7379)
  • Accessibility: Move aria-label/labelledby away from invalid elements to cells (#7566)
  • Print: Event titles should not repeat each day (#6657)
  • Breaking: single-row dayGrid (like dayGridWeek) no longer shows month-numbers. week/multi-day views in timegrid/daygrid will have “Sun 8” header by default, instead of “Sun 8/5” header (no more month number. just day-of-month)
  • Breaking: dayHeaderClassNames was renamed to dayHeaderClass (simple string). Horizontal alignment now uses dayHeaderAlign instead of CSS text-align. See Day Header Render Hooks.
  • Behavior: The dayHeader* settings now apply to the popover header, which is usually desirable. See Popover CSS migration docs.
  • Breaking: dayCellClassNames was renamed to dayCellClass (simple string), and dayCellContent was renamed to dayCellTopContent. See Day Cell Render Hooks.
  • Behavior: The dayCell* settings now apply to the popover body, which is usually desirable. See Popover CSS migration docs.
  • Breaking: The dayCell* settings previously applied to TimeGrid Day Lane, but no longer.
  • Breaking: Week numbers in DayGrid were renamed from weekNumber* (inside views.dayGrid) to top-level “inline week numbers” / inlineWeekNumber* settings. Class-name settings must be simple strings.

Resource DayGrid View#

  • Feature: new class-name setting resourceDayHeaderInnerClass
  • Feature: more data given to resourceDayHeader* (formerly resourceLabel*) hooks (ex: .isToday, .isPast, etc)
  • Breaking: “Resource labels”, as they render in DayGrid and TimeGrid, are now called “resource day headers”. You can configure them as top-level settings, and class-name settings must be simple strings

TimeGrid View#

See the DayGrid View section for subcomponents of the All-Day section.

  • Feature: Improved responsiveness where text-size and date-formatting collapse when a day’s width goes below dayNarrowWidth
  • Feature: new class-name settings (ex: weekNumberHeaderInnerClass, allDayHeaderInnerClass, etc)
  • Feature: the week-number-heeader hooks (weekNumberHeader*) have more data (ex: .textParts, .isNarrow)
  • Feature: the all-day header hooks (allDayHeader*) have more data (ex: .isNarrow)
  • Feature: the day-lane hooks (dayLane*) have more data (.isNarrow, .isStack, etc)
  • Bugfix: TimeGrid “all-day” text is better aligned, better split across multiple lines
  • Breaking-Visual: Newlines in allDayText will be displayed as line breaks in TimeGrid
  • Breaking-Visual: TimeGrid overlapping events that previously spanned full column width now have a right margin. This was an accidental regression from v5 → v6, and the v5 behavior is restored (#6569)
  • Breaking-Visual: Disabled days (via validRange) now display text in TimeGrid header cells. Still no content within body cells.
  • Breaking-Visual: The “all-day” text now appears capitalized as “All-day”
  • Accessibility: TimeGrid accessibility markup more table-like, puts timed events in single “row” labeled by timedText settin
  • Print: First page blank when multiple pages (#7007)
  • Print: Last event cut-off when multiple pages (#7673)
  • Print: Show all time slot lines (#5465). Note: it was impossible to achieve multi-page breaking in Firefox, so falls back to flat list of events without slot lines.
  • Print: new eventPrintLayout setting to control exact print behavior of stacking versus slots
  • Breaking: Week numbers in TimeGrid were renamed from weekNumber* (inside views.timeGrid) to top-level “week number headers” / weekNumberHeader* settings. Class-name settings must be simple strings.
  • Breaking: The all-day section label in TimeGrid was renamed from allDay* (inside views.timeGrid) to top-level “all day header” / allDayHeader* settings. Class-name settings must be simple strings.
  • Breaking: TimeGrid lane hooks were renamed from dayCell* to dayLane* (dayCellClassNames -> dayLaneClass, dayCellDidMount -> dayLaneDidMount, dayCellWillUnmount -> dayLaneWillUnmount). Lane class-name settings must be simple strings, and dayCellContent was removed (no replacement). See Day Lane Render Hooks.

Resource TimeGrid View#

  • Bugfix: resourceTimeGrid-views with no resources shows blank resource row (#7377)
  • Breaking-Visual: The weekNumbers:true setting no longer displays week numbers in resourceTimeGridDay view, because x-axis header cell alongside resource names is reserved for a future label

List View#

  • Breaking: listDaySideFormat was renamed to listDayAltFormat.
  • Feature: better computed listDayFormat/listDayAltFormat for custom-duration-views. instead of just empty values
  • Feature: more class-name settings (ex: listDayClass, listDayBodyClass, noEventsInnerClass, etc)
  • Feature: more data given to listDayHeader* callbacks (ex: .textParts, .dayNumbrText, etc)
  • Accessibility: List-view weekday navLinks should not have aria-hidden (#7645)
  • Accessibility: List-view accessibility markup less table-like, more list-like. Removed table pseudo-headers and thus removed the eventHint and timeHint locale settings.
  • Accessibility: aria structure done differently, as nest list+listitem, instead of table + colgroups
  • Behavior: list-event time “column” is hardcoded as 165px width
  • Bugfix: List View sticky headers lack bottom border (#7778)
  • Breaking: List-view day header hooks moved from views.list.dayHeader* to top-level listDayHeader* settings (for example, dayHeaderClassNames -> listDayHeaderClass, dayHeaderContent -> listDayHeaderContent). See List Day Header Render Hooks. Class-name settings must be simple strings.
  • Breaking: In List view, all-day event text is no longer customized via generic allDay* hooks. Use list event* hooks instead
  • Breaking: noEventsClassNames has been renamed to noEventsClass, which accepts only a simple string (see no-events render hooks)
  • Breaking-Visual: The “all-day” text on events now appears capitalized as “All-day”

MultiMonth View#

  • Feature: navlinks on single-month title
  • Feature: Improved responsiveness where text-size and date-formatting collapse when a day’s width goes below dayNarrowWidth
  • Feature: more class-name settings for customization (ex: singleMonthClass, singleMonthHeaderClass, etc)
  • Breaking-Visual: The multiMonthMinWidth pixel value now includes the padding within each month tile
  • Performance: MultiMonth performance gain, solving “Forced reflow while executing JavaScript took <#> ms” violation (#7209)
  • Accessbility: Improve MultiMonth title hierarchy via role=list (#7537)
  • Breaking: multiMonthMinWidth and multiMonthTitleFormat are renamed to singleMonthMinWidth and singleMonthTitleFormat
  • Breaking: singleMonthMinWidth (formerly multiMonthMinWidth) now INCLUDES padding

Timeline View#

  • Feature: more formal styling hooks for defining space above and below timeline events
  • Bugfix:: scrollTime slightly off when switching from timeline month to week (5686)
  • Bugfix & Breaking-API: The moreLinkClick date is always UTC, not adjusted by timezone plugins (#7314). It now stays consistent with the current timeZone setting.
  • Print: Show all time slot lines (#6636, #6802)

Resource Timeline View#

  • Feature: Virtual rendering for rows and columns, for calendars with a large number of resources. Opt in with virtualization: true (#5673, #6478)
  • Feature: In Resource Timeline view, a high-level resourceColumnHeader* cell (previously resourceAreaHeader*) above columns now stays fixed during horizontal scrolling (#7779)
  • Breaking: resourceAreaWidth was renamed to resourceColumnsWidth
  • Feature: If resourceColumnsWidth or resourceColumns[].width specified as percentage, will persist as percentage after user-resize
  • Feature: more class-name hooks (ex: resourceHeaderRowClass, resourceRowClass, etc)
  • Bugfix: Resource rows don’t adjust height to fit resourceLaneContent (#6103)
  • Bugfix: Resource rows don’t render with correct height (#6082)
  • Bugfix: Resource-Timeline scrolls down when it shouldn’t, attempting to preserve scroll state (#4443)
  • Print: Resource rows no longer break across pages
  • Print: Resource-area columns shrink-to-fit based on percentage, saving more space for timeline
  • Print: Print-view limited to 1000 resources, to prevent browser’s print dialog from crashing
  • Breaking: resourceAreaColumns is renamed to resourceColumns, and related *ClassNames hooks are now *Class string settings
  • Breaking: In v6, the resourceGroupLabel* settings where used to style both row-grouping group headers AS WELL AS column-grouping cells, without any way to distinguish the two from the callbacks themselves. In v7, there are two separate entities for each (resourceGroupHeader* and the generic resourceCell*). Also, .groupValue is killed
  • Breaking: resourceLabel* has been replaced by generalized resourceCell* hooks. If you only want the title cell, branch on info.field === 'title'
  • Breaking: resourceLaneClassNames is renamed to resourceLaneClass (simple string only), and resourceLaneContent is split into resourceLaneTopContent and resourceLaneBottomContent (resource lane render hooks)
  • Breaking: resourceGroupLaneClassNames is renamed to resourceGroupLaneClass (simple string only), and group data now uses fieldValue instead of groupValue (resource group lane render hooks)

Custom Views#

Custom view “via settings”#

  • Breaking: In custom view definitions, .classNames (array) is replaced by .className (single string). More info
  • Breaking: The buttonText setting no longer respected. Instead, add to the buttons map. More info

Custom view “via JS”#

  • Breaking: If using via “plugin”, read in other section how createPlugin not used anymore

Luxon Plugin#

  • Breaking: Luxon 1 package removed (@fullcalendar/luxon)
  • Breaking: Luxon 2 package removed (@fullcalendar/luxon2)
  • Breaking: Luxon 3 package removed (@fullcalendar/luxon3)
    • Temporal used instead for time zone resolution (more info)
    • Formatting and format-string functionality moved to @fullcalendar/format-luxon3 (docs)
    • Conversion utilities removed (toLuxonDateTime and toLuxonDuration)

Moment Plugins#

  • Breaking: moment package removed (@fullcalendar/moment)
    • Date formatting-string functionality moved to @fullcalendar/format-moment plugin (docs)
    • Date conversion utilities (toMoment and toMomentDuration) removed
  • Breaking: moment-timezone support removed (@fullcalendar/moment-timezone) because time zone resolution is now built-in to FullCalendar via the temporal-polyfill peer dependency (more info).

iCalendar Plugin#

Updates to the @fullcalendar/icalendar plugin:

  • Breaking: Your must upgrade the ical.js peerDependency to v2 (#7734)

Custom Plugins#

  • Breaking: the createPlugin function no longer necessary to prepare a plugin. Just pass-in the object

Time Zone#

  • Feature: the timeZone setting can be a named time zone (like "America/New_York") without needing a third-party connector plugin. All dates displayed throughout the UI will respect the current named timeZone. Dates emitted throughout the API will still be legacy Date objects but you are encouraged to use Temporal to interact with them.

Temporal#

The temporal-polyfill package is now a peer dependency of all the FullCalendar packages. This means you are required to install it.

The “Temporal” built-in browser API is coming to all modern browsers, and this package is a polyfill for it, which means it allows you to use it before it’s officially supported.

FullCalendar DOES NOT INSTALL IT GLOBALLY but instead uses it internally. For v7, FullCalendar uses the tree-shakeable API, meaning the code-size impact will be minimal and there will be no side-effects.

Though FullCalendar does not install the polyfill globally, you are welcome to do so for your projects:

import 'temporal-polyfill/global'

Date Navigation#

  • Breaking: in v6, the validRange callback would receive the exact now date and update unpredictably. In v7, it receives the start-of-day of the “now” date, and is re-called whenever the day changes over.

Date Formatting#

  • Feature: date-formatting settings that accept Intl object now accept three additional non-standard properties: weekdayJustify, forceCommas, and omitTrailing (date formatting docs)
  • Feature: No longer internally implements formatRange-related functionality. Relies on standard Intl API.
  • Feature: New extended date formatting option that removes trailing punctuation and whitespace
  • Breaking: Subtle differences in range-formatting output. For example v6 would output "10:00 AM – 11:00 AM" whereas v7 outputs "10:00 – 11:00AM" (removes space & redundant “am”)
  • Breaking: defaultRangeSeparator settings removed. Range separator is now determined by the Intl API.

Locales#

  • Feature: For hint-generating functions (like prevUnit, formerly buttonHints.prev), the first arg is a humanized unit string like “Semana” (week in Spanish), which is hard to work with programmatically, but now there is a SECOND arg which is normalized in singular english units, like “week”.
  • Breaking: Shape of locale data changed (more info)
  • Breaking: Changes in week text settings: weekText -> weekTextShort (ex: "W").

Interactions#

  • Breaking: removed fixedMirrorParent setting, which would allow developers to attach dragged “mirror” elements to an element other than the calendar root element. Now, dragged mirror elements are always attached to the <body> (or shadow-root in the case of web-component).

Distribution#

  • Breaking: All packages distributed as ESM modules ONLY. No longer distributed as CJS. If you’re on Node 22.12+ or 23+, require('fullcalendar') continues to work unchanged — Node now loads ESM packages from CJS code transparently. Only projects on Node 20 or older must explicitly migrate their code to ESM. Read more about ESM for Jest.
  • Breaking: The vanilla JS NPM package fullcalendar (formerly @fullcalendar/core) no longer provides global.min.js files. However, JSDelivr will still respect the .min.js extension and auto-minify it.
  • Internal-Only: Embedded Preact (applies to all but React and Preact packages), upgraded to 10.29.1 to take advantage of flushSync.

Premium License#

While the STANDARD FullCalendar packages have been, and always will be, licensed under the permissive MIT license, the PREMIUM packages have more complex licensing:

Application TypeCompany TypeLicense
Closed-sourceFor-profitCustom commercial license
Closed-sourceNot-for-profitCreative Commons non-commercial license
Open-sourceFor-profitv6: GPLv3 → v7: AGPLv3
Open-sourceNot-for-profitv6: GPLv3 → v7: AGPLv3

In v7, AGPLv3 is replacing GPLv3 as the copyleft license used for open-source projects. If your project’s frontend and backend are open-source and AGPLv3-compliant, use the following license key:

schedulerLicenseKey: 'AGPL-My-Frontend-And-Backend-Are-Open-Source'

We’ve discovered a few instances of for-profit companies using FullCalendar Premium in closed-source projects, claiming to be GPLv3-compliant via the SaaS loophole. By switching to AGPLv3, we are closing this loophole and forcing such companies to either purchase a commercial license or stay on v6.

If you are the author of a GPL’d SaaS project that uses FullCalendar Premium and are concerned that you cannot upgrade to v7 due to the license change, please consider the benefits of switching to AGPLv3 yourself.