01. Bundler 비교 — electron-builder vs forge vs packager
어떤 빌드 도구를 고를지가 이 챕터의 첫 결정이다. 셋의 책임 경계는 다음과 같이 다르다 — packager는 “binary 복사기”고, forge는 “plugin 오케스트레이터”고, builder는 “yaml 한 파일로 all-in-one”이다. 이 결정이 서명·notarize·auto-update까지의 도구 사슬을 결정한다.
한 줄 답
Electron 빌드 도구는 책임 범위가 층층이 다르다 —
packager⊂forge⊂electron-builder(대략적인 기능 포함 관계). 신규 프로젝트는 거의 항상 electron-builder (사실상 표준)나 electron-forge (공식)로 시작한다.
Why — 왜 세 개나 있는가
Electron 배포는 너무 많은 단계가 있다 — Electron binary 다운로드, 소스 복사, asar 묶기, native module rebuild, OS별 installer 생성, 코드 서명, notarization, auto-update 메타 발행. 이 단계를 어디까지 한 도구가 책임지느냐로 갈렸다.
| 도구 | 출생 연도 | 시작 동기 |
|---|---|---|
| electron-packager | 2015 | ”그냥 Electron binary에 내 소스만 얹어주세요” — 최소 단위 |
| electron-builder | 2015 | ”전부 자동화” — yaml/json 한 파일에서 서명·notarize·publish까지 처리 |
| electron-forge | 2016 (재출시 2022 v6) | Electron 팀의 공식 도구 — plugin 모델로 확장성 |
v6 이전의 forge는 builder의 wrapper에 가까웠지만, v6부터는 자체 maker(installer 생성기) 를 갖춰 builder의 직접 경쟁자가 됐다.
How — 세 도구의 책임 경계
electron-packager — “그냥 복사기”
npx @electron/packager . MyApp \
--platform=darwin --arch=arm64 \
--out=dist \
--asar- 결과:
dist/MyApp-darwin-arm64/MyApp.app(그냥.app폴더 — 설치 파일 아님) - installer를 만들지 않는다. dmg, exe 만들려면 따로 도구 (electron-installer-dmg, electron-winstaller).
- 서명을 직접 지원하지 않는다 (옵션은 있지만 단순 wrapper).
- 강점: 단순함. CI 디버깅이나 “정확히 무엇이 일어나는지” 보고 싶을 때.
electron-forge — “공식 + plugin”
# 새 프로젝트
npm create electron-app@latest my-app -- --template=vite-typescript
# 빌드
npm run makeforge.config.ts 예시:
import type { ForgeConfig } from '@electron-forge/shared-types';
import { MakerSquirrel } from '@electron-forge/maker-squirrel';
import { MakerZIP } from '@electron-forge/maker-zip';
import { MakerDMG } from '@electron-forge/maker-dmg';
import { MakerDeb } from '@electron-forge/maker-deb';
import { VitePlugin } from '@electron-forge/plugin-vite';
import { PublisherGithub } from '@electron-forge/publisher-github';
const config: ForgeConfig = {
packagerConfig: {
asar: true,
osxSign: {
identity: 'Developer ID Application: My Co (XXXXX)',
'hardened-runtime': true,
},
osxNotarize: {
tool: 'notarytool',
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASSWORD,
teamId: process.env.APPLE_TEAM_ID,
},
},
makers: [
new MakerSquirrel({}), // Windows
new MakerDMG({}), // macOS dmg
new MakerZIP({}, ['darwin']), // macOS zip (auto-update용)
new MakerDeb({}), // Linux .deb
],
plugins: [new VitePlugin({ /* ... */ })],
publishers: [new PublisherGithub({ repository: { owner: 'me', name: 'app' } })],
};
export default config;- 강점: Electron 팀 공식, plugin 생태계 (Vite/Webpack 통합), TypeScript 친화적
- 약점: 다양한 maker를 직접 조립해야 함 (yaml 한 줄로 되지 않음). 문서 파편화.
electron-builder — “yaml 한 파일 all-in-one”
package.json에 build 키만 추가:
{
"name": "my-app",
"version": "1.4.2",
"scripts": {
"dist": "electron-builder"
},
"build": {
"appId": "com.example.myapp",
"productName": "MyApp",
"directories": { "output": "release" },
"files": ["dist/**/*", "node_modules/**/*"],
"asar": true,
"asarUnpack": ["**/*.node", "ffmpeg/**/*"],
"mac": {
"target": [
{ "target": "dmg", "arch": ["x64", "arm64"] },
{ "target": "zip", "arch": ["x64", "arm64"] }
],
"category": "public.app-category.productivity",
"hardenedRuntime": true,
"entitlements": "build/entitlements.mac.plist",
"notarize": true
},
"win": {
"target": [{ "target": "nsis", "arch": ["x64", "arm64"] }],
"publisherName": "My Co",
"signtoolOptions": {
"certificateSubjectName": "My Co Inc.",
"signingHashAlgorithms": ["sha256"]
}
},
"linux": {
"target": ["AppImage", "deb", "rpm"],
"category": "Office"
},
"publish": [{ "provider": "github", "owner": "me", "repo": "app" }]
}
}- 강점: yaml 한 파일로 7단계 전부 자동화. auto-update용
latest.yml/latest-mac.yml자동 생성. 대부분의 OSS Electron 앱이 이 도구. - 약점: yaml 옵션이 수백 개. 옵션 충돌 시 디버깅 어려움. monolithic 구조.
What — 결정 매트릭스
| 항목 | electron-packager | electron-forge | electron-builder |
|---|---|---|---|
| 유지보수자 | OpenJS Foundation (Electron 팀) | Electron 팀 (공식) | community (Vladimir Krivosheev 외) |
| NPM 다운로드 | |||
| installer 직접 생성 | ✗ (별도 도구) | ✓ (maker plugin) | ✓ (target 옵션) |
| code signing 통합 | 기본만 | ✓ (osxSign) | ✓ (모든 OS 통합) |
| notarization 통합 | ✗ | ✓ (osxNotarize) | ✓ (notarize: true) |
| auto-update 메타 | ✗ | ✓ (publisher) | ✓ (latest.yml) |
| 설정 위치 | CLI 옵션 | forge.config.ts | package.json 또는 electron-builder.yml |
| plugin/extensibility | ✗ | ✓ (plugin) | ✗ (옵션만) |
| TypeScript 친화 | △ | ✓ | △ (d.ts로 가능) |
| 공식성 | 공식 | 공식 | 비공식 |
| delta update | ✗ | △ | ✓ (block map) |
어느 것을 언제 고르나
| 상황 | 추천 |
|---|---|
| 새 OSS 프로젝트 + 최대 자동화 | electron-builder — 대부분 yaml만 잘 채우면 끝 |
| 새 프로젝트 + 공식 도구 선호 + Vite/Webpack 통합 | electron-forge v6 |
| legacy 빌드 시스템을 우리가 직접 짜고 있고, Electron binary만 필요 | electron-packager |
| VS Code/Slack처럼 완전 커스텀 파이프라인 | packager + 자체 스크립트 (실제로 VS Code는 이 모델) |
| Mac App Store 배포가 필수 | electron-builder (mas target) 또는 forge + maker-pkg |
| Microsoft Store (MSIX) 배포 | electron-builder (appx target) |
What-if — 잘못 골랐을 때
| 함정 | 증상 | 해결 |
|---|---|---|
| forge v5에서 멈춰서 v6로 못 옮기는 중 | maker 구성 호환성 깨짐 | v6 migration guide를 따르되, 큰 프로젝트는 builder로 옮기는 게 더 쉬울 수 있음 |
| builder yaml이 너무 길어져서 maintain 불가 | 옵션 1,000줄, 새 멤버가 이해 불가 | electron-builder.yml로 분리 + 주석 + extends 패턴 |
| packager + custom script로 시작했는데 auto-update 만들려니 막막 | Squirrel 메타 직접 생성해야 함 | builder의 --publish never + latest.yml만 빼서 자체 CDN 업로드 |
| 같은 코드가 forge에서는 빌드되는데 builder에서는 안 됨 | native 모듈 rebuild 정책 차이 | builder의 nodeGypRebuild / npmRebuild 옵션 확인 |
asar: false로 두고 빌드 → 시작이 5초 느림 | 수만 개 작은 파일을 OS가 stat | 항상 asar: true (네이티브만 asarUnpack) |
Insight — 흥미로운 이야기
“VS Code는 셋 다 안 쓴다”
Microsoft의 VS Code는 자체 빌드 스크립트 (gulp + 자체 packager wrapper) 를 쓴다. 이유 — VS Code는 Electron 버전을 upstream보다 한두 단계 앞서 쓰고, 빌드 단계에 V8 snapshot, 다국어 번들, Web 버전과의 공유 빌드 그래프 등 일반 도구가 못 따라가는 요구가 있다. 즉, “도구가 충분히 추상화되면 그걸 쓰고, 부족하면 직접 만든다”는 전형적 대형 앱 패턴. 우리 대부분은 그 임계점에 가지 않으므로 builder/forge면 충분하다.
“electron-builder는 Vladimir 한 명이 거의 다 짰다”
사실상 표준이 된 도구가 비공식·1인 메인테이너 (+소수 contributor) 라는 점은 Electron 생태계의 흥미로운 특징이다. 그래서 Electron 팀은 v6부터 forge를 적극 푸시하고 있다 — 공식 도구의 존재감을 높이기 위해. 다만 builder의 NPM 점유율이 너무 높아 현실은 builder가 사실상 표준인 상태가 몇 년 더 갈 가능성이 크다.
“forge v6는 사실상 재출시다”
v5까지의 forge는 builder의 wrapper에 가까웠고, v6에서 자체 maker 생태계로 다시 만들었다. 2022년 출시 이후 Electron 팀 블로그에서 적극 홍보하지만, 기존 v5 사용자의 migration 부담 때문에 교체 속도는 느리다. “공식 도구가 항상 사실상 표준이 되지는 않는다”라는 OSS의 전형적 패턴.
요약 + Mermaid
세 도구의 책임 경계가 다르다 — packager는 1~3단계 (binary 복사), forge/builder는 1~7단계 전부. 사실상 표준은 electron-builder (점유율), 공식 도구는 electron-forge (Electron 팀 추천). 신규 프로젝트는 둘 중 하나로 시작하고, packager는 학습/디버깅·완전 커스텀 시나리오에서만 쓴다.