Xandikos: a CalDAV and CardDAV server that keeps your data in Git
A CalDAV/CardDAV server backed by Git
At a glance
- What is it?
- Xandikos is a Python CalDAV and CardDAV server that stores principals, calendars and address books as a Git repository, which turns backups, history and inspection into git operations. CalDAV and CardDAV are fully implemented, scheduling works between principals on one server, and multi-user support is still described as experimental.
- Who is it for?
- Adopt Xandikos if you want to host your own calendar and contacts server, you value that your data lives in a Git repository you can inspect and back up with ordinary git tools, and your users are all on one server. Do not adopt it for cross-organisation scheduling, since the README states that CalDAV scheduling works end to end when every attendee is a principal on the same Xandikos server, and treat multi-user deployments as experimental.
- 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 last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Calendars and address books as a Git repository
Xandikos is described as a lightweight yet complete CardDAV and CalDAV server that backs onto a Git repository, and the Git part is the architecture rather than a feature bolted on. The server exposes the CalDAV and CardDAV protocols to clients, and behind it everything is stored in a Git repository, using Dulwich as the Git implementation rather than shelling out to the git binary. The consequences show up in how you operate it. A backup of your calendar data becomes a git push, a history of changes becomes git log, and an accidental deletion can be inspected with the same tools you use for code. The project also keeps a benchmark directory and a Makefile target that runs it, which tells you the performance of the storage layer is treated as something to measure rather than assume. The name is a curiosity that the README explains, taken from the March month in the ancient Macedonian calendar.
CalDAV and CardDAV are complete, the rest is uneven
The README keeps a standards table, and reading it carefully is the fastest way to know what you can rely on. CalDAV, RFC 4791, and CardDAV, RFC 6352, are both fully implemented, as are Current Principal, RFC 5397, POST to create members, Extended MKCOL, Collection Synchronization for WebDAV, Calendar Availability and the CalDAV Scheduling Extensions. Core WebDAV is implemented except for LOCK operations, with COPY and MOVE implemented for non-collections. Versioning Extensions is only partially implemented, limited to the REPORT method and the expand-property property, and Access Control is partial as well. CalDAV Time Zone Extensions is partial, with calendar-timezone-id supported but no timezone service provided. Three standards are not implemented at all: WebDAV Quota, WebDAV Mount, which the README says is intentionally not implemented, and iCAL CAP. The full compliance picture is in notes/dav-compliance.rst.
Scheduling only closes the loop inside one server
The scheduling section is the clearest statement of scope. CalDAV scheduling, RFC 6638, works end to end when every attendee is a principal on the same Xandikos server. In that case an organizer's PUT and DELETE are turned into iTIP REQUEST, CANCEL and REPLY messages, delivered into the attendees inboxes and auto-applied to their default calendars, and the attendees' RSVPs flow back into the organizer's stored event. The README also notes that ATTENDEE entries on the organizer's stored event are annotated with a SCHEDULE-STATUS parameter recording the delivery outcome, which is a detail you would otherwise have to reverse engineer from a client's view. The limitation follows directly: for remote attendees, you are outside the model and need the mail based path instead.
Outbound iMIP is off unless you switch it on
The mail based path is the iMIP protocol, and the default is deliberately conservative. Outbound iMIP for remote attendees is off by default, and you enable it with --imip-send=sendmail to pipe through a local sendmail-compatible binary, or --imip-send=smtp with --smtp-host and --smtp-port, optionally --smtp-encryption=starttls or ssl, --smtp-user and --smtp-password-file. The --smtp-from switch sets the From: header, and the originating organiser or attendee goes into Reply-To:. Every switch has a matching XANDIKOS_ environment variable, such as XANDIKOS_IMIP_SEND, XANDIKOS_SMTP_HOST and XANDIKOS_SMTP_FROM, which is how you configure the same behaviour in the container. Inbound iMIP arrives through the xandikos import-imip subcommand, typically piped from a Dovecot Sieve rule, and for deployments that prefer to deliver from the MTA directly, xandikos serve with an imip-listen option exposes an LMTP endpoint that stores messages in the configured principal's schedule inbox.
Standards testing is scripted into the Makefile
The compatibility work is visible in the repository, in a compat/ directory of shell scripts and in a set of Makefile targets. The check target runs the unittest suite, and there are separate targets for vdirsyncer, litmus, pycaldav and the CalDAV server tester, with check-all chaining the unit tests, vdirsyncer, litmus, pycaldav and the style check together:
check-all: check check-vdirsyncer check-litmus check-pycaldav styleThe litmus target runs a shell script with a set of suites, and there are coverage variants of the same targets that run the server under coverage. Style is checked with ruff and typing with mypy, both pinned in the optional dependency groups of pyproject.toml. This matters for a protocol server, because interoperability is the actual failure mode: the litmus, pycaldav and server tester suites are how you find out that a client you care about breaks with a change. The Makefile also has a container target that builds with buildah and pushes to ghcr.io/jelmer/xandikos, and a benchmark target that runs pytest against the bench directory.
The container image takes a handful of environment variables
A Containerfile is provided and the image is regularly built and published at ghcr.io/jelmer/xandikos, with a v$RELEASE tag for every release, for example v0.2.11 for release 0.2.11. Configuration is by environment variable rather than by a config file, and the documented set is short. PORT is the port to listen on, default 8000, METRICS_PORT is the metrics endpoint port, default 8001, LISTEN_ADDRESS is the bind address, default 0.0.0.0, DATA_DIR is the data directory path, default /data, and CURRENT_USER_PRINCIPAL sets the user principal path. The examples directory shows how this is meant to be deployed in practice, with a docker-compose example, systemd unit and socket files, uWSGI configuration, nginx configuration, a Kubernetes manifest, a service monitor manifest and an ingress manifest, plus a Grafana dashboard JSON file in the repository root. The optional dependency extras in pyproject.toml line up with the features, with prometheus for metrics, systemd_python for the systemd integration, qrcode for QR codes, aiosmtpd for the iMIP listener, pywebpush and py-vapid for WebDAV Push, and bcrypt for htpasswd authentication.
Multi-user support is experimental, and the client list is long
The Limitations section of the README is one line and it is the one to read first: multi-user support is experimental. Everything else in the project is mature, the standards table is detailed, the test matrix is scripted and the release history shows steady work, with v0.4.7 on 2026-09-18, v0.4.8 on 2026-09-30 and v0.4.10 on 2026-10-17, and the last push on 2026-10-17. The client support list is the practical guide to what will work, and it lists vdirsyncer, caldavzap and carddavmate, Evolution, DAVx5, the sogo connector for Thunderbird, aCALdav for Android, pycardsyncer, akonadi, CalDAV-Sync and CardDAV-Sync, Calendarsync, Tasks, AgendaV, CardBook, Apple devices, the Home Assistant CalDAV integration, pimsync, davcli, Thunderbird and KashCal. The licence is GPL v3 or later, and the project is developed by Jelmer Vernooij as a long running personal effort.
Editorial conclusion
Adopt Xandikos if you want to host your own calendar and contacts server, you value that your data lives in a Git repository you can inspect and back up with ordinary git tools, and your users are all on one server. Do not adopt it for cross-organisation scheduling, since the README states that CalDAV scheduling works end to end when every attendee is a principal on the same Xandikos server, and treat multi-user deployments as experimental. Verify first that your clients are on the supported list, which includes vdirsyncer, DAVx5, Thunderbird, Evolution, Apple devices and the Home Assistant CalDAV integration, decide whether you need outbound iMIP for remote attendees, which is off by default, and note that WebDAV quota and WebDAV mount are not implemented at all.
Frequently asked questions
What is Xandikos and what does the Git backend do?
Xandikos is a lightweight CalDAV and CardDAV server that stores its data in a Git repository, using Dulwich as the Git implementation. The Git repository means your calendars and address books can be inspected, versioned and backed up with ordinary git tooling.
Which WebDAV standards does Xandikos implement?
CalDAV, CardDAV, Current Principal, POST to create members, Extended MKCOL, Collection Synchronization, Calendar Availability and CalDAV Scheduling are fully implemented. Core WebDAV is implemented without LOCK, Versioning Extensions and Access Control are partial, and WebDAV Quota, WebDAV Mount and iCAL CAP are not implemented.
Does CalDAV scheduling work with attendees outside my server?
Not end to end. The README says CalDAV scheduling works end to end when every attendee is a principal on the same Xandikos server, with organiser changes turned into iTIP messages and RSVPs flowing back. For remote attendees you need outbound iMIP, which is off by default and enabled with --imip-send.
How do I install Xandikos and its dependencies?
Xandikos needs Python 3.10 or later, and on Debian the dependencies can be installed with apt for dulwich, defusedxml, icalendar and jinja2. The package itself is installed with pip, and a container image is published at ghcr.io/jelmer/xandikos with a v$RELEASE tag per release.
Is multi-user support ready for production in Xandikos?
The README lists multi-user support as experimental, so treat shared deployments with care. It is also worth noting that WebDAV quota and WebDAV mount are not implemented, and that the project documents the clients it has been tested with, including vdirsyncer, DAVx5, Thunderbird and the Home Assistant CalDAV integration.
Official sources
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.
[](https://hysenlabs.com/projects/jelmer-xandikos)Was this useful?