Open-source project
Kozea/Radicale avatar
Kozea/Radicale

Radicale: a CalDAV and CardDAV server that stores everything as files

A simple CalDAV (calendar) and CardDAV (contact) server.

5,069 stars530 forksPythonGPL-3.0

At a glance

What is it?
Radicale is a Python CalDAV and CardDAV server that keeps calendars and contacts as plain files on disk. It is small enough to run from a single Docker container, and the trade-off is that you own the storage, the auth and the backups.
Who is it for?
Adopt Radicale if you want CalDAV and CardDAV served from your own machine with data in a folder you can copy, and if you are comfortable managing authentication and backups yourself. Do not adopt it if you need a web calendar UI, shared team scheduling or hosted support, because the project is a sync server and not a groupware suite.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Radicale is, and the problem it removes

Radicale is a CalDAV and CardDAV server. CalDAV is the protocol calendar clients use to read and write events, to-do lists and journal entries; CardDAV is the same idea for contacts, which Radicale stores as vCards. The README describes it as sharing "calendars and contact lists through CalDAV, CardDAV and HTTP".

The problem it removes is the database. Most self-hosted groupware stacks put calendars inside a relational database, behind a web application, behind a reverse proxy. Radicale skips all three. The README states it "Stores all data on the file system in a simple folder structure." That one sentence is the whole design argument. A calendar is a directory. An event is a file. Backup is a copy, migration is a move, and inspecting a broken sync is opening a text editor.

The audience follows from that. It is for people who already run a mail server or a NAS and want their phone and desktop clients pointed at their own machine. It is also for small groups: the repository ships a rights file and a SHARING.md document, so per-collection access control is part of the intended use, not an afterthought.

How the server is put together

The repository layout tells most of the story. The radicale/ package holds the server, config/ holds the default configuration, rights holds the default access rules, and radicale.wsgi is the WSGI entry point for running it behind a web server. There is a Dockerfile, a Dockerfile.dev and a compose.yaml, plus caldav_compat_tests/ and integ_tests/ for protocol-level testing.

The data flow is deliberately thin. A client sends an HTTP request using CalDAV or CardDAV verbs (PROPFIND, REPORT, PUT, DELETE). Radicale authenticates the request, checks it against the rights rules, and then reads or writes a file in the storage directory. There is no cache layer and no second copy of the truth. The pyproject.toml dependency list is short: defusedxml, libpass, vobject, pika and requests. vobject handles iCalendar and vCard parsing, libpass handles password hashing, defusedxml guards XML parsing, and pika is an AMQP client, which points at optional event hooks rather than core storage.

That architecture has a direct consequence. Anything the file system cannot express, Radicale does not do either. There is no scheduling engine, no free/busy negotiation between users, and no server-side search index beyond what the protocol requires. The project's own classifiers call it "Office/Business :: Groupware", but the mechanism is a file-backed WebDAV server, and it should be judged as one.

Installing Radicale and pointing a client at it

The package is on PyPI as Radicale and requires Python 3.9 or newer. The optional extras named in pyproject.toml are bcrypt, argon2, ldap, pam and test. A plain install gives you the server and libpass for password hashing, but not bcrypt or argon2.

The Dockerfile shows how the project builds its own image: it installs the package from a source archive with the extra named by the DEPENDENCIES build argument, whose default is bcrypt.

dockerfile
ARG VERSION=master
ARG DEPENDENCIES=bcrypt
RUN apk add --no-cache --virtual .build-deps gcc libffi-dev musl-dev rust cargo \
    && python -m venv /app/venv \
    && /app/venv/bin/pip install --no-cache-dir "Radicale[${DEPENDENCIES}] @ https://github.com/Kozea/Radicale/archive/${VERSION}.tar.gz"

The shorter route is the compose.yaml in the repository. It uses the image ghcr.io/kozea/radicale:stable, maps port 5232, and bind-mounts ./config and ./data into the container.

yaml
services:
    radicale:
        image: ghcr.io/kozea/radicale:stable
        ports:
        - 5232:5232
        volumes:
          - config:/etc/radicale
          - data:/var/lib/radicale

After that, the server answers on port 5232. Add a calendar in your client with the URL http://your-host:5232/ and the credentials you configured. The README does not document a default login, so there is nothing to guess: you set authentication yourself before exposing the service. For a first real use, create a collection, put one event in it, and confirm that a file appears under the data directory. If the file is there and the client shows the event, the whole stack is working end to end.

Authentication, TLS and the parts you supply

Radicale can "limit access by authentication" and "secure connections with TLS", per the README, but it does not ship either one configured. The config file in the repository is the starting point, and the auth backends are optional dependencies: bcrypt and argon2 for password hashing, ldap for directory-backed logins, pam for system accounts. If you install the base package and enable an auth type whose library is missing, the server will not start.

This is the sharpest edge in the project. A default install with no auth and no TLS is fine on localhost and unacceptable on a public interface, and nothing in the install step stops you from exposing it. The rights file is equally load-bearing: it decides which collections a user can read or write, and the README does not walk through a worked example of tightening it.

TLS is normally terminated in front of Radicale rather than inside it. The Dockerfile installs openssl and ca-certificates, so certificates can be handled in the container, but the repository's compose.yaml publishes plain port 5232 with no TLS configuration at all. Treat the compose file as a development convenience, not a deployment recipe.

Where Radicale is the wrong tool

Radicale stores files. That is the feature and the limitation. Concurrent writes from several clients to the same collection are resolved by whatever the file system and the storage layer do, and the README does not describe conflict resolution or versioning. If two people edit the same shared event at the same moment, you should not expect a merge.

There is no web interface for calendars. A user who wants to click a date and type an event is not served by this project; they need a client. There is no built-in user management UI, no invitation flow, and no resource booking. The documentation is a separate DOCUMENTATION.md plus the site at radicale.org, and the README points at a wiki, issues and discussions for everything else, which means the answers to operational questions are spread across four places.

Finally, the file-backed model assumes a local file system. Put the data directory on a network share with weak locking and you have moved the risk from the server to the storage layer without the server knowing. If your environment needs multi-writer consistency guarantees, Radicale is the wrong shape of tool.

Radicale compared with Baïkal and DAViCal

The two comparisons people search for are Baïkal and DAViCal, and the difference is storage. Radicale keeps calendars and contacts as files in a folder structure, per the README. Baïkal and DAViCal are PHP projects that store their data in a database, typically SQLite or MySQL.

The practical split: a database gives you transactional writes, a query layer and a web admin interface, at the cost of a database to install, back up and upgrade. Files give you a data directory you can rsync, diff and read, at the cost of giving up those database guarantees. Radicale's install reflects its side of that trade: a Python package and a handful of dependencies, or one container. It does not require a database server at all.

There is also a language and packaging difference that matters for maintenance. Radicale is Python, distributed on PyPI, with a published Docker image and a WSGI entry point. That fits teams already running Python services. The PHP alternatives fit teams already running a PHP web stack. Neither is better in the abstract; the deciding question is which runtime you already patch on a schedule.

Maintenance, licensing and what an upgrade costs

Radicale is GPL-3.0 licensed, stated in the README and in pyproject.toml as "GNU GPL v3". That matters if you plan to modify the server and distribute it, because the GPL's copyleft terms attach to distributed derivatives. Running it as a service for yourself or inside your organisation is a different situation from shipping a modified build to customers, and the licence text, not this article, is what governs that. If you fork it, keep the source available and keep the notices intact.

The project is not archived and the last push was on 2026-09-22, one day before this was written, so development is current. Releases are frequent and small: v3.8.0 on 2026-09-03, v3.7.8 on 2026-08-06, v3.7.7 on 2026-07-19. The changelog is the file to read before upgrading, because the release titles mix features, fixes and "Adjutments", and the version in pyproject.toml is already 3.8.1.dev.

Upgrade cost is low by design. There is no schema migration step, since there is no schema. The real work is checking that your config keys and rights rules still behave after a release, and that optional dependencies such as libpass, which pyproject.toml pins at >=1.9.3, resolve cleanly. The maintenance burden you carry is not the code, it is the storage: backups, permissions on the data directory, and the auth backend you chose.

Editorial conclusion

Adopt Radicale if you want CalDAV and CardDAV served from your own machine with data in a folder you can copy, and if you are comfortable managing authentication and backups yourself. Do not adopt it if you need a web calendar UI, shared team scheduling or hosted support, because the project is a sync server and not a groupware suite. Before migrating, verify three things: that your client completes a PROPFIND against the URL you configure, that your chosen auth backend is installed (the base install only pulls libpass), and that a restore from a copy of the data directory actually works.

Frequently asked questions

What is Radicale?

Radicale is a CalDAV and CardDAV server written in Python. It shares calendars, to-do lists, journal entries and contacts over CalDAV, CardDAV and HTTP, and stores all data on the file system in a folder structure.

What port does Radicale use?

The Docker image and the compose.yaml in the repository use port 5232. The Dockerfile's default command binds the server to 0.0.0.0:5232 and [::]:5232.

How do I install Radicale?

Install the Radicale package from PyPI with pip, which requires Python 3.9 or newer, or run the container image ghcr.io/kozea/radicale:stable with the provided compose.yaml. Optional extras such as bcrypt, argon2, ldap and pam are installed separately.

What are the alternatives to Radicale?

Baïkal and DAViCal are the closest alternatives, and both keep their data in a database rather than a folder of files. Radicale's difference is that it needs no database server and its data directory can be copied directly.

Can Radicale sync with Google Calendar?

The repository does not document a Google Calendar integration. Radicale exposes CalDAV and CardDAV endpoints, so syncing depends on whether the client you use supports pointing at a custom CalDAV URL.

How do I set up Radicale?

Start from the config file in the repository and the compose.yaml, which bind-mounts ./config to /etc/radicale and ./data to /var/lib/radicale. Authentication is not configured for you, so choose an auth backend from the optional dependencies before exposing the service.

Official sources

  1. Kozea/Radicale on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kozea-radicale.svg)](https://hysenlabs.com/projects/kozea-radicale)