How reduanahmadswe/dayonedesktop works
1. Overall shape
DayOne Desktop is a Windows-only Electron app with two user-facing surfaces sharing one local SQLite database: a compact “wallpaper panel” that sits on the desktop behind icons, and a full editor window for managing tasks, calendar, notes, and settings.
2. Process boundary
The architecture is split into an Electron main process under electron/ and a renderer React app under src/. The main process owns app lifecycle, windows, tray, database access, startup behavior, and native Windows integration. The renderer owns all UI and never touches the filesystem or database directly.
3. Renderer structure
The renderer is organized by feature: tasks, calendar, notes, and settings, plus shared widgets used by the wallpaper panel. src/App.tsx routes between the desktop panel and editor shell, while src/layouts/WallpaperLayout.tsx and src/layouts/EditorLayout.tsx define the two primary UI shells.
4. Desktop wallpaper layer
The desktop panel is not a normal floating window. It is attached to the Windows desktop shell using native Win32 interop in electron/native/wallpaper.ts with koffi, so it appears behind desktop icons and remains click-through. This is the key architectural boundary that makes the “today panel on the desktop” behavior possible.
5. Window management
electron/windows/windowManager.ts centralizes creation and control of the editor window and the wallpaper window. It coordinates route loading, visibility, focus behavior, and the “second instance brings editor forward” experience. The tray and IPC window handlers both delegate to this layer.
6. Data layer
Persistence is local-only via Prisma + SQLite. The Prisma schema lives in prisma/schema.prisma, migrations under prisma/migrations, and the runtime database file is stored in the app’s user data directory. The database models cover tasks, categories, notes, events, reminders, and settings.
7. Main-process database initialization
electron/database/init.ts and electron/database/client.ts handle creation and initialization of the SQLite database, including default settings and seed data. The repo also has explicit seed helpers such as seedStudentTasks.ts, plus CLI scripts for inspection and seeding, which indicates the database is a first-class subsystem rather than incidental storage.
8. IPC as the application boundary
All renderer-to-backend traffic goes through typed IPC. electron/preload.ts exposes a window.dayone bridge, and src/services/ipcClient.ts is the renderer-side wrapper. Channel names in electron/ipc/channels.ts separate concerns by domain: tasks, notes, categories, events, settings, wallpaper, and window operations.
9. IPC handlers and state invalidation
The handlers under electron/ipc/handlers/ implement CRUD and app actions in the main process. After mutations, the backend broadcasts data:changed so renderer views can refresh. This means UI state is driven by local DB changes plus explicit invalidation events rather than remote sync or shared memory.
10. Background services
The main process includes several long-lived services: startup registration with Windows, auto-updater support, display/monitor tracking, reminder notifications, wallpaper attach retries, and a watchdog to reattach after shell restarts or sleep. These services make the app behave like a persistent desktop companion rather than a normal single-window app.
11. Tray-centered app control
electron/tray.ts is the main user-control surface when the editor is hidden. It exposes app actions such as opening the editor, showing/hiding the wallpaper, navigating to feature sections, and toggling startup behavior. The close button does not terminate the app; tray state is part of the normal runtime model.
12. Build and packaging pipeline
The project is built with Vite for the renderer, TypeScript for Electron code, Prisma client generation, and electron-builder for NSIS packaging. The build output is split between dist/ for renderer assets and dist-electron/ for main/preload code, with packaged native dependencies such as Prisma’s engine and koffi unpacked so Electron can load them correctly.
13. Development mode differences
Development uses the Vite dev server plus Electron launch scripts, but the wallpaper injection path is intentionally disabled in dev. That means the true desktop-layer behavior is only exercised in installed production builds, which is an important distinction when diagramming runtime behavior versus development behavior.
14. Key end-to-end flows
The main architectural flow is: renderer UI action → preload bridge → IPC handler → Prisma/SQLite update → data:changed broadcast → renderer refresh. The desktop-specific flow adds another path: main process boot → wallpaper attach service → native Win32 desktop parenting → always-visible today panel. These two flows define the repo’s core behavior.
Main entry points: main.ts Main entry · index.ts IPC handlers · App.tsx App shell · ipcClient.ts IPC client
Components 22
Electron main
App lifecycle, windows, IPC, native integration, and local services.
- Main entry · Starts the Electron app and wires together main-process subsystems.
electron/main.ts - Window manager · Creates and coordinates editor and wallpaper windows, focus, route loading, and instance behavior.
electron/windows/windowManager.ts - Tray control · System tray actions for opening the app, toggling surfaces, and startup behavior.
electron/tray.ts - IPC handlers · Typed application actions for tasks, notes, events, reminders, settings, wallpaper, and window ops.
electron/ipc/handlers/index.ts - Channel map · Shared channel names that define renderer-to-main boundaries by domain.
electron/ipc/channels.ts - Preload bridge · Exposes the window.dayone API to the renderer as the only backend entrypoint.
electron/preload.ts - Desktop attach · Native Win32 wallpaper parenting that attaches the panel behind desktop icons.
electron/native/wallpaper.ts - Wallpaper service · Retries and maintains the desktop-shell attachment for the wallpaper surface.
electron/services/wallpaperAttachService.ts - Background services · Startup registration, display tracking, reminders, updater support, and watchdog behavior.
electron/services/startupService.ts
Renderer UI
React UI, feature pages, layouts, widgets, and client-side state.
- App shell · Routes between wallpaper panel and editor shell in the renderer.
src/App.tsx - Wallpaper layout · Layout for the desktop-attached today panel.
src/layouts/WallpaperLayout.tsx - Editor layout · Layout for the full editor window.
src/layouts/EditorLayout.tsx - Feature pages · Task, calendar, notes, and settings screens in the editor.
src/features/tasks/components/TasksPage.tsx - Wallpaper widgets · Shared desktop-panel widgets such as tasks, notes, clock, date, and calendar month.
src/widgets/WallpaperTodayPanel/index.tsx - IPC client · Renderer-side wrapper around the dayone bridge for backend calls and refresh flow.
src/services/ipcClient.ts - UI stores · Client state for settings, theme, and wallpaper behavior.
src/store/useSettingsStore.ts
Local data
Prisma schema, SQLite persistence, migrations, and seed data.
- DB client · Creates and initializes the Prisma-backed SQLite client and runtime database state.
electron/database/client.ts - DB init · Bootstraps default settings and initial database state.
electron/database/init.ts - Schema · Defines tasks, categories, notes, events, reminders, and settings models.
prisma/schema.prisma - Migrations · Database schema evolution for the local SQLite store.
prisma/migrations/20260627000000_init/migration.sql
Build & packaging
Tooling for development, bundling, and installer packaging.
- Build tooling · Vite, TypeScript, and Electron launch scripts for development and production builds.
vite.config.ts - Packaging · Electron Builder packaging, native dependency handling, and NSIS installer output.
electron-builder.yml
Connections 23
- Main entry → Window manager: creates · Main process delegates window lifecycle to the centralized manager.
- Main entry → Tray control: owns · Tray is initialized from the app bootstrap.
- Main entry → IPC handlers: registers · Main bootstrap wires typed IPC handlers.
- Main entry → Preload bridge: loads · Preload exposes the renderer bridge.
- Main entry → Background services: starts · Bootstraps background services on app launch.
- Window manager → Wallpaper service: attaches · Window manager coordinates the wallpaper surface lifecycle.
- Wallpaper service → Desktop attach: uses · Desktop attachment relies on native Win32 interop.
- IPC handlers → DB client: queries · Handlers perform CRUD through the local database client.
- DB init → DB client: initializes · Database startup sets defaults and seed state.
- Schema → Migrations: evolves to · Schema is realized through generated migrations.
- Preload bridge → IPC client: exposes · Renderer consumes the backend through the bridge and client wrapper.
- IPC client → IPC handlers: calls · Renderer actions dispatch to main-process handlers.
- IPC handlers → Channel map: uses · Handlers and renderer share domain channel names.
- App shell → Wallpaper layout: routes · App shell selects the desktop panel layout.
- App shell → Editor layout: routes · App shell selects the editor window layout.
- Editor layout → Feature pages: hosts · Editor shell renders the feature views.
- Wallpaper layout → Wallpaper widgets: hosts · Wallpaper surface is composed from shared widgets.
- Feature pages → IPC client: reads/writes · Feature pages load and mutate data through IPC.
- Wallpaper widgets → IPC client: reads · Desktop widgets pull data via the renderer client.
- UI stores → App shell: supports · Client state feeds layout and theme behavior.
- Build tooling → App shell: bundles · Vite builds the React renderer.
- Build tooling → Main entry: compiles · TypeScript build produces main-process output.
- Packaging → Desktop attach: packages · Installer build ships native modules required for desktop attachment.