⚡ Electron★ 용어 사전Core Runtime — 런타임·프로세스 용어

01 · Core Runtime — 런타임 / 프로세스 용어

이 챕터: Electron 런타임을 이루는 객체와 프로세스 — Main / Renderer / Preload / Utility / GPU / Zygote, 그리고 그 위에 얹힌 BrowserWindow · webContents · session · IPC 모듈들. 참고 챕터: 01-process-model, 02-window-lifecycle, 03-ipc-bridge


app (module)

Electron 앱의 라이프사이클·전역 설정을 담당하는 Main 프로세스 전용 모듈.

app.whenReady(), app.on('window-all-closed'), app.quit() 같은 이벤트 진입점의 본진. 단일 인스턴스 강제(app.requestSingleInstanceLock()), 기본 프로토콜 등록(app.setAsDefaultProtocolClient), 사용자 데이터 경로 변경(app.setPath('userData', ...))도 여기서 한다. 흔한 오해는 “renderer에서도 쓸 수 있다” — Main 전용이고 renderer에서는 @electron/remote(deprecated) 없이는 못 닿는다.

관련: [BrowserWindow], [process.type], [session] 참고 챕터: 02-window-lifecycle


BrowserView

한 BrowserWindow 안에 겹쳐 띄우는 별도 webContents 영역. iframe 없이 native 합성.

메인 UI는 로컬 페이지로 두고 그 안에 외부 사이트(광고·OAuth 콜백·웹 미리보기)를 BrowserView로 띄우는 패턴. iframe과 달리 별도 프로세스에 격리되고, CSS로 위치를 잡을 수 없어 좌표를 직접 설정해야 한다. deprecation 주의: Electron 30+에서 WebContentsView로 대체 권고.

관련: [BrowserWindow], [webContents], [contextIsolation] 참고 챕터: 02-window-lifecycle


BrowserWindow

OS 창 + webContents + Renderer 프로세스를 한 묶음으로 추상화한 Main 프로세스 객체.

new BrowserWindow({ webPreferences: { ... } }) 한 줄이 OS에 창을 만들고, Chromium 렌더러 프로세스를 띄우고, 그 안의 webContents를 만든다. 창 1개 = 프로세스 1개가 디폴트(process per window). loadURL/loadFile로 콘텐츠를 띄우고, webPreferences로 sandbox·contextIsolation·preload를 지정한다.

관련: [webContents], [webPreferences], [preload script], [session] 참고 챕터: 02-window-lifecycle


contextBridge

Preload에서 Renderer의 window좁은 함수만 안전하게 노출하는 API.

contextBridge.exposeInMainWorld('api', { ping: () => ipcRenderer.invoke('ping') })로 renderer는 window.api.ping()만 볼 수 있고 Node 전체는 못 본다. 유일한 안전 통로contextIsolation: true일 때만 의미가 있다. 노출 객체는 값 복제되며 함수만 살아남는다 (proxy/getter는 깨질 수 있음).

관련: [contextIsolation], [preload script], [ipcRenderer], [invoke/handle] 참고 챕터: 03-ipc-bridge, 05-security


contextIsolation

Preload 스크립트의 JS 컨텍스트를 페이지의 JS 컨텍스트와 분리하는 보안 플래그.

Electron 12+ 기본값 true. 이게 켜져 있어야 preload의 Node API가 page script에 새지 않는다 — XSS가 한 번 터져도 require('child_process')를 못 부른다. false로 끄면 preload와 page가 같은 window를 공유해 보안 모델이 무너진다 — 절대 끄지 말 것.

관련: [contextBridge], [preload script], [sandbox], [nodeIntegration] 참고 챕터: 05-security


GPU Process

Chromium이 OpenGL/Metal/D3D 호출을 격리한 그래픽 전담 프로세스. Electron도 그대로 가져온다.

Renderer가 직접 GPU에 닿지 않고 GPU Process를 거친다 — 드라이버 크래시가 앱 전체를 죽이지 않게. chrome://gpu (Electron에서도 동작) 또는 app.getGPUFeatureStatus()로 상태 확인. 가상머신/원격 데스크톱에서는 종종 SwiftShader(소프트웨어 렌더링)로 폴백한다. app.disableHardwareAcceleration()으로 끌 수 있으나 시작 전(app.ready 전)에 호출해야 한다.

관련: [Renderer Process], [Zygote Process] 참고 챕터: 01-process-model, 07-performance-memory


invoke/handle

Renderer → Main 요청-응답 IPC 패턴. Promise 기반.

ipcRenderer.invoke('get-user', id)ipcMain.handle('get-user', async (e, id) => ...). 이전의 send/on은 발사 후 잊기(fire-and-forget)였고, invoke/handleawait 가능하다. 채널 이름은 좁게, 인자는 검증 — ipcMain.handle('exec', ...)처럼 일반 명령 노출 금물.

관련: [ipcMain], [ipcRenderer], [contextBridge] 참고 챕터: 03-ipc-bridge


ipcMain

Main 프로세스의 IPC 수신부. Renderer가 보낸 채널 메시지를 받아 처리한다.

ipcMain.handle(channel, handler) (요청-응답), ipcMain.on(channel, listener) (이벤트). handler의 첫 인자 eventevent.sender (webContents)로 어떤 창이 보냈는지 확인 가능 — 출처 검증의 1차 수단.

관련: [ipcRenderer], [invoke/handle], [webContents] 참고 챕터: 03-ipc-bridge


ipcRenderer

Renderer 프로세스의 IPC 송신부. Main 또는 다른 webContents로 메시지를 보낸다.

contextIsolation: true일 때 renderer에서 직접 import 불가 — preload에서 contextBridge로 좁게 감싸 노출해야 한다. invoke(요청), send(이벤트), sendSync(동기 — UI freeze 위험, 피할 것).

관련: [ipcMain], [contextBridge], [preload script] 참고 챕터: 03-ipc-bridge


Main Process

Electron 앱이 시작될 때 처음 뜨는 Node.js 프로세스 1개. BrowserWindow를 만들고 OS API를 직접 호출한다.

권한이 가장 강하다 — fs, child_process, Electron의 app/dialog/Tray/Menu 전부 여기서. 동시에 가장 느린 병목이 되기 쉽다 — Main이 sync I/O를 하면 모든 창이 멈춘다. 무거운 일은 Utility Process나 worker로 옮겨야 한다.

관련: [Renderer Process], [Utility Process], [app (module)] 참고 챕터: 01-process-model


MessagePort / MessageChannel

Main을 거치지 않고 두 webContents 사이에 직통 채널을 여는 Web 표준 API. Electron이 native 수준에서 지원.

port1.postMessage(...)port2.onmessage. Main의 ipcMain.handle 트래픽을 줄이거나, worker처럼 한 작업 전용 스트림이 필요할 때. Electron 7+ 이후 webContents.postMessage(channel, message, [port])로 port를 전달한다.

관련: [ipcMain], [ipcRenderer], [Worker] 참고 챕터: 03-ipc-bridge


nodeIntegration

Renderer에서 Node API를 직접 쓸 수 있게 하는 레거시 플래그. Electron 5+ 기본 false.

true로 켜면 renderer에서 require('fs')가 동작한다 — 편하지만 XSS 한 번에 OS가 뚫린다. 2024년 기준 어떤 새 코드에도 켜지 말 것. 켜야 한다는 요구는 거의 항상 preload + contextBridge로 해결 가능.

관련: [contextIsolation], [sandbox], [preload script] 참고 챕터: 05-security


preload script

Renderer가 페이지 스크립트를 실행하기 직전에 같은 컨텍스트에서 먼저 실행되는 스크립트.

webPreferences: { preload: path.join(__dirname, 'preload.js') }. contextIsolation: true라면 preload는 자기만의 격리된 컨텍스트에서 돌고, contextBridgewindow에 함수를 노출한다. preload는 Node 기능을 제한적으로 쓸 수 있고(sandbox: true일 땐 더 좁다), Electron 20+에서는 sandbox가 기본이라 preload도 sandbox 안에서 돈다.

관련: [contextBridge], [contextIsolation], [sandbox] 참고 챕터: 01-process-model, 03-ipc-bridge


process.type

현재 코드가 어느 프로세스에서 도는지 알려주는 Electron 확장 속성. 'browser' | 'renderer' | 'worker' | 'utility'.

Main은 'browser'라는 점이 헷갈린다(역사적 이름). 같은 파일이 여러 프로세스에서 import될 때 분기로 쓴다 — 단, 가능하면 분기 대신 파일 분리가 낫다.

관련: [Main Process], [Renderer Process], [Utility Process] 참고 챕터: 01-process-model


Renderer Process

한 BrowserWindow를 그리는 Chromium 렌더러 프로세스. 프로세스마다 격리된 V8 인스턴스.

창을 N개 띄우면 보통 N개의 renderer가 뜬다 — affinity로 같은 origin끼리 묶을 수 있지만 권장은 분리. Renderer는 OS에 직접 닿지 않고 preload를 통과한 IPC로만 닿는다.

관련: [Main Process], [BrowserWindow], [Zygote Process] 참고 챕터: 01-process-model


sandbox

Chromium의 OS-레벨 sandbox를 renderer + preload에 적용하는 보안 플래그. Electron 20+ 기본 true.

sandbox 안에서는 preload도 Node 전부를 못 쓰고 허용된 일부 모듈(electronipcRenderer, contextBridge 등)만 쓴다. 파일시스템·child_process는 막힌다. 현대 Electron의 보안 기본선 — 끄려면 강한 이유가 필요하다.

관련: [contextIsolation], [nodeIntegration], [Zygote Process] 참고 챕터: 05-security


session

쿠키·캐시·인증·permission·proxy를 담는 브라우저 컨텍스트 객체. webContents 1개에 1개.

session.defaultSession이 앱 전체 공통, session.fromPartition('persist:user1')로 사용자별 분리. permission 요청 핸들러(setPermissionRequestHandler), 인증서 검증(setCertificateVerifyProc), CORS 우회(webRequest) 등 보안 정책의 본진.

관련: [BrowserWindow], [webContents], [webSecurity] 참고 챕터: 02-window-lifecycle, 05-security


Utility Process

Main에서 spawn하는 Node.js 기반 보조 프로세스. Electron 22+ 1급 API.

utilityProcess.fork('worker.js') — Node child_process.fork와 비슷하지만 Electron이 알고 관리해 종료·로깅·MessagePort 전송이 잘 된다. 무거운 파일 인덱싱, OCR, 압축을 Main에서 분리할 때. Renderer와 달리 Chromium 없음 → 메모리 가볍다.

관련: [Main Process], [MessagePort], [Worker] 참고 챕터: 01-process-model, 07-performance-memory


V8 Snapshot

V8이 컨텍스트를 직렬화한 메모리 이미지. 시작 시 부트스트랩 시간을 줄인다.

Chromium은 자체 snapshot으로 빠르게 뜨고, Electron 앱은 electron-link + @electron/mksnapshot으로 자기 코드의 일부를 snapshot에 넣을 수 있다 (Atom 시절 유산). VS Code도 사용. 단점은 빌드 복잡도 — 대부분 앱은 일반 require로 충분.

관련: [V8], [Main Process] 참고 챕터: 07-performance-memory


webContents

한 페이지의 렌더링·네비게이션·이벤트를 다루는 객체. BrowserWindow의 핵심 내부.

win.webContents로 접근. loadURL, executeJavaScript, openDevTools, on('did-finish-load'), printToPDF, capturePage페이지 한 장에 대한 거의 모든 API가 여기. WebContents는 BrowserWindow 없이도 존재 가능 — BrowserView<webview>가 각각 자기 webContents를 가진다.

관련: [BrowserWindow], [BrowserView], [session] 참고 챕터: 02-window-lifecycle


webFrame

Renderer 안에서 자신의 frame에 작용하는 API. zoom·spellcheck·V8 cache.

webFrame.setZoomFactor(1.2), webFrame.insertCSS(...), webFrame.executeJavaScript(...). Renderer 전용(Main에서 못 씀). <iframe>이 있는 페이지에서는 frame마다 별도 webFrame이 있다.

관련: [webContents], [Renderer Process] 참고 챕터: 02-window-lifecycle


webPreferences

BrowserWindow 생성 시 보안·기능 옵션을 모은 객체.

{ preload, sandbox, contextIsolation, nodeIntegration, webSecurity, allowRunningInsecureContent, devTools }. 보안 5종 세트(contextIsolation: true, sandbox: true, nodeIntegration: false, webSecurity: true, allowRunningInsecureContent: false)는 모두 디폴트가 안전 — 끄는 옵션을 추가하지 말 것.

관련: [BrowserWindow], [sandbox], [contextIsolation], [webSecurity] 참고 챕터: 05-security


Worker (Web Worker / Node Worker)

Renderer 안의 Web Worker (브라우저 표준) 또는 Main의 Node Worker Thread.

Renderer에서 CPU 무거운 일을 백그라운드로 빼는 표준 방법. new Worker('worker.js', { type: 'module' }). Main에서는 worker_threads로 Node Worker Thread를 띄울 수도 있으나 Electron의 권장은 Utility Process — Node Worker는 Main 메모리를 공유해 격리가 약하다.

관련: [Utility Process], [Renderer Process] 참고 챕터: 07-performance-memory


Zygote Process

Chromium의 프로세스 fork 템플릿. 새 renderer를 빠르게 띄우는 시드 프로세스.

Linux/macOS에서 --type=zygote로 떠 있다가 새 renderer 요청 시 fork — JIT 워밍·라이브러리 로딩 비용을 절약한다. Activity Monitor/ps에서 정체 모를 Electron 자식 프로세스가 보이는 이유. Windows는 zygote 모델이 없음.

관련: [Renderer Process], [GPU Process], [Main Process] 참고 챕터: 01-process-model


부록: 자주 헷갈리는 짝

차이
nodeIntegration vs contextIsolation전자는 renderer에 Node를 줄지, 후자는 preload와 page를 격리할지. 보통 전자 false + 후자 true.
sandbox vs contextIsolation전자는 OS 레벨 격리, 후자는 JS 컨텍스트 격리. 둘 다 켜야 한다.
BrowserWindow vs webContents전자는 OS 창 + 옵션, 후자는 그 안의 페이지. 한 BrowserWindow에 webContents 여러 개일 수도(예: BrowserView).
ipcRenderer.send vs invoke전자는 fire-and-forget, 후자는 Promise. 새 코드는 invoke.
Utility Process vs Worker Thread전자는 별도 OS 프로세스, 후자는 같은 프로세스의 스레드. 격리 강도 차이.

더 읽기