03 — Wails & Neutralino
한 줄 답: Tauri만 대안이 아니다. Wails는 Go 백엔드 + OS webview를 묶어 Go 개발자에게 자연스러운 데스크톱 앱을 약속하고, Neutralino는 C++ 코어 + Node 없는 런타임으로 극단적인 작은 번들을 달성한다. 둘 다 팀 언어 스택과 일치할 때만 합리적 — 생태계 크기는 Electron·Tauri의 1/10 이하.
Why — 왜 또 다른 대안이 필요한가
Electron이 Node 팀, Tauri가 Rust 팀을 위한 답이라면 — Go 팀과 C++ 팀은? 데스크톱 GUI 시장은 언어별로 분절되어 있고, 각 언어 커뮤니티는 *“우리 언어로 데스크톱 앱을 짓고 싶다”*는 욕구가 있다.
백엔드 언어 → 자연스러운 데스크톱 도구
JavaScript → Electron
Rust → Tauri
Go → Wails
C++ (가벼움) → Neutralino
C++ (full UI) → Qt
C# / .NET → MAUI · Avalonia · WinUI
Dart → Flutter Desktop
Swift → AppKit (macOS only)→ *“우리 회사 백엔드가 Go”*인 팀이 데스크톱 도구를 만들 때 — 그 도구만 JS로 작성하기 싫다는 욕구가 Wails의 출발점.
How — Wails 개요
구조
코드 예시
// app.go
package main
import (
"context"
"fmt"
"os"
)
type App struct {
ctx context.Context
}
func (a *App) ReadFile(path string) (string, error) {
data, err := os.ReadFile(path)
if err != nil {
return "", fmt.Errorf("read failed: %w", err)
}
return string(data), nil
}
func main() {
app := &App{}
wails.Run(&options.App{
Title: "MyApp",
Width: 1024,
Height: 768,
Bind: []interface{}{app}, // 메소드가 JS에 노출됨
})
}// 프론트엔드 (TypeScript)
import { ReadFile } from '../wailsjs/go/main/App'; // 자동 생성
const content = await ReadFile('/path/to/file');→ struct의 public 메소드가 그대로 JS의 async 함수가 된다. TypeScript 타입 자동 생성. Electron의 ipcMain.handle 같은 채널 이름 관리 없음.
Wails의 장점
| 측면 | Wails 우위 | 이유 |
|---|---|---|
| 번들 크기 | ~10MB | OS webview + Go 단일 바이너리 |
| 시작 시간 | ~0.3-0.7초 | Go 시작 빠름 |
| 메모리 | ~50-100MB | Node 없음 |
| Go 표준 라이브러리 | 그대로 | net/http, os, sync 등 |
| 동시성 | Goroutine | Node의 단일 스레드보다 자연스러움 |
| 배포 | 단일 바이너리 | go build 한 줄 (cross compile) |
| 타입 자동 생성 | TS 인터페이스 | 메소드 시그니처에서 |
Wails의 한계
| 측면 | 한계 | 영향 |
|---|---|---|
| 생태계 | npm의 1/100 | UI 라이브러리는 그대로 쓰지만, 데스크톱 특화 모듈 빈약 |
| 문서 | 영어 위주 · 한국어 빈약 | 학습 곡선 |
| 커뮤니티 | 작음 | 문제 발생 시 Stack Overflow 답 적음 |
| OS webview 차이 | Tauri와 동일한 함정 | WKWebView/WebView2/WebKitGTK |
| 모바일 | 없음 | 데스크톱 전용 |
| 디버깅 | Go ↔ JS 양쪽 | 익숙해지면 OK, 처음은 어려움 |
How — Neutralino 개요
출발점
Neutralino의 슬로건은 “Lightweight cross-platform desktop app framework”. Tauri보다도 가벼움을 목표.
Electron: Chromium + Node + 앱
Tauri: OS webview + Rust + 앱
Neutralino: OS webview + C++ 작은 코어 + 앱 (Node 없음)구조
특징
- Node 없음 — 백엔드가 C++ 단일 바이너리. 언어를 안 묶음.
- 확장 가능 — extension 메커니즘으로 Node·Python·Go·Rust를 외부 프로세스로 붙일 수 있음.
- 번들 ~5MB — Tauri보다도 작음 (Tauri는 Rust 표준 라이브러리 포함, Neutralino는 C++ 코어만).
- WebSocket 기반 IPC — 프론트와 코어가 WebSocket으로 통신. 디버깅·로깅이 브라우저 도구로 가능.
코드 예시
// 프론트엔드 (vanilla JS — 어떤 프레임워크도 가능)
import { os, filesystem } from '@neutralinojs/lib';
const content = await filesystem.readFile('/path/to/file');
const cpus = await os.execCommand('sysctl -n hw.ncpu');// 확장 호출
const result = await Neutralino.extensions.dispatch('my-python-ext', 'process', { data: '...' });→ Python으로 AI 추론을 하는 데스크톱 도구를 Neutralino 코어 + Python extension으로 짤 수 있다 — Node 안 거치고.
Neutralino의 한계
| 측면 | 한계 | 영향 |
|---|---|---|
| 커뮤니티 | 매우 작음 (GitHub Stars ~9k) | 라이브러리·예시 부족 |
| 문서 | 기본기만 | 복잡 케이스는 직접 풀어야 함 |
| OS API 깊이 | 얕음 | 트레이·메뉴는 OK, 깊은 통합은 어려움 |
| 코드 서명·notarization | 직접 | electron-builder 같은 통합 도구 없음 |
| 자동 업데이트 | 별도 구현 | Electron의 electron-updater 없음 |
| WebSocket 의존 | 보안 검토 필요 | localhost 바인딩이지만 원리상 표면 |
| 디버깅 도구 | 빈약 | DevTools 통합 약함 |
→ Neutralino는 극단적인 가벼움과 언어 자유를 약속하지만 — 운영 인프라가 전부 직접이라는 비용. 소규모·내부 도구에 적합.
What — 4가지 도구의 비교
| 측면 | Electron | Tauri | Wails | Neutralino |
|---|---|---|---|---|
| 백엔드 언어 | JavaScript (Node) | Rust | Go | C++ (확장 가능) |
| 번들 크기 | ~120MB | ~10MB | ~10MB | ~5MB |
| 시작 시간 | ~1.5초 | ~0.5초 | ~0.4초 | ~0.3초 |
| 메모리 (idle) | ~150MB | ~100MB | ~70MB | ~60MB |
| webview | 번들 Chromium | OS webview | OS webview | OS webview |
| 생태계 (GitHub Stars) | 113k | 80k | 25k | 9k |
| npm/crate 통합 | npm 완벽 | crates.io 좋음 | Go 표준 좋음 | 별도 |
| 자동 업데이트 | electron-updater 성숙 | tauri-updater 있음 | wails-updater 미성숙 | 없음 (직접) |
| 코드 서명·notarization | electron-builder | tauri 통합 OK | 직접 | 직접 |
| 모바일 | 없음 | Tauri 2.0 | 없음 | 없음 |
| 한국어 자료 | 풍부 | 늘어남 | 적음 | 거의 없음 |
| 회사 입문 난이도 | 낮음 | 보통 | 보통 (Go 팀) | 높음 |
What — 언제 Wails가 옳은가
적합 시나리오
실제 사용 예
- 체커리(Checkrr) — 미디어 라이브러리 검증 도구. Go 백엔드의 데스크톱 GUI.
- CodeNation IDE 프로젝트 — Go 학습자용 작은 IDE.
- 사내 클러스터 관리 도구 — Kubernetes/Go 백엔드와 같은 언어로 작성.
부적합 시나리오
- 팀이 Go를 모름 — Rust보다 학습이 쉽지만, 없는 언어 새로 배움은 비용.
- 모바일 동시 출시 필요.
- 복잡 UI + Chromium 통일성 critical.
- 대규모 외부 사용자 (생태계·운영 인프라 부족).
What — 언제 Neutralino가 옳은가
적합 시나리오
- 극단적인 가벼움이 USP — 총 번들 < 10MB가 마케팅 포인트.
- 내부 도구 — 생태계 부족을 팀이 직접 풀 수 있는 작은 도구.
- 다언어 백엔드 — Python AI 추론 + JS UI + C++ 코어를 한 데스크톱 앱으로.
- 임베디드 데스크톱 — IoT 게이트웨이의 작은 GUI (Raspberry Pi 등).
부적합 시나리오
- 대규모 외부 출시 — 운영 인프라(업데이트·사이닝·notarization) 없음.
- 복잡 OS API — 깊은 통합은 Electron이 압도적.
- 팀이 작음 + 자체 해결 능력 부족.
What-if — 잘못 선택했을 때
1) 팀이 JS인데 “가볍다”고 Wails 도입
→ Go 학습 6개월. 표준 라이브러리·툴체인·테스트 프레임워크 전부 새로움. 6개월 뒤 Tauri 또는 Electron 회귀. 대응: Wails는 Go 팀 전용. JS 팀이면 Tauri (가벼움) 또는 Electron (생태계).
2) 외부 출시 앱을 Neutralino로
→ 자동 업데이트 직접 구현. 코드 사이닝·notarization 전부 직접. macOS Gatekeeper에서 안 열림 → 사용자 불만 폭주. 대응: 외부 출시는 Electron 또는 Tauri. Neutralino는 내부 도구 전용.
3) 복잡 UI를 Wails로
→ Tauri와 같은 OS webview 차이 문제 + Wails 자체의 미성숙 (라이프사이클 이벤트 등) . 1년 뒤 Electron으로 회귀. 대응: 복잡 UI는 Electron. Wails는 간단~중간에 한해.
4) Neutralino의 극단적인 가벼움에 끌려 도입
→ 모든 운영 인프라 직접 구현 — 자동 업데이트, 사이닝, 충돌 리포트, 분석. 대응: 가벼움이 진짜 USP가 아니면 Tauri로 충분. Neutralino는 진짜 임베디드/극단 케이스만.
Insight — 흥미로운 이야기
”Wails의 출발 — Go의 데스크톱 야망”
Go는 서버 사이드 1위급 언어지만 데스크톱 GUI는 약점이었다. Fyne·Gioui 등 순수 Go GUI 라이브러리가 있지만 모양이 OS native와 어색. Wails는 Go 백엔드 + 웹 UI로 Go의 GUI 빈자리를 채웠다.
흥미로운 건 — Wails v1(2019)은 임베디드 Chromium이었다가, v2(2022)에서 OS webview로 전환. 즉 Wails는 Electron 스타일 → Tauri 스타일로 변천한 도구. 같은 시기 Tauri가 처음부터 OS webview로 시작한 것과 수렴했다.
”Neutralino — Sri Lanka의 한 명의 프로젝트”
Neutralino의 메인테이너 Shalitha Suranga는 Sri Lanka의 학생/엔지니어. 2020년 한 명의 사이드 프로젝트로 시작해 2024년 현재 GitHub Stars 9k. 극단적인 가벼움이라는 단 하나의 USP로 틈새 시장을 잡았다.
→ 생태계가 작다는 것은 작은 팀이 결정에 빠르게 반영된다는 것과 대규모 운영에는 적합 안 한다는 것이 동전의 양면.
”한국 — Go 데스크톱 사례”
한국 IT에서 Wails 사용 사례는 오픈소스·사이드 프로젝트 위주. 카카오·우아한형제들 등의 내부 도구에서 Go 백엔드의 작은 GUI (배포 도구, 로그 뷰어 등)로 간간이 쓰임. 외부 공개 앱에 적용된 사례는 공개적으로 드뭄.
→ 언어 다양성과 생태계 채택은 항상 trade-off. 외부 공개는 Electron의 안정성이 압승.
”C++ 데스크톱의 90년대 vs 2020년대”
C++로 데스크톱 GUI를 만든다면 Qt가 사실상 표준이고 MFC·WTL·wxWidgets가 그 뒤. Neutralino는 그 C++ 전통과는 다른 길 — 웹 UI + C++ 코어. Native UI 안 만들고 web으로 가는 것이 2020년대 답임을 인정한 사례.
요약 + 다이어그램
Wails는 Go 팀의 데스크톱 답 — Tauri와 비슷한 구조(OS webview + 컴파일 언어 백엔드)지만 Go의 동시성·표준 라이브러리·단일 바이너리 배포가 자연스럽다. Neutralino는 극단적 가벼움 + 언어 자유의 답 — 번들 ~5MB, 어떤 언어로든 extension. 그러나 생태계·운영 인프라 부족으로 내부 도구 전용에 가깝다. 두 도구 다 팀 언어 스택과 일치할 때만 합리적이고, 그렇지 않다면 Electron·Tauri의 큰 생태계가 압도적이다.
다음 문서:
04-pwa-and-tauri-mobile.md— 데스크톱 설치가 반드시 필요한가? PWA로 충분한 자리와 Tauri 2.0의 모바일 지원.