Your Calendar Is Already Plain Text: Own the .ics File the Way You Own Your Notes
An .ics file is UTF-8 text — content lines separated by CRLF — governed by RFC 5545, an IETF standards-track document in force since September 2009 1. Every calendar app on your device already reads it. This post is not "write your calendar in Vim daily" — it is "own your calendar data in a portable format the way you own your notes" 2.
The reveal is quiet. The meeting invite in your inbox is already an .ics attachment your mail client parses on your behalf, over an email-transport protocol also defined at the IETF (RFC 6047, iMIP) 3. The conference schedule you subscribed to last October is one URL serving the same text format. The Fastmail engineers who wrote the JSON successor to iCalendar (RFC 8984, 2021) called the older format "widely deployed" in their own abstract — because it is 4. A folder of .ics files is a calendar the same way a folder of .md files is a note-vault: portable, greppable, editable, and readable by tools that have not been built yet.
What an .ics file actually is
An .ics file is a UTF-8 text stream of "content lines" separated by CRLF sequences, wrapping calendar components 1. RFC 5545 §3.1 puts it in one sentence: "Content lines are delimited by a line break, which is a CRLF sequence (CR character followed by LF character)" 1. No vendor charset, no binary blob, no proprietary framing.
RFC 5545 §3.1.4 pins the character set in one line — "The default charset for an iCalendar stream is UTF-8 as defined in [RFC3629]" 5. That single sentence is what makes the file portable: no vendor gets to invent a framing on top.
The whole vocabulary fits on one whiteboard. §3 of the spec: "All calendar components start with the letter 'V'. For example, 'VEVENT' refers to the event calendar component, 'VTODO' refers to the to-do calendar component, and 'VJOURNAL' refers to the daily journal calendar component" 6. Add VFREEBUSY and you have named every top-level component the spec defines. Everything you have ever received from a calendar app is one of those four bones wrapped inside a VCALENDAR envelope.
The IANA media-type registration in §8.1 is what makes the whole ecosystem interoperable — "Registration of media type text/calendar / Type name: text / Subtype name: calendar" 7. Every mail client attaches invites with that MIME type. Every browser knows how to hand a .ics URL to the calendar app. The registry does not know what vendor made the file, and it does not need to.
The 11-line file the spec teaches you to write
RFC 5545 §3.4 ships the canonical example of an iCalendar object — the shortest file that satisfies the spec, and the shape every richer file is a variation on 8. Copy this into bastille.ics and double-click it; every calendar client on your device will open it as a scheduled event.
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:[email protected]
DTSTAMP:19970610T172345Z
DTSTART:19970714T170000Z
DTEND:19970715T040000Z
SUMMARY:Bastille Day Party
END:VEVENT
END:VCALENDAR
Read it top-to-bottom. BEGIN:VCALENDAR and END:VCALENDAR are the outer envelope. VERSION:2.0 and PRODID are the two required calendar-level properties. Inside sits one VEVENT, whose §3.6.1 grammar is eventc = "BEGIN" ":" "VEVENT" CRLF eventprop *alarmc "END" ":" "VEVENT" CRLF 9. UID is the event's stable identifier — the spec insists it be globally unique so the same event can round-trip through five different servers without duplicating. DTSTAMP is when the record was written; DTSTART and DTEND are the window. SUMMARY is the title you will read on the day.
There is nothing else. Everything else — attendees, reminders, recurrence, geo, category, description — is optional properties inside that VEVENT. The spec is short about it on purpose; the same shape carries an all-day birthday, a video call, and a doctor's appointment.
How to export the calendar you already have
Every mainstream calendar client documents an .ics export as a first-class action. Google Calendar Help says plainly: "When you export your calendar, download an .ics file to your computer" 10. Apple's Calendar user guide says: "You can export an individual calendar's events to a calendar (.ics) file" 11. The export button is the ubiquitous door out.
The five-minute drill turns the calendar you already have into a folder you own. Pick the calendar you rely on today and do this once:
- Export the whole calendar. In Google Calendar's web UI, use Settings → Import & Export → Export to download a ZIP of
.icsfiles, one per calendar 10. In Apple Calendar, right-click a calendar in the sidebar and choose Export → Export…; the file lands wherever you point it 11. In Fastmail, Outlook, and Thunderbird, the operation is one menu item away and the output is the same MIME type. - Move the file next to your notes. Save it under the same top-level folder as your Markdown vault (
~/notes/calendar/2026-work.ics, for example). The whole point of the exercise is that time-shaped data now lives on your disk in the same posture as the rest of your writing. - Open it in your text editor. UTF-8 CRLF text opens fine in any editor; the file will not scare you. Scroll to the first
VEVENT. Read one event. Notice that the fields are the shape of the spec, not the shape of a vendor. - Re-import it into a second calendar app. Google Calendar's Import screen accepts an
.icsfile directly; Apple, Outlook, Fastmail, and Thunderbird all do the same 10. If your export from vendor A round-trips into vendor B, the vendor never owned the data. - Commit the folder.
git initinside the notes directory.git add calendar/. Commit. From this point on the calendar has a history you cangit log, the same way your notes do.
Nothing above required a plugin, a paid tier, or a custom sync bridge — the spec that makes it work is 17 years old and has not been touched by any vendor.
How to subscribe to a calendar folder or URL
The receive-side companion to export is subscribe. RFC 4791 (CalDAV, 2007) defines the HTTP-based publish/subscribe layer on top of RFC 5545; every mainstream calendar client also accepts a plain HTTPS URL serving a static .ics. Sports schedules, class timetables, and open-source release calendars have shipped this way for two decades.
The subscribe drill takes three minutes. In Google Calendar, use Other calendars → + → From URL and paste the HTTPS location of your .ics file. In Apple Calendar, File → New Calendar Subscription…. In Outlook, Add calendar → Subscribe from web. Fastmail, Thunderbird, and Nextcloud expose the same primitive under similar names. Once subscribed, the client re-fetches the URL on its own schedule; edits at the source propagate to every subscriber the next time they poll.
Publishing an .ics at a URL is portable, not private. The URL is public to anyone who has it. There is no authentication, no access control, and no per-viewer redaction unless you put the file behind an auth layer you built or bought — for example, a reverse proxy that requires a token, or a WebDAV/CalDAV server (RFC 4791) that speaks Basic or Bearer auth on top of HTTP. If a subscribe URL leaks, every event on it leaks. Treat a published .ics the same way you would treat a public GitHub Gist: fine for a conference schedule; not fine for a therapist's appointment.
The parts you should not oversell
Two parts of RFC 5545 are famously easier to file than to interoperate on — time zones and recurring events — and pretending otherwise is dishonest. Both are documented in the spec itself; the discipline is to write around them, not through them, and to test the round-trip on a low-stakes event before you trust either.
Time zones are the boot-loader footgun. RFC 5545 handles time zones with a VTIMEZONE component that a VEVENT references by TZID, and a naive export that stamps DTSTART in local wall-clock time without a matching VTIMEZONE block will re-render at the wrong hour when it is re-imported into a client running a different zone 1. If you can, store events in UTC and let the client render locally; when you need a zoned event (a recurring 09:00 stand-up that survives daylight saving), export from a client that emits VTIMEZONE blocks and re-import into one that respects them. Test the round-trip on a low-stakes event first.
Recurring events (RRULE) are famously buggy across implementations. The RRULE property defines recurrence with a grammar that fits in a paragraph of §3.3.10 — FREQ, INTERVAL, BYDAY, BYMONTH, BYSETPOS, UNTIL 12. In the simple cases (weekly on Tuesday, monthly on the 15th) every client renders the same shape. In the compound cases (the second-to-last weekday of every third month, until December) clients disagree quietly, and one calendar's occurrence set will not match another's. If a recurrence pattern is business-critical, keep the source of truth in one client, do not fan out complex RRULE blocks across four vendors, and if you must — read the RRULE back after import to confirm what the receiving client actually stored.
Neither caveat retracts the spine of the piece. The VEVENT bones are portable, the export path is universal, the subscribe primitive works. The two hard edges are exactly the places where "run the round-trip test on a low-stakes event first" replaces "trust the vendor button."
Cross-vendor round-trip: who reads the same file
The table below is not a competitor comparison; it is a consumer matrix. RFC 5545 is the shared substrate, and every row in the table participates in it — the villain of this post is the shape of a calendar trapped inside one vendor's database with no plain-text artifact, not any of the vendors themselves.
| Client | Reads .ics | Exports .ics | Subscribes to .ics URL | Speaks CalDAV (RFC 4791) |
|---|---|---|---|---|
| Google Calendar (web, mobile) | yes | yes (per-calendar; ZIP of .ics) | yes | via third-party or via .ics URL |
| Apple Calendar (macOS, iOS) | yes | yes | yes | native |
| Microsoft Outlook / Outlook.com | yes | yes | yes | Exchange + .ics publish |
| Fastmail Calendar | yes | yes | yes | native |
| Thunderbird (Mozilla) | yes | yes | yes | native |
| Nextcloud Calendar (self-hosted, AGPL-3.0, ~1,150+ stars on GitHub) 13 | yes | yes | yes | native |
| Any text editor (Vim, VS Code, Notepad) | yes (open + edit) | — | — | — |
Two rows deserve a footnote. Fastmail's own engineers wrote the modern JSON calendar spec (RFC 8984); they positioned JSCalendar as an alternative and, over time, successor to iCalendar, and wrote in their motivation section that "the data model should be generally compatible with the iCalendar data format [RFC5545] [RFC7986] and extensions … translation with no loss of semantics should be easy with most common iCalendar files" 14. The successor exists; the substrate is still iCalendar and will be for the horizon that matters. Mozilla's ical.js (MPL-2.0) is the open parser the Thunderbird ecosystem uses, self-described as a "Javascript parser for ics (rfc5545) and vcard (rfc6350) data" 15. When a well-maintained open parser reads a spec verbatim, the spec is not going anywhere.
Why keep a folder of .ics next to your notes
Steph Ango's essay File over app names the durability principle: "Apps are ephemeral, but your files have a chance to last" 16. A calendar exported to .ics is the "file" in Ango's sentence. The calendar UI in front of you today may be re-priced, sunset, or acquired next year. The folder of text on your disk is not.
The pattern is not new. Tero Karvinen — a Haaga-Helia lecturer who wrote Command Line Basics Revisited — argued for the folder-of-plain-text calendar in 2021 under the header "Keep your calendar in a plain text file," extending it to a per-tool convention he called calendar.txt: "Calendar.txt is versionable, supports all operating systems and easily syncs with Android mobile phone" 17. That convention picks a different file shape than RFC 5545 does — a plain flat text log rather than a spec-compliant VEVENT bundle — and it is the right convention for someone who wants to author calendars by hand. The wider convention, and the one that round-trips into every existing calendar client, is .ics.
The claim is narrow. Most of us will not hand-write VEVENT blocks daily. What we will do is keep the export — a ~/notes/calendar/ folder with an .ics per calendar, updated on a cadence that matches how often our calendar changes — so the file is on our disk when the vendor is not. Your notes are already plain Markdown files on your own device. An .ics folder is the same architecture applied to the time-side of the vault.
Frequently Asked Questions
The eight questions below are the ones a reader arrives with when they search for "plain-text calendar," "how do I export my calendar as an ics file," or "is iCal an Apple format." Answers stay short so a language model can lift them; each maps to a section above so you can follow the argument back to the primary source.
How do I keep my calendar as plain-text files I own, alongside my notes?
Export each calendar you rely on to .ics using the vendor's built-in export path (Google, Apple, Outlook, Fastmail, Thunderbird all document one) 10 11. Save the files under the same folder tree as your notes vault — then commit the folder to git. To keep the export current, either re-export on a cadence or point a subscribe URL at a static .ics you edit.
What is an .ics file, exactly?
A UTF-8 text file — content lines separated by CRLF, structured as a VCALENDAR envelope wrapping VEVENT / VTODO / VJOURNAL / VFREEBUSY components, per RFC 5545 (2009) 1 6. The IANA MIME type is text/calendar, registered in §8.1 7. That single specification is what makes every calendar app on your device interoperate on the same file.
Isn't this just "write your calendar in Vim"?
No. This piece is about owning your calendar data in a portable format the way you own your notes — not authoring events by hand every day. The export drill above turns the calendar you already have (Google, Apple, Outlook, Fastmail) into a folder of .ics you own — the daily authoring stays wherever it works for you 2.
How do I export my Google Calendar as an .ics file?
Google Calendar's own help page phrases it verbatim: "When you export your calendar, download an .ics file to your computer" 10. In the web UI, go to Settings → Import & Export → Export; a ZIP downloads containing one .ics file per calendar. Apple, Outlook, Fastmail, Thunderbird, and Nextcloud all expose the equivalent operation under similar names 11.
How do I subscribe to a calendar URL?
Publish a .ics at an HTTPS URL and point each client at it. Google Calendar: Other calendars → From URL. Apple Calendar: File → New Calendar Subscription. Outlook and Fastmail expose the same primitive. The IETF definition of the HTTP-based publish/subscribe layer is RFC 4791 (CalDAV, 2007); the plain .ics-at-a-URL flavor is what the spec makes possible without any extra software.
Is iCal an Apple format?
No. The format is iCalendar — its specification is RFC 5545, edited by B. Desruisseaux of Oracle in September 2009 1. Apple retired its iCal client name in 2012, but the format was never Apple's. RFC 5545's abstract says the format is "independent of any particular calendar service or protocol" 18, and Fastmail's own IETF engineers call it "widely deployed" in the abstract of the JSON successor spec 4.
Can I really write an .ics file by hand?
Yes for a single event or a small file — the spec ships an 11-line canonical example that any editor can produce (§3.4) 8. No if you plan to do it every day for a busy calendar. The honest scope: hand-authoring an .ics is useful for one-off invites, testing, or committing a public event feed to a repo. For the calendar you live inside, the point is portability of the exported file, not manual authoring 2.
What about recurring events and time zones?
The RRULE grammar is §3.3.10; the VTIMEZONE component is §3.6.5 of RFC 5545 12 1. Simple recurrences (weekly on Tuesday) round-trip cleanly across clients; compound recurrences (BYDAY + BYSETPOS + UNTIL) sometimes disagree. Time zones round-trip cleanly when the exporter emits a matching VTIMEZONE block; otherwise the naive local-time export will render at the wrong hour in a client on a different zone. Run the round-trip test on a low-stakes event before you trust either.
Your notes are already plain Markdown files on your own device. An .ics folder is the same architecture applied to the calendar — a shape governed by an IETF standard from 2009 that every calendar app on your device already reads. Export what you have, save it next to your notes, and commit. mnmnote.com lives in your browser — the file, from that point on, is yours.
Footnotes
-
Desruisseaux, B. (Ed.), Oracle. "RFC 5545 — Internet Calendaring and Scheduling Core Object Specification (iCalendar)." IETF Standards Track, September 2009. https://www.rfc-editor.org/rfc/rfc5545. Accessed 2026-07-04. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
MNMNOTE. "Sidecar files are how you add metadata you own." https://blog.mnmnote.com/posts/sidecar-files-are-how-you-add-metadata-you-own. Accessed 2026-07-04. ↩ ↩2 ↩3
-
Melnikov, A. (Ed.), Isode. "RFC 6047 — iCalendar Message-Based Interoperability Protocol (iMIP)." IETF Standards Track, December 2010. https://www.rfc-editor.org/rfc/rfc6047. Accessed 2026-07-04. ↩
-
Jenkins, N.; Stepanek, R. (both Fastmail). "RFC 8984 Abstract — JSCalendar: A JSON Representation of Calendar Data." IETF Standards Track, July 2021. https://www.rfc-editor.org/rfc/rfc8984. Accessed 2026-07-04. ↩ ↩2
-
Desruisseaux, B. (Ed.). "RFC 5545 §3.1.4 — Character Set." IETF, September 2009. https://www.rfc-editor.org/rfc/rfc5545#section-3.1.4. Accessed 2026-07-04. ↩
-
Desruisseaux, B. (Ed.). "RFC 5545 §3 — Conventions." IETF, September 2009. https://www.rfc-editor.org/rfc/rfc5545#section-3. Accessed 2026-07-04. ↩ ↩2
-
Desruisseaux, B. (Ed.). "RFC 5545 §8.1 — iCalendar Media Type Registration." IETF, September 2009. https://www.rfc-editor.org/rfc/rfc5545#section-8.1. Accessed 2026-07-04. Corroborated at https://www.iana.org/assignments/media-types/text/calendar. ↩ ↩2
-
Desruisseaux, B. (Ed.). "RFC 5545 §3.4 — iCalendar Object." IETF, September 2009. https://www.rfc-editor.org/rfc/rfc5545#section-3.4. Accessed 2026-07-04. ↩ ↩2
-
Desruisseaux, B. (Ed.). "RFC 5545 §3.6.1 — Event Component." IETF, September 2009. https://www.rfc-editor.org/rfc/rfc5545#section-3.6.1. Accessed 2026-07-04. ↩
-
Google Calendar Help. "Import events to Google Calendar." Google, undated (live). https://support.google.com/calendar/answer/37118. Accessed 2026-07-04. ↩ ↩2 ↩3 ↩4 ↩5
-
Apple. "Export the calendar as a file — Calendar User Guide for Mac." Apple Support, undated (live). https://support.apple.com/guide/calendar/export-calendars-icl1023/mac. Accessed 2026-07-04. ↩ ↩2 ↩3 ↩4
-
Desruisseaux, B. (Ed.). "RFC 5545 §3.3.10 — Recurrence Rule." IETF, September 2009. https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10. Accessed 2026-07-04. ↩ ↩2
-
Nextcloud. "nextcloud/calendar." GitHub, accessed 2026-07-04. https://github.com/nextcloud/calendar. ↩
-
Jenkins, N.; Stepanek, R. (both Fastmail). "RFC 8984 §1.1 — Motivation, JSCalendar: A JSON Representation of Calendar Data." IETF Standards Track, July 2021. https://www.rfc-editor.org/rfc/rfc8984#section-1.1. Accessed 2026-07-04. ↩
-
Mozilla-comm. "kewisch/ical.js." GitHub, accessed 2026-07-04. https://github.com/kewisch/ical.js. ↩
-
Ango, S. "File over app." stephango.com, 2023-07-01. https://stephango.com/file-over-app. Accessed 2026-07-04. ↩
-
Karvinen, T. "Calendar.txt — Keep your calendar in a plain text file." terokarvinen.com, 2021. https://terokarvinen.com/2021/calendar-txt/. Accessed 2026-07-04. ↩
-
Desruisseaux, B. (Ed.). "RFC 5545 Abstract." IETF, September 2009. https://www.rfc-editor.org/rfc/rfc5545. Accessed 2026-07-04. ↩