Noureddine RAMDI / Luna: a self-hosted Go calendar aggregator unifying CalDav, iCal, and Google Calendar

Created Mon, 04 May 2026 10:23:02 +0000 Modified Sat, 23 May 2026 20:41:27 +0000

Opisek/luna

Luna tackles a common pain point in calendar management: juggling multiple protocols and calendar services, each with their own quirks and APIs. Instead of switching between apps or dealing with inconsistent views, Luna unifies CalDav, iCal, and Google Calendar data behind one customizable web interface. It’s a solo developer’s effort written in Go, aiming for a 1.0 release that balances protocol normalization, user management, and frontend theming.

How Luna unifies diverse calendar protocols under a single web interface

At its core, Luna is a self-hosted calendar aggregator written in Go. The project’s primary goal is to normalize multiple calendar sources — CalDav servers, iCal feeds, and Google Calendar APIs — into a single, consistent data model that feeds a customizable web frontend.

The architecture reflects this challenge. Luna acts as a backend service that connects to each calendar type using their respective protocols. It then abstracts away their differences to expose a unified event model. This is non-trivial since CalDav, iCal, and Google Calendar differ in authentication, event representation, and capabilities.

On top of this, Luna provides user management, letting multiple users configure and view their own aggregated calendars securely. The frontend is written with customization in mind — it supports built-in and user-installable themes and fonts to tailor the UI experience.

The stack is straightforward and pragmatic: Go for backend and API logic, serving a web frontend that users interact with through their browsers. The project is designed to be self-hosted, avoiding reliance on third-party cloud calendar aggregators.

The normalization layer and theming system: Luna’s technical strengths and tradeoffs

What sets Luna apart technically is its protocol normalization layer. Instead of treating each calendar source as a separate silo, it translates CalDav, iCal, and Google Calendar events into a unified internal representation. This simplifies frontend rendering and user experience, as the UI deals with one consistent event model.

This abstraction is challenging because each protocol has subtle differences, especially around recurring events, timezones, and event metadata. Luna currently lacks full support for recurring events, which is a notable limitation for production use, as recurring meetings are a staple of calendar workflows.

The codebase reflects a careful balance between flexibility and complexity. User management is baked in, which adds another layer of infrastructure beyond just calendar fetching. The theming system is surprisingly comprehensive for an open-source solo project; it supports multiple themes and fonts, with facilities for users to install their own, enhancing the UX.

One tradeoff is the frontend’s lack of mobile responsiveness at this stage. This limits usability for users who rely on smartphones. Also, being a solo project, some edge cases and protocol quirks may not be fully handled yet, which is expected with early-stage software.

Overall, the code is clean and idiomatic Go. The repo structure suggests clear separation of concerns: protocol adapters, user management, frontend assets, and API routes are logically organized.

Explore the project: navigating Luna’s code and documentation

The Luna repository contains a detailed README with high-level overviews and links to deployment and security guides. While there are no explicit installation commands in the README extract provided, the project points to a Deployment Guide for setup instructions and a Security & Privacy document outlining compromise analyses.

Here’s how you can explore the repo effectively:

  • Start with the README to understand the overall architecture and goals.
  • Dive into the internal directory where protocol adapters for CalDav, iCal, and Google Calendar likely live. This is where normalization happens.
  • Check out the user management code to see how authentication and multi-user support are implemented.
  • Look at the frontend or web assets folder to explore theming and UI customization.
  • Review the API documentation linked in the README to understand how the frontend communicates with the backend.

Even without quickstart commands, the repo provides a good foundation for anyone wanting to self-host a unified calendar frontend or contribute to the protocol normalization code.

Verdict: who should consider using Luna today?

Luna is relevant for privacy-conscious users or small teams who want to aggregate calendars from multiple protocols without relying on external cloud services. Its self-hosted nature gives control over data and customization.

However, it’s important to note its current limitations: incomplete recurring event support and no mobile-responsive UI make it less suitable for heavy daily use or users dependent on smartphones.

The project is a solid technical foundation and a worthwhile exploration for Go developers interested in calendar protocols or building unified frontends. It’s also a nice example of how to architect a normalization layer for disparate APIs.

If you need a production-ready, full-featured calendar aggregator today, commercial or more mature open-source alternatives might be preferable. But if you want to experiment, self-host, and contribute to a growing Go project tackling a tough integration problem, Luna is a good candidate.


→ GitHub Repo: Opisek/luna ⭐ 361 · Go