{"id":12734,"library":"ical.js","title":"iCal.js - iCalendar and vCard Parser","description":"ical.js is a JavaScript library designed for parsing and manipulating iCalendar (RFC 5545) and vCard (RFC 6350) data, along with their JSON counterparts jCal (RFC 7265) and jCard (RFC 7095). The library is currently at version 2.2.1 and maintains an active development cycle, regularly releasing updates that include bug fixes, performance improvements, and TypeScript type enhancements. Originally ported from libical with a focus on web compatibility, it provides a robust, dependency-free solution for handling calendar and contact data. A key differentiator is its dual distribution, offering both ES6 modules for modern environments and a transpiled ES5 CommonJS build for broader compatibility, particularly in older browser script tags. It also offers an optional, separate bundle for comprehensive IANA timezone definitions, acknowledging their size and update frequency.","status":"active","version":"2.2.1","language":"javascript","source_language":"en","source_url":"https://github.com/kewisch/ical.js","tags":["javascript","calendar","iCalendar","jCal","vCard","jCard","parser","typescript"],"install":[{"cmd":"npm install ical.js","lang":"bash","label":"npm"},{"cmd":"yarn add ical.js","lang":"bash","label":"yarn"},{"cmd":"pnpm add ical.js","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Since v2.0.0, the primary `ical.js` bundle is an ES6 module. CommonJS `require()` is not directly supported without transpilation or using the `ical.es5.cjs` distribution.","wrong":"const ICAL = require('ical.js');","symbol":"ICAL","correct":"import ICAL from 'ical.js';"},{"note":"Core classes like `Component` and `Event` are available as named exports directly from the main package, or can be accessed via `ICAL.Component` after a default import.","wrong":"import Component from 'ical.js/Component';","symbol":"Component","correct":"import { Component } from 'ical.js';"},{"note":"The `Time` class is used for handling iCalendar date and time objects, often in conjunction with `ICAL.Event` recurrence rules.","wrong":"import Time from 'ical.js/Time';","symbol":"Time","correct":"import { Time } from 'ical.js';"},{"note":"TypeScript types are available since v2.1.0, enabling better type checking and IDE support for the library's classes and interfaces.","symbol":"Types","correct":"import type { Component, Event, Time } from 'ical.js';"}],"quickstart":{"code":"import ICAL from \"ical.js\";\n\nasync function parseAndDisplayCalendar() {\n  const icsData = `BEGIN:VCALENDAR\\nVERSION:2.0\\nPRODID:-//Example Corp//NONSGML My Calendar//EN\\nCALSCALE:GREGORIAN\\nBEGIN:VEVENT\\nUID:event1@example.com\\nDTSTAMP:20230101T120000Z\\nDTSTART:20230115T100000Z\\nDTEND:20230115T110000Z\\nSUMMARY:Team Meeting\\nDESCRIPTION:Discuss Q1 planning and objectives.\\nLOCATION:Conference Room A\\nEND:VEVENT\\nBEGIN:VEVENT\\nUID:event2@example.com\\nDTSTAMP:20230101T130000Z\\nDTSTART:20230220T140000Z\\nDURATION:PT1H30M\\nSUMMARY:Project Deadline Review\\nRRULE:FREQ=MONTHLY;COUNT=3\\nEND:VEVENT\\nEND:VCALENDAR`;\n\n  try {\n    const jcalData = ICAL.parse(icsData);\n    const comp = new ICAL.Component(jcalData);\n\n    console.log(\"Calendar events:\");\n    const events = comp.getAllSubcomponents('vevent');\n\n    if (events.length === 0) {\n      console.log(\"No events found.\");\n      return;\n    }\n\n    events.forEach((eventComp, index) => {\n      const event = new ICAL.Event(eventComp);\n      console.log(`\\nEvent ${index + 1}:`);\n      console.log(`  Summary: ${event.summary}`);\n      console.log(`  Location: ${event.location || 'N/A'}`);\n      console.log(`  Start: ${event.startDate.toString()}`);\n\n      if (event.isRecurring()) {\n        console.log(`  (Recurring Event - Rule: ${event.getFirstPropertyValue('rrule') ? event.getFirstPropertyValue('rrule').toString() : 'N/A'})`);\n        const iterator = event.iterator();\n        let occurrences = [];\n        let next;\n        // Get up to 5 occurrences\n        for (let i = 0; i < 5 && (next = iterator.next()); i++) {\n            occurrences.push(new ICAL.Time(next).toString());\n        }\n        if (occurrences.length > 0) {\n            console.log(`  First 5 occurrences: ${occurrences.join(', ')}`);\n        }\n      } else {\n        console.log(`  End: ${event.endDate.toString()}`);\n      }\n    });\n\n  } catch (error) {\n    console.error(\"Error parsing iCalendar data:\", error);\n  }\n}\n\nparseAndDisplayCalendar();\n","lang":"typescript","description":"Demonstrates parsing an iCalendar string, accessing the calendar component, and iterating through its event components to log event summaries, locations, start times, and handle recurring events."},"warnings":[{"fix":"For modern environments (Node.js or browser with build tools), use `import ICAL from 'ical.js';`. For direct browser `<script>` tags or older environments, include the `ical.es5.cjs` bundle (e.g., `https://unpkg.com/ical.js/dist/ical.es5.min.cjs`).","message":"`ical.js` transitioned to ES6 modules in v2.0.0. This change breaks direct CommonJS `require()` usage with the main bundle, requiring module-aware environments or specific ES5 builds.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"For timezone-aware operations, you must explicitly include the separate `ical.timezones.js` bundle. This can be done as an additional script or integrated into your build process to ensure comprehensive timezone data is available.","message":"The main `ical.js` package does not include IANA timezone definitions by default to reduce bundle size. Date calculations and recurrence expansions involving timezones will be inaccurate or incorrect without them.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For modern browsers, use `<script type=\"module\" src=\"https://unpkg.com/ical.js/dist/ical.min.js\"></script>`. For broader compatibility or older environments, use the ES5 CommonJS build: `<script src=\"https://unpkg.com/ical.js/dist/ical.es5.min.cjs\"></script>`.","message":"Direct usage of the `ical.js` ES6 module via a browser `<script>` tag requires the `type=\"module\"` attribute. Failing to include this or attempting to use it in older browser environments will lead to module loading errors.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using `import ICAL from 'ical.js';` in module-aware environments or include the `ical.es5.cjs` bundle for legacy browser script tags.","cause":"Attempting to use `ical.js` (v2.0.0+) in a CommonJS environment with `require()` or directly in a browser without `type=\"module\"` or the ES5 build.","error":"ReferenceError: ICAL is not defined"},{"fix":"Include `ical.timezones.js` in your project for comprehensive IANA timezone support. If issues persist, verify that the iCalendar data itself contains VTIMEZONE components if specific timezones are expected.","cause":"This typically occurs when dealing with recurring events that rely on timezone data, but the `ical.timezones.js` bundle has not been included, or timezone definitions are missing from the ICS file itself.","error":"TypeError: Cannot read properties of undefined (reading 'start') or incorrect recurrence calculations"},{"fix":"Review the iCalendar/vCard string for syntax compliance. Tools like the `ical.js` online validator (`kewisch.github.io/ical.js/validator.html`) can help identify specific parsing issues and correct formatting errors.","cause":"The input iCalendar or vCard string is malformed or contains syntax errors according to RFC specifications (e.g., missing colons, invalid property names, incorrect folding).","error":"ICAL.parse: expected ':' but found '...' at line X"}],"ecosystem":"npm"}