Getting Started with Electron
Your journey from web developer to desktop app builder starts here. Learn to think in terms of processes, security boundaries, and native integration.
The Mental Model Shift
If you're coming from web development, Electron will feel both familiar and foreign. You'll write React components and style with CSS—but you'll also think about process architecture, native APIs, and security boundaries that don't exist in browser-based apps.
Here's the shift: A web app runs in a single process with sandboxed limitations. An Electron app runs in multiple processes—one with full system access (main process) and others running your UI (renderer processes). This separation is intentional: security.
Think of it like building a client-server app, except both the client and server run on the same machine. The main process is your "backend" with database access (file system), and renderers are your "frontend" displaying UI. They communicate through IPC (Inter-Process Communication), just like HTTP requests.
Setting Up Your Environment
The good news: if you can build web apps, you already have most of what you need. Electron runs on Node.js, so your existing JavaScript/TypeScript knowledge transfers directly. The learning curve isn't the language—it's understanding the architecture.
Prerequisites
- Node.js v18+ - The runtime that powers Electron
- npm or yarn - Package management
- VS Code - Best IDE for TypeScript + Electron debugging
- Basic TypeScript knowledge - Type safety is crucial for multi-process apps
# Verify your setup
node --version # v18.0.0 or higherThe Fast Path: Electron Forge
Electron Forge is the official scaffolding tool. It's opinionated (in a good way) and sets up everything you need: TypeScript, webpack, hot reload, and build tools. When I started VibeBlaster, I used Forge and never looked back.
Why Forge over manual setup? Because desktop app development has unique requirements: code signing, auto-updates, platform-specific builds, and installer generation. Forge handles all of this with sane defaults.
npm create electron-app@latest my-app -- --template=typescript-webpack# This creates a production-ready structure with:
# ✓ TypeScript configured
# ✓ Webpack for bundling
# ✓ Hot reload enabled
# ✓ Build tools ready
💡 Pro Tip: Start with the typescript-webpack template. It includes everything you'll eventually need. Trust me—adding TypeScript and webpack to an existing Electron app later is painful.
Understanding the Structure
An Electron app isn't a single JavaScript file—it's an orchestrated system of processes working together. Understanding this structure is crucial because it informs every architectural decision you'll make.
my-electron-app/ ├── src/ │ ├── main/ │ │ └── index.ts # Main process (Node.js runtime) │ ├── preload/ │ │ └── index.ts # Security bridge │ └── renderer/ │ ├── index.html # UI entry point │ ├── App.tsx # React app (or your framework) │ └── index.tsx # Renderer bootstrap ├── package.json ├── tsconfig.json └── forge.config.ts # Build configuration
Main Process
Your "backend." Runs in Node.js with full system access. Creates windows, handles file I/O, manages app lifecycle.
Think: Express server, but for desktop
Renderer Process
Your "frontend." Runs in Chromium, sandboxed for security. Each window is a separate renderer process.
Think: React app in a browser tab
Preload Script
The secure bridge. Exposes carefully chosen APIs from main to renderer without breaking sandboxing.
Think: API gateway with CORS policies
⚠️ Critical Security Concept
Renderer processes should NEVER have direct access to Node.js APIs. This is intentional—if a renderer is compromised (XSS attack, malicious npm package, etc.), the attacker shouldn't get system access. The preload script acts as a controlled gateway, exposing only safe, validated APIs.
Your First Meaningful App
Instead of "Hello World," let's build something you'll actually understand: a simple note-taking app. It'll demonstrate the three-part architecture, IPC communication, and file system access—the foundation of every Electron app you'll ever build.
What We're Building
A desktop notes app that:
- Saves notes to disk (main process handles file I/O)
- Displays a UI (renderer process shows the interface)
- Communicates securely (preload script bridges the two)
This demonstrates the core pattern you'll use in every Electron app: renderer requests data, main process handles privileged operations, data flows back through secure channels.
The Main Process: Your Backend
The main process creates windows and handles system operations. Here's the conceptual flow:
App Initialization
Wait for Electron to be ready, then create the main window
Window Configuration
Set size, load HTML, configure security (context isolation, no Node.js in renderer)
IPC Handlers
Register handlers for renderer requests (save-note, load-note, etc.)
File System Operations
Handle reading/writing notes to disk (privileged operation)
The Preload Script: Secure Bridge
This is where security happens. The preload script runs in a special context with access to both Node.js and the renderer's window object—but it exposes ONLY the APIs you explicitly allow.
The Pattern:
contextBridge creates a safe channel
exposeInMainWorld adds APIs to window
ipcRenderer.invoke calls main process handlers
Renderer never touches Node.js directly, ever
The Renderer: Your UI
This is familiar territory—React, Vue, or vanilla JS. The only difference: instead of calling an HTTP API, you call the APIs exposed by your preload script.
The mental model:
// Web app pattern:
await fetch('/api/notes')
// Electron app pattern:
await window.electronAPI.loadNotes()
Same concept, different transport. Instead of HTTP, you're using IPC.
💡 VibeBlaster Example
In VibeBlaster, the renderer displays OAuth login buttons. When clicked, it callswindow.api.startOAuthFlow('twitter'). The main process opens a secure browser window, handles the OAuth callback, stores tokens securely, and returns success to the renderer. The renderer never sees the tokens or opens windows—it just requests the operation through the secure bridge.
Development Workflow: Why It Matters
Electron development feels surprisingly like web development because of hot reload. Change code, see results instantly—no full rebuild. This is critical when you're iterating on UI or debugging IPC communication.
Hot Reload (Renderer)
Changes to your UI (HTML, CSS, React components) refresh automatically. Just like Create React App or Vite.
Why: Your renderer is just a web page running in Chromium
Manual Restart (Main)
Changes to main process code require restarting the entire app. Electron Forge handles this, but expect a 2-3 second delay.
Why: Main process is Node.js, not hot-reloadable
Development Commands
npm startorelectron-forge startLaunches your app with DevTools enabled. This is your daily driver during development.
npm run packageCreates a distributable version for your current platform (no installer). Useful for testing the packaged version before distribution.
npm run makeCreates platform-specific installers (.dmg for Mac, .exe for Windows, .deb for Linux). This is what you distribute to users.
🛠️ Real-World Workflow (VibeBlaster)
Daily development: npm start and keep it running. UI changes show instantly, main process changes restart the app automatically.
Testing OAuth flows: Use npm run packageto test the production-like version (OAuth redirect URIs behave differently in dev vs. production).
Pre-release testing: npm run make to generate the installer, install it locally, and test the full user experience including auto-updates.
Pro Tip: DevTools are Your Friend
Electron's DevTools work exactly like Chrome DevTools. You can inspect the renderer process (your UI), set breakpoints, monitor network requests, and debug React components with React DevTools.
For the main process, use console.log()or attach a debugger via VS Code's launch configuration. Main process logs appear in your terminal, not the app window.
Ready for the Deep Dive?
You've seen the three-part architecture in action and understand the mental model. Now it's time to understand why Electron works this way—and how to design your app's architecture around these constraints.
In the next chapter, you'll learn:
- •Why multi-process? The security and performance reasons behind the architecture
- •IPC patterns: When to use invoke/handle vs. send/on, and why it matters
- •Security boundaries: Where XSS and injection attacks can happen, and how to prevent them
- •Real-world architecture: How VibeBlaster structures main process modules and IPC handlers
This is where you'll move from "it works" to "I understand why it works this way"—which is when you start making better architectural decisions.