TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
An easy, private, local web calendar with CalDAV sync. Your data on your terms.
ProductivityTypeScript · CSSGitHub @Ivan-MalinovskiOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
A beautiful CalDAV client for the web
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
A lightweight CalDAV calendar for the web.
Calino is a local-first, browser-based calendar client that connects to your calendar services. No Calino account is required: the app is a static page, stores its working data locally, and syncs with the CalDAV/CardDAV servers you configure. Optional webcal feeds, CORS proxies, AI photo extraction, map links, and hosted fonts are separate network integrations.
If you've been looking for a beautiful, modern browser-based CalDAV calendar that doesn't come as part of a bloated suite, Calino has you covered.Read the full README ↗A lightweight CalDAV calendar for the web.
Calino is a local-first, browser-based calendar client that connects to your calendar services. No Calino account is required: the app is a static page, stores its working data locally, and syncs with the CalDAV/CardDAV or JMAP servers you configure. Optional webcal feeds, CORS proxies, AI photo extraction, map links, and hosted fonts are separate network integrations.
If you've been looking for a beautiful, modern browser-based CalDAV calendar that doesn't come as part of a bloated suite, Calino has you covered.
Try it now at calino.io — the hosted version, nothing to install. Prefer to run your own? Self-hosting instructions are below.
Active project: Calino is under active development. New features and improvements ship regularly — please report bugs, they're more than welcome!
Calino also supports JMAP for calendars and contacts. There is nothing to pick: type your server and credentials, and Calino detects whether it speaks JMAP or CalDAV (servers that offer both, such as Stalwart, use JMAP). Calendars, events, recurrence, reminders, attendees and invitations, free/busy, contacts, offline editing and live updates work the same as with CalDAV. Tasks and journals need a JMAP tasks capability, which Stalwart doesn't offer yet, so those stay CalDAV-only there. If you'd rather use CalDAV on a server that offers both, tick Use CalDAV under Connection settings. JMAP Calendars is still an Internet-Draft; Calino is verified against Stalwart, and other servers may differ. Details, limits and how to test are in docs/JMAP.md.
Due to the browser-based nature of Calino, a web CalDAV/CardDAV/JMAP server must allow requests from your Calino origin with CORS headers. If that's not an option, you can use a proxy URL during setup; Calino provides https://proxy.calino.io as a convenience.
With a proxy, requests pass through the proxy operator, so use your own proxy or configure CORS directly when that matters. The hosted proxy sees connection metadata and request URLs, but is designed not to log credentials or calendar bodies. See docs/CORS_PROXY.md for the hosted proxy's limits and self-hosting options.
Using Pangolin, Cloudflare Access, or a similar gateway in front of your server? See docs/AUTH_GATEWAY.md for the headers and CORS preflight setup.
Like Calino in your browser? There's a native, standalone Android app too: Ivan-Malinovski/calino-android. It's built from scratch in Kotlin and Jetpack Compose, with no WebView.
This repository also builds a Capacitor-wrapped Android app with OS-level reminders, background calendar mirroring, and optional BYOK AI photo extraction. The AI provider receives the image and prompt when you choose to use that feature. Find the latest APK in the GitHub Releases page.
I have made it as close as possible, as to what I envision the perfect CalDAV non-enterprise calendar to be, according to my own tastes. I'm simply sharing it with the world. The design philosophy is to have sensible and automatic default settings, that adjust according to your browser and calendar, so that you can use it from any client, without needing further customization.
Cmd/Ctrl+K for the command palette — navigate, create events, sync, search, settings from the same textboxRRULE + per-occurrence completion, no vendor properties), so they interoperate with Thunderbird and other CalDAV clients. See docs/RECURRING_TASKS.md for the wire format and a per-client interop tableService-Worker-Allowed: /..css file into public/themes/ and rebuilding the app (themes are loaded at build time, not at runtime).docs/CALINOSETTINGSSYNC.md for details.An Android APK is published on the GitHub Releases page — it is not distributed via Google Play. Because it is sideloaded, Android may ask you to allow installs from your browser or file manager.
For notification reminders to actually fire reliably, some phone makers (Xiaomi/MIUI especially, also Oppo, Realme, Honor, OnePlus, and others) aggressively kill background apps to save battery, which silently breaks scheduled reminders. Check dontkillmyapp.com for your device and set Calino's battery/power mode to "No restrictions" or equivalent.
/setup), which derives the key from a password that stays on the device.docs/DOCKER.md./setup wizard — no Node.js required. See docs/SELF_HOSTED_CONFIG.mdmailto: invite. On JMAP accounts Calino asks the server to send invitations, updates and cancellations (verified between local Stalwart users; delivery to outside addresses depends on the server's mail setup). Calino has no screen for incoming invitations or replying to them yetpnpm install
pnpm dev
Open http://localhost:5173. The Vite dev server is intended for development; use the production build or Docker for a deployment.
The fastest way to self-host. Pre-built multi-arch images (amd64 + arm64) are on GHCR:
docker run -d -p 8080:8080 ghcr.io/ivan-malinovski/calino:latest
Tip:
:latestand:mainpoint to the latest stable release published from a version tag. Pin a version tag without the leadingv(for example:0.30.0) when you need a fixed image.
Or clone and customize:
git clone https://github.com/Ivan-Malinovski/calino.git
cd calino
docker compose up -d
Calino runs at http://localhost:8080 by default.
To customize settings (site URL, offline support), create a .env file — see docs/DOCKER.md for full details.
Preconfigure CalDAV accounts: Visit /setup in any running Calino instance to generate a config file with encrypted credentials. Place it in the project root and rebuild — users will be prompted for a master password instead of entering server details manually. See docs/SELF_HOSTED_CONFIG.md for details.
Calino is a static React app — host it anywhere that serves HTML/JS.
pnpm builddist/ folder (make sure SPA fallback is configured — see below)Most user data, including CalDAV account metadata and credentials, lives in the browser's localStorage; large raw ICS documents, attachments, and contact photos use IndexedDB. There is no backend or central Calino application server.
For a private-network deployment that must connect directly to a plain-HTTP
CalDAV server, build with CALINO_SELF_HOSTED=true pnpm build. The DAV server
must allow the Calino origin through CORS. HTTP transmits credentials and
calendar data without encryption, and an HTTPS-hosted Calino may still be
blocked by the browser's mixed-content policy; see
docs/DOCKER.md.
Config (in-app): Click the gear icon or use Cmd/Ctrl+K → "Settings" → add your CalDAV server URL, username, and password.
Site URL (for SEO / Open Graph cards):
cp .env.example .env.local
# Edit .env.local and set VITE_SITE_URL=https://your-domain.com
pnpm build
VITE_SITE_URL is baked into index.html at build time and used for the canonical link, Open Graph / Twitter cards, and the JSON-LD structured-data block.
Calino is a Vite SPA. Any static host works as long as it rewrites all unknown paths to /index.html (so client-side routes like /week and /day resolve on refresh).
GitHub Pages — the repository workflow deploys the project site for the
upstream repository. For a fork, update the workflow's VITE_SITE_URL and
the Vite base path if you are deploying under a project subpath, enable
Settings → Pages → Source: GitHub Actions, then push to main. A custom
domain or a host that serves the app at / does not need a subpath base.
Caddy (example):
yourcaldav.server.com {
@cors method OPTIONS
handle @cors {
header {
Access-Control-Allow-Origin "*" # or your selfhosted Calino instance URL
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PROPFIND, PROPPATCH, REPORT, OPTIONS, MKCOL, MKCALENDAR, COPY, MOVE"
Access-Control-Allow-Headers "Authorization, Content-Type, Depth, Prefer, If-None-Match, If-Match"
Access-Control-Expose-Headers "ETag"
}
respond "" 204
}
header {
Access-Control-Allow-Origin "*"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PROPFIND, PROPPATCH, REPORT, OPTIONS, MKCOL, MKCALENDAR, COPY, MOVE"
Access-Control-Allow-Headers "Authorization, Content-Type, Depth, Prefer, If-None-Match, If-Match"
Access-Control-Expose-Headers "ETag"
-Server
}
reverse_proxy 192.168.1.1:89 # your caldav server IP and port
}
Tip: Replace
*with your Calino origin in production (e.g.https://calendar.example.com) to avoid letting arbitrary sites read your calendar.
Service Worker / Offline Mode: The service worker is disabled by default. To enable offline support, build with CALINO_ENABLE_SW=true and make sure the final host serves /sw.js with Service-Worker-Allowed: /. The service worker caches the app shell; CalDAV synchronization still needs network access. See docs/DOCKER.md for Docker setup.
If adding headers to your CalDAV server:
Access-Control-Allow-Origin: <your-calino-origin>
Access-Control-Allow-Headers: Authorization, Content-Type, Depth, If-Match, If-None-Match
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PROPFIND, PROPPATCH, REPORT, OPTIONS, MKCOL, MKCALENDAR, COPY, MOVE
Access-Control-Expose-Headers: ETag, DAV, Allow
Tip: If something isn't working, don't guess at which header is missing — open Settings → Sync, pick your account and press Diagnose. Calino probes the server check by check and tells you what to change. Note that browsers hide a server's
Access-Control-Allow-*headers from JavaScript, so some verdicts are marked "inferred": they're deduced from how the server behaved rather than read off the wire. ExposingDAVandAllow(above) lets Calino read those two directly.
JMAP servers need the same headers on their API endpoints, not just
/.well-known/jmap; Stalwart answers CORS only on the latter unless Use permissive CORS is enabled (seedocs/JMAP_TESTING.md). AllowPOST, exposeWWW-AuthenticateandRetry-Afteras well, and note that live updates useEventSource, which can't send anAuthorizationheader cross-origin; Calino reads the event stream withfetchinstead.
Note:
MKCOL,COPY, andMOVEare required for settings sync (creating/moving the Calino settings collection). Omitting them still lets calendars load, but settings sync will fail.
Note:
Access-Control-Expose-Headers: ETagis optional but worth setting. Without it the browser hides theETagyour server returns on every write, and Calino has to spend an extra PROPFIND per write to recover it.
If you can't add CORS headers to your CalDAV server, run a tiny proxy yourself. The easiest option is the bundled Docker proxy — enable it alongside Calino with a compose profile:
docker compose --profile proxy up -d
This pulls the published multi-architecture calino-proxy image (and falls
back to the local proxy/ build context if it is unavailable). Then set the
Proxy URL in Calino settings to http://<your-host>:8081. It's a separate,
zero-dependency container that you can also run standalone or as a Cloudflare
Worker. See docs/CORS_PROXY.md for all options.
For an internet-facing proxy, do not leave the defaults open: set both
CALINO_PROXY_ALLOWED_ORIGINS and CALINO_PROXY_ALLOWED_TARGETS to your
Calino origin and CalDAV host(s). Put the proxy behind HTTPS as well. These
restrictions reduce open-relay and SSRF risk; see docs/CORS_PROXY.md.
React 19 + TypeScript + Vite, Zustand v5, tsdav (CalDAV), CardDAV, JMAP (JSCalendar/JSContact), date-fns, chrono-node, @dnd-kit, framer-motion, Fuse.js, ical.js, Vitest, and Playwright.
Calino is largely vibecoded by Claude Opus 4.8, Opus 5 and ChatGPT 5.6 Sol and Luna. Developed and tested against real calendar workflows, and has been used in real life for months. Issues may still arise; bug reports are very welcome. But for good measure, keep backups of your calendars.
MIT