Skip to content

AvengeMedia/dankcalendar

Repository files navigation

DankCalendar

DankCalendar

Local, Google, Microsoft, CalDAV, and iCloud calendars in one standalone app

Built with Quickshell and Go

GitHub stars GitHub License AUR version (bin) AUR version (git) Discord Ko-Fi donate

DankCalendar is a standalone calendar app that brings your Local, Google, Microsoft, CalDAV, and iCloud calendars together in one place. It runs as a lightweight daemon with a tray icon, keeps your accounts in sync, and reminds you about events — all with the look and feel of DankMaterialShell.

Repository Structure

This is a monorepo containing both the calendar interface and the core backend services:

dankcalendar/
├── quickshell/         # QML-based calendar interface
│   ├── Modules/        # UI components (calendar views, sidebar, tray)
│   ├── Modals/         # Settings, account, event, and search dialogs
│   ├── Services/       # IPC bridge and shell-side state
│   ├── Widgets/        # Calendar-specific Dank UI controls
│   ├── Common/         # Shared resources, themes, and i18n
│   ├── DankCommon/     # → symlink into the dank-qml-common submodule
│   └── translations/   # POEditor-managed string catalogs
├── dank-qml-common/    # Shared DMS widget library (git submodule)
├── core/               # Go backend, daemon, and CLI
│   ├── cmd/dcal/       # dcal CLI and daemon entrypoint
│   ├── internal/       # Providers, sync engine, reminders, IPC, OAuth
│   ├── api/            # HUMA + chi HTTP API
│   ├── ent/            # Ent ORM schema and generated code
│   └── repo/           # Repository-pattern data access
├── assets/             # Icons, desktop entry, systemd unit
└── Makefile            # Build, install, and dev targets

See it in Action

Installation

Arch Linux (AUR)

# Prebuilt binary
yay -S dankcalendar-bin

# Build from latest git
yay -S dankcalendar-git

From Source

git clone --recurse-submodules https://github.com/AvengeMedia/dankcalendar.git
cd dankcalendar
sudo make install

Already cloned without submodules? Run git submodule update --init first — the shared widget library (dank-qml-common) is vendored as a submodule and the build fails without it.

This installs:

  • dcal binary to /usr/local/bin (the Quickshell UI is embedded in the binary)
  • Desktop entry + icon

Override the prefix with PREFIX=/usr sudo make install.

At launch the embedded UI is unpacked read-only into the session runtime dir ($XDG_RUNTIME_DIR/dankcal-shell/, tmpfs) and verified against the binary on every start, so editing the unpacked files has no effect. To run a modified copy of the UI, point dcal at any directory containing a shell.qml with dcal -c <dir> or the DANKCAL_SHELL_DIR environment variable — there is no implicit filesystem lookup otherwise.

Optional session service (starts the daemon at login, restarts on failure):

make install-systemd
systemctl --user enable --now dcal

You can also toggle Start at login from Settings → General, which manages an XDG autostart entry that launches dcal run -d --hidden.

Requirements

  • Quickshell (qs)
  • Qt 6 declarative (including Qt.labs.platform for the tray icon)
  • Go 1.25+ (build only — the binary is pure Go, no CGO)

Features

Multiple Providers Connect Local, Google, Microsoft, CalDAV, and iCloud accounts and view every calendar in a single unified agenda.

Background Sync A lightweight daemon keeps your accounts in sync and serves the UI over IPC. Closing the window only hides it — sync and reminders keep running.

Event Reminders Native desktop notifications for upcoming events, with per-event and per-calendar reminder configuration.

Tray Integration A system tray icon to show, hide, and quit the app, plus quick access to upcoming events.

Secure Credentials OAuth tokens and account secrets are stored in your system keyring, never in plaintext.

Keyboard Navigation Full keyboard-driven navigation with a shortcuts overlay, plus spotlight-style search across your events.

Localized User-facing strings are translatable and managed through POEditor.

Usage

dcal           # launch, or show/focus the window if already running
dcal show      # same as above
dcal show --view day   # open (or focus) directly on a view: month|week|day|agenda
dcal toggle    # toggle window visibility
dcal run       # run in the foreground (logs to the terminal)
dcal run -d    # run as a background daemon
dcal restart   # restart the running shell
dcal kill      # stop everything

Closing the window only hides it — the daemon and tray icon keep running. Reopen from the tray icon, the desktop entry, or dcal show. Quit entirely from the tray menu or dcal kill.

Manage accounts and sync from the command line:

dcal account list                 # list connected accounts
dcal account add local ~/cal      # add a local calendar directory
dcal account add caldav           # add a CalDAV / iCloud account
dcal account setup google         # OAuth setup for Google
dcal account setup microsoft      # OAuth setup for Microsoft
dcal account remove <account-id>  # remove an account
dcal sync [account-id]            # force a sync
dcal reminders                    # list upcoming reminders

IPC

The daemon exposes a scriptable IPC surface — handy for keybinds and automation:

dcal ipc ui.toggle
dcal ipc ui.show
dcal ipc ui.show view=day          # open on a specific view: month|week|day|agenda
dcal ipc ui.openEvent uid=<uid>    # open a specific event's details window
dcal ipc events.list from=2026-06-01 to=2026-06-30
dcal ipc accounts.list
dcal ipc reminders.upcoming
dcal ipc system.autostart

Development

git submodule update --init   # once after clone (or clone with --recurse-submodules)

make run            # build and run against the in-repo quickshell config
make test           # run the Go test suite
make fmt            # format Go code
make update-common  # bump the dank-qml-common submodule + nix flake input together

Shared widgets (quickshell/DankCommon/) live in the dank-qml-common submodule — edit them in place, they hot-reload like any other QML, but they are committed and PR'd in that repo. See CONTRIBUTING for the workflow.

Tip: Run with hot reload to pick up QML changes without restarting:

# from core/
DCAL_ENABLE_HOTRELOAD=1 go run ./cmd/dcal run -c ../quickshell

Install prek and activate the hooks:

prek install

The hooks run gofmt -s, go vet, go mod tidy, and the Go test suite for changes under core/, plus generic whitespace/YAML checks.

See CONTRIBUTING.md for editor setup, the i18n workflow, and Go style guidelines.

Contributing

Contributions welcome. Bug fixes, widgets, features, providers, and translations all help.

  1. Fork the repository
  2. Make your changes
  3. Test thoroughly (make test)
  4. Open a pull request

Include screenshots or video in your PR when the change is user-facing.

Credits

License

MIT License - See LICENSE for details.

Releases

Packages

Contributors

Languages