"웹 기술로 데스크톱 앱을 만든다" — Electron은 HTML, CSS, JavaScript만으로 Windows, macOS, Linux 앱을 동시에 만들 수 있는 프레임워크입니다.

면접에서 Electron이 뭔지 물어보면 "Chromium + Node.js를 합친 것"이라고 답하면 절반은 맞지만, 왜 그 구조를 택했는지까지 설명할 수 있으면 좋습니다.


Electron이란

Electron은 웹 기술(HTML, CSS, JavaScript)로 크로스플랫폼 데스크톱 애플리케이션 을 만드는 프레임워크입니다.

  • GitHub에서 Atom 에디터를 만들기 위해 개발
  • VS Code, Slack, Discord, Figma 등이 Electron으로 만들어짐
  • Chromium(렌더링 엔진) + Node.js(시스템 접근)를 결합한 구조

왜 Electron을 쓰는가

장점설명
크로스플랫폼하나의 코드로 Windows, macOS, Linux 지원
웹 생태계 활용React, Vue 등 프론트엔드 프레임워크 그대로 사용
빠른 개발 속도네이티브 대비 개발 시간이 훨씬 짧음
풍부한 생태계npm 패키지를 그대로 사용 가능
단점설명
앱 크기Chromium을 포함하므로 최소 100MB+
메모리 사용량브라우저 엔진을 내장하므로 메모리를 많이 사용
성능네이티브 앱 대비 성능이 떨어질 수 있음

환경 설정

Node.js 설치 확인

BASH
# Node.js 16 이상이 필요합니다
node -v   # v18.x 이상 권장
npm -v

프로젝트 초기화

BASH
# 프로젝트 디렉토리 생성
mkdir my-electron-app
cd my-electron-app

# package.json 생성
npm init -y

# Electron 설치
npm install electron --save-dev

package.json 수정

JSON
{
  "name": "my-electron-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^28.0.0"
  }
}

"main" 필드가 Electron의 진입점을 가리킵니다. 이게 메인 프로세스의 시작 파일입니다.


Hello World 앱 만들기

main.js (메인 프로세스)

JAVASCRIPT
// main.js — Electron의 메인 프로세스 진입점
const { app, BrowserWindow } = require('electron');
const path = require('path');

// 브라우저 윈도우를 생성하는 함수
function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // preload 스크립트 경로 설정
      preload: path.join(__dirname, 'preload.js'),
    },
  });

  // HTML 파일을 로드합니다
  win.loadFile('index.html');
}

// 앱이 준비되면 윈도우 생성
app.whenReady().then(() => {
  createWindow();

  // macOS에서는 Dock 아이콘 클릭 시 윈도우가 없으면 새로 생성
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

// 모든 윈도우가 닫히면 앱 종료 (macOS 제외)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

preload.js

JAVASCRIPT
// preload.js — 렌더러에서 Node.js API에 접근할 수 있도록 다리 역할
window.addEventListener('DOMContentLoaded', () => {
  // DOM이 준비되면 버전 정보를 표시합니다
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector);
    if (element) element.innerText = text;
  };

  for (const type of ['chrome', 'node', 'electron']) {
    replaceText(`${type}-version`, process.versions[type]);
  }
});

index.html

HTML
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta http-equiv="Content-Security-Policy"
        content="default-src 'self'; script-src 'self'" />
  <title>Hello Electron!</title>
</head>
<body>
  <h1>Hello Electron!</h1>
  <p>
    Chrome: <span id="chrome-version"></span> /
    Node: <span id="node-version"></span> /
    Electron: <span id="electron-version"></span>
  </p>
</body>
</html>

실행

BASH
npm start

이렇게 하면 데스크톱 창이 하나 뜨면서 "Hello Electron!"과 버전 정보가 표시됩니다.


프로젝트 구조 이해

PLAINTEXT
my-electron-app/
├── main.js          # 메인 프로세스 (Node.js 환경)
├── preload.js       # 프리로드 스크립트 (브릿지 역할)
├── index.html       # 렌더러 프로세스 (브라우저 환경)
├── package.json     # 프로젝트 설정
└── node_modules/
  • main.js: Node.js API를 사용할 수 있는 메인 프로세스
  • preload.js: 메인과 렌더러를 안전하게 연결하는 다리
  • index.html: 사용자에게 보이는 UI (브라우저 환경)

개발 모드에서 유용한 설정

JAVASCRIPT
// main.js에 추가 — 개발 중에만 DevTools 자동 열기
function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
    },
  });

  win.loadFile('index.html');

  // 개발 모드에서 DevTools 열기
  if (!app.isPackaged) {
    win.webContents.openDevTools();
  }
}

app.isPackaged를 사용하면 빌드된 앱인지 개발 중인지 구분할 수 있습니다. 프로덕션에서는 DevTools가 열리지 않습니다.


면접 포인트 정리

  • Electron = Chromium(UI 렌더링) + Node.js(시스템 접근)의 결합
  • 메인 프로세스(Node.js)와 렌더러 프로세스(Chromium)로 나뉨
  • app.whenReady()는 Electron 앱의 라이프사이클 시작점
  • macOS는 창을 모두 닫아도 앱이 종료되지 않는 것이 관례 (window-all-closed 이벤트)
  • preload 스크립트가 메인과 렌더러 사이의 안전한 통로 역할

Electron의 "Hello World"를 만들었으면 다음은 프로세스 모델을 이해해야 합니다. 메인과 렌더러가 왜 분리되어 있는지, IPC가 왜 필요한지가 그 핵심입니다.

댓글 로딩 중...