"Next.js로 만든 웹사이트를 5MB짜리 .exe 파일로 만들 수 있다고?"
🤔 왜 데스크톱 앱이 필요한가?
웹 개발자인 나는 평소에 React, Next.js로 웹사이트를 만들었다. 그런데 클라이언트가 이런 요청을 했다:
"이거 웹사이트 말고 프로그램으로 만들어주세요. 더블클릭하면 실행되는 거요!"
아... 데스크톱 앱이라니. C++이나 C# 배워야 하나? 아니면 Python으로 PyQt 써야 하나?
그때 발견한 게 Tauri였다.
🎯 Tauri란 무엇인가?
"웹 기술로 데스크톱 앱을 만드는 프레임워크"
간단히 말하면:
React/Vue/Next.js로 만든 웹사이트
↓
Tauri로 빌드
↓
Windows/Mac/Linux 실행 파일 (.exe, .dmg, .AppImage)
Electron 아니야?
맞다. 비슷한 도구로 Electron이 있다. VS Code, Discord, Slack 같은 유명한 앱들이 Electron으로 만들어졌다.
그런데 Tauri는 Electron의 진화형이라고 보면 된다.
⚡ Electron vs Tauri 비교
실제로 "Hello World" 앱을 만들어서 비교해봤다.
파일 크기
Electron "Hello World": 147 MB 📦📦📦📦📦📦📦
Tauri "Hello World": 5 MB 📦
30배 차이!
메모리 사용량
Electron: ~150 MB
Tauri: ~30 MB
왜 이렇게 차이가 날까?
Electron:
┌─────────────────────────────────┐
│ Electron App │
├─────────────────────────────────┤
│ Chromium (브라우저 전체 내장) │ ← 이게 크다!
│ Node.js (런타임 내장) │
│ 내 앱 코드 │
└─────────────────────────────────┘
Tauri:
┌─────────────────────────────────┐
│ Tauri App │
├─────────────────────────────────┤
│ OS 기본 WebView 사용 │ ← 이미 설치되어 있음
│ Rust 런타임 (작음) │
│ 내 앱 코드 │
└─────────────────────────────────┘
Tauri는 OS에 이미 있는 브라우저를 사용한다!
- Windows: Edge WebView2
- macOS: Safari WebKit
- Linux: WebKitGTK
🏗 Tauri 구조
전체 구조
┌─────────────────────────────────────────┐
│ Tauri Desktop App │
├─────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────┐ │
│ │ Frontend (웹 기술) │ │
│ │ • HTML, CSS, JavaScript │ │
│ │ • React, Vue, Svelte... │ │
│ │ • Next.js도 가능! │ │
│ └───────────┬───────────────────┘ │
│ │ IPC (Inter-Process │
│ │ Communication) │
│ ┌───────────▼───────────────────┐ │
│ │ Backend (Rust) │ │
│ │ • 파일 시스템 접근 │ │
│ │ • 데이터베이스 │ │
│ │ • 시스템 API │ │
│ │ • 네이티브 기능 │ │
│ └───────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘
IPC (통신) 방식
Frontend에서 Backend 함수 호출:
// Frontend (TypeScript/React)
import { invoke } from '@tauri-apps/api/core';
async function greet() {
const response = await invoke<string>('greet', {
name: 'World'
});
console.log(response); // "Hello, World!"
}
// Backend (Rust)
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
마치 API 호출하듯이 사용!
🚀 실제로 만들어보기
1. 설치
# Node.js 필요 (18+)
npm create tauri-app@latest
대화형으로 선택:
✔ Project name · my-tauri-app
✔ Choose which language to use for your frontend · TypeScript
✔ Choose your package manager · npm
✔ Choose your UI template · React
✔ Choose your UI flavor · TypeScript
2. 프로젝트 구조
my-tauri-app/
├── src/ # Frontend (React)
│ ├── App.tsx
│ ├── main.tsx
│ └── ...
│
├── src-tauri/ # Backend (Rust)
│ ├── src/
│ │ └── main.rs # Rust 진입점
│ ├── Cargo.toml # Rust 의존성
│ └── tauri.conf.json # Tauri 설정
│
├── package.json # Node.js 의존성
└── ...
3. 개발 모드 실행
npm run tauri dev
자동으로 일어나는 일:
- Rust 백엔드 컴파일
- React dev server 시작 (Vite)
- 데스크톱 창 열림
- Hot Reload 활성화 (코드 수정 시 자동 새로고침)
4. 간단한 기능 추가
Rust 백엔드 (파일 읽기)
// src-tauri/src/main.rs
use std::fs;
#[tauri::command]
fn read_file(path: String) -> Result<String, String> {
fs::read_to_string(path)
.map_err(|e| e.to_string())
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![read_file])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
React 프론트엔드
// src/App.tsx
import { invoke } from '@tauri-apps/api/core';
import { useState } from 'react';
function App() {
const [content, setContent] = useState('');
async function handleReadFile() {
const fileContent = await invoke<string>('read_file', {
path: '/path/to/file.txt'
});
setContent(fileContent);
}
return (
<div>
<button onClick={handleReadFile}>파일 읽기</button>
<pre>{content}</pre>
</div>
);
}
5. 빌드
npm run tauri build
결과물:
- Windows: my-tauri-app.exe, my-tauri-app.msi
- macOS: my-tauri-app.dmg, my-tauri-app.app
- Linux: my-tauri-app.AppImage, my-tauri-app.deb
💡 실제 사용 사례
1. Screenpipe
- 기능: 24/7 화면/오디오 녹화 + AI 분석
- 이유: 백그라운드 실행 필요, 로컬 파일 접근
2. Cap
- 기능: Loom 대체 화면 녹화 앱
- 이유: 화면 캡처 API, 로컬 저장
3. Aptakube
- 기능: Kubernetes 클러스터 관리 UI
- 이유: kubectl 명령어 실행, 설정 파일 접근
🎨 Next.js와 통합하기
Tauri는 **Next.js SSG(Static Site Generation)**와 완벽하게 호환된다!
설정 방법
// tauri.conf.json
{
"build": {
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build",
"devPath": "http://localhost:3000",
"distDir": "../out" // Next.js 빌드 결과물
}
}
// next.config.js
module.exports = {
output: 'export', // SSG 모드
images: {
unoptimized: true // Tauri에서 필요
}
}
주의: Next.js SSR은 안 됨! SSG만 가능.
🔒 보안
Tauri의 강력한 보안 기능:
1. Allowlist (권한 시스템)
// tauri.conf.json
{
"tauri": {
"allowlist": {
"all": false, // 모든 API 기본 차단
"fs": {
"readFile": true, // 파일 읽기만 허용
"writeFile": false,
"scope": ["$APPDATA/myapp/*"] // 특정 디렉토리만
},
"shell": {
"open": true // URL 열기만 허용
}
}
}
}
2. CSP (Content Security Policy)
{
"tauri": {
"security": {
"csp": "default-src 'self'; script-src 'self'"
}
}
}
Electron과의 차이:
- Electron: 기본적으로 모든 권한 허용 (위험)
- Tauri: 기본적으로 모든 권한 차단 (안전)
⚠️ 단점과 한계
1. 러닝 커브
- Rust 문법: 처음엔 어려울 수 있음
- 하지만 간단한 앱은 Rust 몰라도 됨 (템플릿 복사!)
2. 생태계
- Electron이 훨씬 오래되어서 자료가 많음
- Tauri는 2019년 시작 (비교적 최신)
3. 플랫폼 차이
- OS마다 WebView가 다름 → CSS 미묘한 차이 있을 수 있음
- 철저한 크로스 플랫폼 테스트 필요
4. Next.js SSR 불가
- SSG만 가능
- API Routes도 불가
- Rust 백엔드로 대체해야 함
🎯 언제 Tauri를 쓸까?
✅ Tauri가 좋은 경우
- 가벼운 데스크톱 앱
- 파일 시스템 접근 필요
- 로컬에서만 동작
- 개인정보 보호 중요
- 빠른 성능 필요
❌ Tauri가 적합하지 않은 경우
- 웹으로 충분한 경우 (그냥 웹사이트가 나음)
- SSR 필수인 경우
- Rust 배우기 싫은 경우 (Electron 쓰세요)
📊 성능 벤치마크
실제 프로젝트에서 측정:
지표 Electron Tauri 차이
| 빌드 크기 | 147 MB | 5 MB | 30x |
| 메모리 (유휴) | 150 MB | 30 MB | 5x |
| 시작 시간 | 2.5초 | 0.8초 | 3x |
| CPU (유휴) | 2% | 0.5% | 4x |
🚦 시작하기 전 체크리스트
- [ ] Node.js 18+ 설치
- [ ] Rust 설치 (curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh)
- [ ] 웹 개발 경험 (React, Vue 등)
- [ ] 데스크톱 앱이 정말 필요한지 확인
🔗 유용한 리소스
- Tauri 공식 문서
- Tauri GitHub
- Awesome Tauri - 예제 앱 모음
- Tauri Discord - 커뮤니티
🎬 마무리
처음엔 "Rust라니 어렵겠지..."라고 생각했는데, 막상 써보니 생각보다 쉬웠다.
웹 개발자라면:
// 이런 코드만 쓸 줄 알면
const result = await invoke('my_function', { param: 'value' });
// Rust는 복붙하고 약간만 수정
#[tauri::command]
fn my_function(param: String) -> String {
format!("Hello, {}", param)
}
결론:
- 가볍고 빠른 데스크톱 앱이 필요하다면? → Tauri
- 기존 Electron 앱이 너무 무겁다면? → Tauri로 마이그레이션 고려
- 웹 개발자인데 데스크톱 앱 만들고 싶다면? → Tauri부터 시작
5MB짜리 .exe 파일의 매력, 한번 느껴보시길! 🚀
📝 다음 글 예고
다음엔 실제로 "Screenpipe + Tauri로 AI 채팅 앱 만들기" 튜토리얼을 작성해보겠습니다.
- Screenpipe 백엔드 통합
- Next.js 채팅 UI
- Rust로 AI API 호출
- 단일 .exe 파일로 배포
Stay tuned! 👋
'Tech Notes' 카테고리의 다른 글
| 앱 딥링크(Deep Link) 완벽 가이드 (0) | 2026.02.05 |
|---|---|
| [앱인토스] WebView 미니앱 테스트 방법 (0) | 2026.02.05 |
| Claude Code의 --continue와 --fork 완벽 가이드 : git 과 비슷 (0) | 2026.01.29 |
| [Claude] Agent 와 Tool 의 차이 (0) | 2026.01.28 |
| [Claude] CLAUDE.md 에 대하여 (0) | 2026.01.28 |