Introduction to Electron JS: The Complete Guide for Building Cross-Platform Desktop Apps

Electron JS has exploded in popularity among developers needing to build performant, native-feeling desktop applications with web technologies. This open-source framework lets you use JavaScript, HTML and CSS to craft apps that consistently look and feel right at home on Windows, macOS and Linux systems.

Whether you want to extend an existing web app to desktop or build a sleek new desktop app from scratch, Electron makes it straightforward to distribute on multiple platforms. Companies like Microsoft, Slack, Discord, Spotify and WhatsApp already use Electron in their desktop offerings.

In this comprehensive guide, you’ll learn:

  • What exactly Electron is and why it has become a top choice
  • How Electron provides native access capabilities from the web
  • What makes Electron apps stand apart from progressive web apps
  • Step-by-step instructions for building your first Electron app
  • Best practices for structuring and deploying Electron projects
  • Debugging tips for peak Electron app performance
  • Where to find Electron-specific learning resources
  • Real-world examples of Electron apps

Let’s get started building the future of cross-platform desktop apps!

What Exactly is Electron JS?

Electron JS is an open-source framework developed by GitHub for building cross-platform desktop applications using web technologies. Apps built with Electron combine the Chromium browser engine and Node.js environment into a single runtime.

This allows Electron apps to easily leverage Chromium for displaying content and Node.js for backend logic/APIs. As a result, developers can use HTML, CSS and JavaScript across both the front and backend codebase.

Electron also provides access to native operating system APIs normally unavailable from the web, like file system access, notifications, system dialogs and more. This erases many limitations faced when building desktop apps with web tech in the past.

Apps built on Electron are packaged and distributed as normal desktop application installers. This means they live natively on user devices instead of running isolated in a browser tab. Popular apps using Electron today include:

  • Microsoft Teams
  • Slack
  • Discord
  • Spotify
  • Figma
  • Visual Studio Code
  • WhatsApp Desktop
  • Twitch Desktop

This ability to leverage web technologies for building desktop apps that feel native across platforms has fueled Electron’s rapid adoption. Next up, let’s understand how Electron provides JavaScript access to native operating system capabilities.

Bridging JavaScript and Native Capabilities

A core value proposition of Electron is enabling web technologies to tap into native desktop features usually inaccessible from the browser sandbox. This is accomplished through a multi-process architecture with specialized process types.

The Main Process

The main process is responsible for managing all other processes in the app. It has full access to Node.js APIs and handles critical application tasks like:

  • Initializing browser windows
  • Installing native modules
  • Hardware interactions
  • System notifications
  • Dialog boxes

The main process serves as a gateway to privileged native resources on host devices. It runs a complete Node.js instance and can directly leverage thousands of modules from npm.

Renderer Processes

Electron apps can spawn multiple renderer processes, each equivalent to a browser tab running web page content. These handle all UI components getting displayed to users via:

  • HTML for structure
  • CSS for styling
  • JavaScript for logic

Renderer processes have no access to native OS capabilities or Node.js APIs. However, they can indirectly access many system resources by communicating with the main process.

Preload Scripts

Preload scripts run immediately when each renderer process launches and serve as middleware between renderers and main. They have Node.js API access when executed and can:

  • Initialize context bridges
  • Set globals APIs
  • Install native modules

Altogether, this multi-process model provides both security and flexibility:

  • Main process manages OS system resources
  • Renderer processes display UIs isolated from privilege
  • Preload scripts enable JS context sharing across processes

Let’s see how Electron differs from related web-based approaches for building desktop apps.

How Electron Apps Differ from Progressive Web Apps

Progressive web applications (PWAs) represent another technology for building web-native hybrid desktop experiences. So how are Electron apps unique?

While PWAs allow websites to morph into persistent desktop apps with many native features, the web remains a constrained environment in some aspects.

Progressive web apps in comparison to Electron:

  • Can only access limited system resources granted by browsers
  • Require browser UIs like navigation bars instead of pure native menus
  • Sandboxed from freely accessing hardware devices and peripherals
  • Restricted from advanced native OS capabilities like filesystem I/O

Furthermore, PWAs must be implemented using specific web development strategies for installability and offline access. Electron apps on the other hand allow utilizing any frontend JS framework (React, Vue, Svelte etc) since Chromium handles UI rendering under the hood.

In summary, Electron provides complete flexibility over both UI appearance and backend device/system access in building desktop-caliber apps.

Now let‘s dive into building a hands-on Electron app from scratch!

Building Your First Electron Desktop App

One of the best things about Electron is how quickly you can build and run desktop apps with web languages you already know.

Let‘s walk through a simple Electron app example together:

Step 1: Install Prerequisites

We‘ll need Node.js installed for access to npm and the terminal for executing commands.

On Windows, you can use PowerShell. On Linux and macOS, use your standard terminal app.

Verify proper Node.js installation with:

node -v
npm -v 

Step 2: Scaffold the App

Let‘s scaffold out an Electron app skeleton with npm:

npm init electron-app my-first-electron-app

This will generate a starter project directory named "my-first-electron-app" with all boilerplate Electron code in place.

Step 3: Install Dependencies

Navigate into the new directory and install app dependencies:

cd my-first-electron-app
npm install

This uses the including package.json config to grab Electron and any other libraries needed.

Step 4: Run the App

Start the app in development mode with:

npm start

A desktop window should now open with default Electron starter content rendered!

Step 5: Add Application Logic

Open main.js in an editor to define custom application logic:

const { app, BrowserWindow } = require(‘electron‘) 

function createWindow() {
  // Code for window creation
}

app.whenReady().then(() => {    
  createWindow()

  app.on(‘activate‘, () => {
    // Recreate window on macOS
  })

  app.on(‘window-all-closed‘, () => {
    // Quit app when windows closed
  })
}) 

Implement window creation, macOS behavior overrides, cleanup handlers and more here.

The index.html file can be edited to update UI markup and styles. Renderer process JavaScript code gets added to renderer.js.

That‘s it! With just those basics, you can build and distribute a cross-platform desktop app on Windows, macOS and Linux leveraging JavaScript, HTML and CSS.

Now let‘s explore some best practices for structuring production-grade Electron apps.

Structuring Electron Apps for Production

As Electron apps grow in scope, it becomes important to adopt an organized project structure early on. Here are some tips for structuring scalable apps:

Separate Main and Renderer Code

Keep main process and renderer process JavaScript code isolated into separate files:

  • main.js – App bootstrap and main process logic
  • renderer.js – Renderer window UI logic

This prevents bloating individual files while allowing clear separation of responsibilities.

Organize by Feature

For large apps with many windows, organize files/folders by feature area:

app
├─ main.js
├─ mainWindow.js
├─ settingsWindow.js
├─ helpers
│  ├─ db.js
│  ├─ api.js
├─ windows
│  ├─ mainWindow.html
│  ├─ settingsWindow.html

This keeps all related logic together, especially when using multiple renderer windows.

Refactor Shared Logic

Extract any reused logic into standalone modules under helpers. For example:

// db.js
exports.saveSettings = () => {
  // database logic  
}

// mainWindow.js
const { saveSettings } = require(‘./helpers/db‘)

This avoids duplication across files and encapsulates logic easier to maintain.

Add Build Scripts

Use npm scripts to automate builds for production:

"scripts": {
  "start": "electron .",  
  "build": "electron-builder"
}

Then generate distributables just by running npm run build – no manual work needed!

Debugging Electron Apps

Electron apps live simultaneously across multiple processes – a main process along with one or more renderer processes.

Debugging across this environment requires using specific tools capable of attaching to Node.js and browser contexts.

Here are some tips for debugging Electron apps efficiently:

Enable DevTools

All renderer processes run an instance of Chromium under the hood. Use the familiar Chrome DevTools to debug by toggling this flag:

mainWindow.webContents.openDevTools()

You can inspect DOM elements, profile JavaScript execution and more!

Debug Main Process

Since the main process runs in Node.js, you can debug using the node inspector:

electron --inspect-brk=9229 app

This allows setting breakpoints and stepping through main process code line-by-line.

Log Across Processes

Simple console.log calls only show messages from the current process. Use the remote module instead:

const { remote } = require(‘electron‘) 
remote.getGlobal(‘console‘).log(‘message‘)  

Now messages get sent application-wide to aid debugging anywhere.

With these tools and patterns, you can squeeze peak performance out of Electron apps!

Learning Resources for Mastering Electron

Thanks to Electron‘s expansive community and ecosystem, there are plenty of amazing resources available for taking your skills further:

Official Electron Documentation

Of course, the official Electron JS documentation is the ultimate guide to all framework capabilities and APIs:

https://www.electronjs.org/docs

Read through for comprehensive details on main processes, renderer processes, modules, distribution and countless other topics critical for building production-ready Electron desktop apps.

Modern Desktop Apps with Electron Course

For a structured video course, check out this Modern Desktop Apps with Electron offering from educator Shaun Wassell on LinkedIn Learning:

https://www.linkedin.com/learning/modern-desktop-apps-with-electron

It covers core concepts like managing windows/menus before building a complete Markdown app from scratch across 11 hours of content.

Electron Userland

Electron Userland offers lots of helpful tooling and services purpose-built for Electron development:

https://electronuserland.com

From cross-platform installers to performance monitoring and crash analytics, find critical services here to level up your next Electron project!

Awesome Electron

For more community-curated Electron learning resources, the Awesome Electron GitHub repo maintains a frequently updated list covering books, videos, seed projects, SDKs and more:

https://github.com/sindresorhus/awesome-electron

An amazing community resource for developers!

Real-World Examples of Electron Apps

Let’s spotlight some popular real-world Electron apps taking advantage of native operating system capabilities:

Microsoft Teams

Microsoft Teams has become vital collaboration software for remote work during the pandemic. The desktop app provides crucial functionality like:

  • Screen sharing
  • Live video calling
  • Calendar integration
  • Third-party messaging

Teams taps into Electron for native APIs powering OS interactions across Windows, macOS and Linux.

Figma

Figma has risen to prominence as one of the top UI/UX design tools. The Figma desktop app gives designers native-quality OS integration enabling:

  • Vector graphics editing
  • Prototyping
  • Design systems crafting
  • Collaboration via comments/mentions

By using Electron, Figma combines the comfort of web with the performance of dedicated desktop software.

Visual Studio Code

Visual Studio Code from Microsoft is arguably the most popular code editor among developers today. At 50+ million monthly active users, VS Code shines by enabling:

  • Extensions and customizations
  • Built-in terminal access
  • Portable workplace via Sync
  • IntelliSense and debugging

The use of Electron for native extensibility makes VS Code feel right at home across operating systems.

As you can see, Electron delivers immense opportunities for crafting performant cross-platform desktop apps with web technologies. The Electron community and ecosystem continue growing rapidly – will you join in building the next generation of native desktop apps with JavaScript?