Skip to Content
Project Structure

Project Structure

        • index.tsApp lifecycle
        • window.tsMain, activation and About windows
        • menu.tsNative menu
        • updater.tsAuto updater
        • events.tsTyped event bus, forwarded to the renderer
        • paths.tsPaths of resources/ and drizzle/ in dev and production
        • index.tsExposes tRPC to the renderer, nothing else
        • config.tsConfig schema
        • i18n.tsTranslation resources
        • license.tsLicense types and helpers
        • index.html
          • main.tsxEntry point
          • styles.cssTailwind CSS and theme colors
    • AGENTS.mdInstructions for AI agents (CLAUDE.md imports it)
    • biome.jsonLinter and formatter
    • components.jsonshadcn/ui
    • drizzle.config.tsdrizzle-kit
    • electron-builder.tsPackaging, signing, publishing
    • electron.vite.config.tsBuild of main, preload and renderer
    • tsconfig.node.jsonMain + preload (Node.js types)
    • tsconfig.web.jsonRenderer (DOM types)

Processes

Electron apps run code in several processes:

  • Main – runs in Node.js, creates windows and has full system access. It owns the database, the config file and the auto updater.
  • Preload – runs before the page loads. In this template it only exposes the tRPC bridge.
  • Renderer – runs your React UI in a sandboxed Chromium page, without access to Node.js. It talks to the main process only through tRPC.

Code needed by both sides (zod schemas, types, translations) lives in src/shared/.

Import aliases

AliasPoints toAvailable in
@renderer/*src/renderer/src/Renderer
@shared/*src/shared/Main, preload, renderer
@main/*src/main/Renderer, types only

The renderer imports the type of the tRPC router from @main/trpc/router, which is why tsconfig.web.json also includes src/main. Importing a value from @main in the renderer would fail at runtime.

Last updated on