npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@neo-reckoning/ical

v0.1.0

Published

iCal (.ics) parser and generator for @neo-reckoning/core. Converts VEVENT data to DateRange[] and back.

Readme

@neo-reckoning/ical

iCal (.ics) parser and generator for @neo-reckoning/core. Converts VEVENT data to DateRange[] and back.

This package parses .ics calendar data into neo-reckoning DateRange[], preserves recurrence structure when possible, and generates valid .ics output from those ranges.

What this does

  • Parse VEVENT data — convert all-day events, timed events, spans, recurrence rules, and exceptions into DateRange[]
  • Generate .ics output — export DateRange[] back to VCALENDAR / VEVENT form
  • Preserve recurrence structure — directly map simple RRULE patterns into native neo-reckoning recurrence fields
  • Expand complex rules when needed — fall back to explicit date expansion for recurrence patterns that do not fit the native model
  • Work in browser and Node — built on ical.js, which runs in both environments

Install

npm install @neo-reckoning/ical

Quick start

import { detectDataWindow, generateICS, parseICS } from '@neo-reckoning/ical';

const window = {
  from: new Date('2026-03-01T00:00:00'),
  to: new Date('2026-03-31T00:00:00'),
};

const ranges = parseICS(icsText, window);
const detected = detectDataWindow(icsText);
const ics = generateICS(ranges, { calendarName: 'Roundtrip' });

API

parseICS(icsText, window)

Parses .ics text into DateRange[] within a time window.

  • Single-day, timed, and multi-day VEVENTs become native neo-reckoning ranges
  • Simple RRULEs map directly to recurrence fields like everyWeekday, everyDate, and everyMonth
  • Complex RRULEs are expanded to explicit dates within the requested window
  • EXDATE values become exceptDates

generateICS(ranges, options?)

Exports DateRange[] back to .ics format.

  • Writes a valid VCALENDAR wrapper
  • Generates VEVENT entries for single events, spans, and supported recurrence patterns
  • Preserves timezones, EXDATE values, and optional calendar metadata such as calendarName

detectDataWindow(icsText)

Performs a lightweight regex scan of raw .ics text to find where the actual calendar data lives.

  • Scans VEVENT DTSTART, DTEND, and UNTIL values
  • Ignores unrelated timezone blocks
  • Returns a padded { from, to } window or null if no event dates are present

Two-tier RRULE handling

Neo-reckoning has its own native recurrence model, but .ics RRULEs are broader. This package handles them in two tiers:

  • Tier 1: direct mapping — simple RRULEs are converted into native DateRange recurrence fields so they stay compact and editable.
  • Tier 2: expansion — complex RRULEs are expanded with the rrule library into explicit dates within the requested parse window.

Tier 2 is used for patterns like ordinal weekdays (BYDAY=2TU), non-daily INTERVAL > 1, and other RRULE parts that do not map cleanly onto the native model.

Supported patterns

| RRULE pattern | DateRange mapping | Notes | |---|---|---| | FREQ=DAILY | everyWeekday: [0, 1, 2, 3, 4, 5, 6] | Daily recurrence across all weekdays | | FREQ=WEEKLY;BYDAY=... | everyWeekday | If BYDAY is omitted, the DTSTART weekday is used | | FREQ=MONTHLY;BYMONTHDAY=... | everyDate | If BYMONTHDAY is omitted, the DTSTART day-of-month is used | | FREQ=YEARLY;BYMONTH=... | everyMonth | If BYMONTH is omitted, the DTSTART month is used | | UNTIL or COUNT | fromDate, toDate, fixedBetween | Bounds the recurrence window | | EXDATE | exceptDates | Applied to both mapped and expanded recurrences |

Patterns outside those mappings fall back to Tier 2 expansion inside the requested parse window.

Round-trip

parseICS() followed by generateICS() preserves the parsed DateRange structure for supported data. That means ranges can be imported from .ics, manipulated in neo-reckoning form, then exported back without flattening simple recurrence into one-off events.

This is a structural round-trip, not a byte-for-byte source preservation guarantee.

Browser-first design

This package uses ical.js, which works in browsers and Node. That keeps the parser and generator usable in frontend apps, React Native, workers, Node services, and MCP servers without separate platform-specific implementations.

License

MIT