Skip to content

Add Electron quickstart app#280

Open
Brian Plattenburg (bplattenburg) wants to merge 2 commits intomainfrom
add-electron-quickstart
Open

Add Electron quickstart app#280
Brian Plattenburg (bplattenburg) wants to merge 2 commits intomainfrom
add-electron-quickstart

Conversation

@bplattenburg
Copy link
Copy Markdown
Member

Summary

  • New /electron/ quickstart implementing the Tasks demo on Electron with Ditto JS SDK 5.0.0.
  • Ditto Node SDK runs in Electron's main process (full peer-to-peer over LAN + websocket); a React/TS renderer mirrors javascript-web and communicates with Ditto via a contextBridge IPC API. The main-process observer fans task updates out to all renderer windows.
  • Dev-only scope: no CI, no installers, no signing. Targets macOS (Apple Silicon), Linux (x64/arm64), Windows (x64).

Why

Customer ask for an Electron reference app. First quickstart running Ditto's Node SDK inside Electron — documents the BLE/AWDL transport caveats for unsigned dev builds and uses N-API prebuilds (verified to load in Electron without @electron/rebuild).

Validation

Validated locally on macOS (Apple Silicon). Requesting Aaron LaBeau (@biozal) to validate on Windows (x64) before merge.

New /electron/ quickstart implementing the Tasks demo on Electron with
the Ditto JS SDK 5.0.0. The Ditto Node SDK runs in Electron's main
process (full peer-to-peer sync over LAN + websocket), and a React +
TypeScript renderer mirrors the javascript-web app, communicating with
Ditto entirely via a contextBridge IPC API. The main-process observer
fans task list updates out to all renderer windows.

Why: customer ask for an Electron reference app. This is the first
quickstart that runs the Ditto Node SDK inside Electron's main process,
so it documents the BLE/AWDL transport caveats for unsigned dev builds
and uses N-API prebuilds (verified to load in Electron without
@electron/rebuild). Dev-only scope: no CI, no installers.
Copilot AI review requested due to automatic review settings May 7, 2026 19:49
@bplattenburg Brian Plattenburg (bplattenburg) requested a review from a team as a code owner May 7, 2026 19:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Electron-based “Tasks” quickstart that runs the Ditto Node SDK in Electron’s main process and exposes a typed IPC API to a React/TypeScript renderer.

Changes:

  • Introduces a new /electron/ app scaffolded with electron-vite + React + Tailwind, including main/preload/renderer separation.
  • Implements a Ditto-backed tasks CRUD flow in the main process with IPC fan-out of task updates to renderer windows.
  • Updates the repo root README to link to the new Electron quickstart.

Reviewed changes

Copilot reviewed 24 out of 27 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
README.md Adds Electron quickstart link to the repo index.
electron/.gitignore Ignores Electron build outputs and local deps.
electron/electron.vite.config.ts electron-vite build config for main/preload/renderer.
electron/eslint.config.js ESLint flat config for TS + React + Prettier.
electron/package.json Declares Electron quickstart dependencies and scripts.
electron/package-lock.json Locks dependency graph for the Electron app.
electron/postcss.config.js PostCSS config for Tailwind + autoprefixer.
electron/prettier.config.js Prettier formatting settings for the Electron app.
electron/README.md Electron quickstart documentation and architecture overview.
electron/tailwind.config.js Tailwind content scanning configuration.
electron/tsconfig.json TS project references setup.
electron/tsconfig.node.json TS config for main/preload TypeScript.
electron/tsconfig.web.json TS config for renderer TypeScript.
electron/src/types.ts Shared task + IPC channel/type definitions.
electron/src/main/index.ts Electron main process entry + IPC handlers + window creation.
electron/src/main/env.ts Loads required Ditto env vars from repo root .env.
electron/src/main/ditto.ts Ditto initialization, sync config, observer, and CRUD helpers.
electron/src/preload/index.ts Exposes typed IPC-backed window.ditto API via contextBridge.
electron/src/preload/api.d.ts Global window.ditto TypeScript declaration.
electron/src/renderer/vite-env.d.ts Vite client typings for the renderer.
electron/src/renderer/index.html Renderer HTML shell and CSP meta.
electron/src/renderer/index.css Tailwind directives and full-height layout.
electron/src/renderer/main.tsx React root bootstrap.
electron/src/renderer/App.tsx App wiring for Ditto info, sync toggle, and task list callbacks.
electron/src/renderer/components/DittoInfo.tsx Displays app identity + sync toggle UI.
electron/src/renderer/components/ErrorMessage.tsx Dismissible error overlay component.
electron/src/renderer/components/TaskList.tsx Task list UI with edit/toggle/delete/create actions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread electron/package.json Outdated
Comment thread electron/src/main/ditto.ts
Comment thread electron/src/renderer/App.tsx
Comment thread electron/src/renderer/components/TaskList.tsx
Comment thread electron/src/renderer/index.html Outdated
Comment thread electron/src/main/index.ts Outdated
- Bump Node engine and README to >=22.12 to match Electron 42's
  bundled runtime (avoids strict-engines install failures).
- Add connect-src to the renderer CSP so Vite HMR's WebSocket can
  connect during dev.
- Drop sandbox: false from BrowserWindow webPreferences and ship
  the preload as CommonJS (.cjs). contextBridge + ipcRenderer work
  cleanly under the default sandbox, and ESM preloads silently fail
  to load when sandboxed.
- Hydrate initial renderer state via a new tasks:get IPC method to
  close a race: the main-process observer fires when cloud sync
  delivers tasks, often before the BrowserWindow has registered its
  IPC listener. Renderer now subscribes first, then fetches initial
  state.
@bplattenburg
Copy link
Copy Markdown
Member Author

Thanks @copilot — addressed three, dismissing one, deferring two. Details:

Addressed in b0f9278:

  • [package.json:10] Bumped engines.node and the README to >=22.12.0 to match Electron 42's bundled Node runtime.
  • [index.html:8] Added connect-src 'self' ws://localhost:* http://localhost:* to the renderer CSP so Vite HMR's WebSocket can connect in dev.
  • [main/index.ts:37] Dropped sandbox: false. The preload only uses contextBridge and ipcRenderer, both available under sandbox. Also reconfigured electron-vite to emit the preload as CommonJS (.cjs) — ESM preloads silently fail to load when the renderer is sandboxed.

Dismissed:

  • [ditto.ts:37] The Ditto SDK's expiration handler is invoked immediately on first connect when there is no cached JWT — that's the v5 login mechanism. No explicit auth.login is required, and javascript-web (the canonical v5 reference, Update Quickstart for Javascript to v5 #241) follows the same pattern with no explicit login. Verified locally: ditto_auth: no cached JWT, notifying login provider immediately followed by auth server login successful shows the chain.

Deferred (matches javascript-web canonical pattern):

  • [App.tsx:49] setSyncActive updater containing startSync/stopSync side effects — same shape as javascript-web/src/App.tsx post-Update Quickstart for Javascript to v5 #241. If we change it here we should change it there too, in a separate cross-cutting PR.
  • [TaskList.tsx:165] handleCreate doesn't trim — TaskList.tsx is copied verbatim from javascript-web. Same divergence-from-canonical concern; cosmetic.

Bonus (caught while validating the sandbox+CJS preload change): the main-process observer fires when cloud sync delivers tasks, often before the BrowserWindow has registered its IPC listener — leaving the renderer with an empty list. b0f9278 adds a tasks:get IPC method so the renderer subscribes first, then hydrates initial state. Confirmed locally: tasks now load on launch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants