UniCalendar
approvedby yinshaohua
A unified calendar view syncing events from Google Calendar, CalDAV, and ICS feeds into one beautiful interface. - This plugin has not been manually reviewed by Obsidian staff.
UniCalendar
A unified calendar view for Obsidian that aggregates events from Google Calendar, CalDAV servers, and ICS feeds into a single month view — with Chinese lunar calendar, solar terms, and public holiday annotations.

Features
- Unified month view — see all your calendar sources in one place, color-coded by source
- Google Calendar sync — OAuth 2.0 PKCE flow, no server required; supports multiple calendars per account
- CalDAV sync — connect to Nextcloud, iCloud, Fastmail, or any CalDAV-compatible server
- ICS feed sync — subscribe to any public or private
.icsURL - Chinese lunar calendar — lunar dates, traditional festivals (春节, 端午, 中秋…), and 24 solar terms displayed in each cell
- Public holiday overlay — statutory holidays and adjusted workdays (补班) sourced from holiday-cn
- Event deduplication — events shared across sources are shown once, with configurable source priority. Additional same-source deduplication removes duplicate instances when a provider returns the same occurrence more than once; if duplicates share the same source, start time, and overlapping normalized titles (exact match or one title containing the other), UniCalendar keeps the richer copy (for example the one with location, description, or meeting link metadata)
- Auto-sync — configurable sync interval (default 30 minutes); manual sync available via command palette
- Mobile compatible — works on iOS and Android (
isDesktopOnly: false)
Installation
From Obsidian community plugins (recommended)
- Open Settings → Community plugins → Browse
- Search for UniCalendar
- Select Install, then Enable
Manual installation
- Download
main.js,manifest.json, andstyles.cssfrom the latest release - Copy the three files to
<Vault>/.obsidian/plugins/uni-calendar/ - Reload Obsidian and enable the plugin in Settings → Community plugins
Configuration
Open Settings → UniCalendar to configure calendar sources.
Add a Google Calendar source
- Select Add source → Google Calendar
- Enter your Google OAuth client ID and client secret (see Google Cloud Console)
- Choose a Google proxy mode if your network needs help reaching Google OAuth and Calendar API endpoints
- Select Authorize — a browser window opens for the OAuth flow
- After authorization, select which calendars to include
Google proxy modes
UniCalendar supports three Google proxy modes:
- System proxy — uses Obsidian/Electron networking. This is the default and respects the proxy behavior provided by the app/runtime.
- No proxy — sends Google requests directly from the desktop plugin process. Use this when a system proxy interferes with Google requests.
- Custom proxy — connects through a local or LAN HTTP proxy with
hostandport, for example127.0.0.1and7897.
Custom proxy mode is for standard HTTP CONNECT proxies. UniCalendar opens a CONNECT tunnel to Google, upgrades it to TLS, and then sends the original Google OAuth token and Calendar API requests through that tunnel. It is not a forwarding endpoint and does not use a target= query parameter.
The legacy Google proxy address field is kept only for older saved data migration. New saves store proxyMode, proxyHost, and proxyPort, and clear the old proxyUrl value.
Add a CalDAV source
- Select Add source → CalDAV
- Enter the server URL, username, and password
- Select Discover calendars to list available calendars
For Feishu/Lark CalDAV performance notes and troubleshooting, see Feishu CalDAV diagnostics.
Add an ICS feed
- Select Add source → ICS feed
- Paste the ICS URL
- Optionally set a display name and color
Other settings
| Setting | Default | Description |
|---|---|---|
| Sync interval | 15 min | How often to auto-sync all sources |
| Show lunar calendar | On | Display lunar dates and festivals in month cells |
| Show holidays | On | Overlay public holiday and workday annotations |
| Month overflow mode | Expand | How to handle cells with more events than fit |
Event title filters
Use Settings → UniCalendar → Event title filters to hide noisy events across all calendar sources without deleting the underlying event data.
Each rule supports two modes:
- Hide when title exactly matches — useful for suppressing one recurring event name only
- Hide when title contains the string — useful for suppressing classes of events by keyword
Examples:
- Input
WaytoAGI晚8点共学with exact match hides only events whose title is exactlyWaytoAGI晚8点共学 - Input
WaytoAGIwith contains hides any event whose title containsWaytoAGI
Matching is case-insensitive and ignores leading/trailing or repeated whitespace.
Usage
- Select the calendar icon in the ribbon to open the calendar view
- Use the command palette (
Ctrl/Cmd+P) and search for Open calendar - Navigate months with the
<and>arrows in the view header - Select any event to see its full details
Privacy
UniCalendar operates entirely locally. Calendar credentials are stored in your vault's plugin data file (<Vault>/.obsidian/plugins/uni-calendar/data.json). No data is sent to any third-party service other than the calendar providers you explicitly configure. Holiday data is fetched from the jsdelivr CDN on first load and cached locally.
Development
UniCalendar is an Obsidian community plugin. The TypeScript entry point is main.ts, bundled by esbuild into root-level main.js, which Obsidian loads together with manifest.json and optional styles.css.
Project structure
src/
main.ts # Plugin lifecycle, command/view registration
lunar/ # Lunar calendar, solar terms, and holiday services
models/ # Shared domain types
settings/ # Settings tab and configuration UI
store/ # Event storage, filtering, and deduplication
sync/ # Google, CalDAV, and ICS sync adapters
views/ # Calendar view and event detail modal
tests/ # Vitest test suites and Obsidian mocks
.planning/ # Version-controlled GSD Core plans and history
Keep src/main.ts small and place feature logic in focused modules under src/.
Project planning uses GSD Core. Its project context, requirements, roadmap, phase plans, summaries, and milestone archive are version controlled under .planning/. The local .gsd/ directory is retained only as a legacy migration source and is not used for new planning work.
Environment
Install dependencies into the project-local node_modules/ directory from the repository root. No PowerShell Profile function or external dependency directory is required:
npm install
Common commands
# Install dependencies.
npm install
# Watch mode, auto-recompile on save.
npm run dev
# Production build.
npm run build
# Run tests.
npm test
# Lint.
npm run lint
Manual testing
Copy main.js, manifest.json, and styles.css to <Vault>/.obsidian/plugins/uni-calendar/, then reload Obsidian and enable the plugin in Settings → Community plugins.
Manifest and releases
- Keep
manifest.jsonfields accurate, includingid,name,version,minAppVersion,description, andisDesktopOnly. - Treat
manifest.jsonidas stable after release. - When bumping a release version, update both
manifest.jsonandversions.json. - GitHub release tags should exactly match the manifest version, without a leading
v. - Attach
manifest.json,main.js, andstyles.cssas individual release assets.
Plugin guidelines
- Default to local/offline operation and document any network access clearly.
- Do not add hidden telemetry, ads, remote-code execution, or custom auto-update behavior.
- Use stable command IDs for user-facing commands.
- Keep mobile compatibility in mind because
isDesktopOnlyisfalse. - Register events, DOM listeners, and intervals through Obsidian cleanup helpers so unload is safe.
License
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.