Flutter Desktop & 네이티브 옵션
이 문서가 답하는 질문: “웹 기술이 아닌 데스크톱 옵션 — Flutter Desktop, .NET MAUI, Qt, 순수 네이티브 — 는 언제 정답인가?” 한 줄 답 (Pyramid Top): “웹 컴포넌트 재사용이 제로에 가깝거나 그래픽 정밀도·성능이 핵심이면, 웹 wrapper(Electron/Tauri)를 떠나 네이티브 또는 GPU 기반 UI(Flutter Skia)로 가는 게 답이다.”
Why — 왜 존재하는가
Electron·Tauri는 HTML/CSS/JS를 데스크톱에 가져온 것이다. 그 모델이 부적합한 자리가 있다:
| 시나리오 | 이유 | 대안 |
|---|---|---|
| 60fps 복잡 애니메이션 | 웹 렌더러 한계 | Flutter (Skia GPU 렌더) |
| 시스템 깊은 통합 | 권한·UI 제한 | 순수 네이티브 (Cocoa/WPF) |
| 디자인 시스템 100% 통제 | 웹 컴포넌트는 OS 베끼기 | Flutter (자체 위젯) |
| Microsoft 생태계 | .NET 라이브러리 | .NET MAUI |
| 크로스 OS 풀스택 (임베디드 포함) | RTOS·임베디드 | Qt |
How — 어떻게 동작하는가
Flutter Desktop
OS UI를 흉내내지 않는다 — 모든 픽셀을 직접 그린다. 결과: 모든 OS에서 픽셀 단위 동일. 단점: OS 네이티브 느낌과 미묘하게 다름.
.NET MAUI
Microsoft가 Xamarin Forms를 잇는 후계자로 만든 크로스 플랫폼 .NET UI.
What — 구체 사양·수치·예시
Flutter Desktop — 사이즈/시작 시간
| 지표 | Flutter | Electron |
|---|---|---|
| Hello World 번들 | ~20MB | ~100MB |
| 시작 시간 | ~300ms | ~1.5s |
| 메모리 | ~80MB | ~150MB+ |
| 60fps 보장 | ✓ (대부분) | △ (CSS animation 한계) |
Flutter Desktop의 한계
// 시스템 트레이? 외부 패키지 필요
// dependencies:
// tray_manager: ^0.2.0
import 'package:tray_manager/tray_manager.dart';
await trayManager.setIcon('assets/icon.png');시스템 트레이·메뉴바·다이얼로그 같은 데스크톱 OS 통합은 외부 패키지에 의존 — 안정성·일관성이 Electron만큼은 아님.
.NET MAUI 컴포넌트
{/* MainPage.xaml */}
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui">
<VerticalStackLayout>
<Label Text="Hello, .NET MAUI!" FontSize="32"/>
<Button Text="Click" Clicked="OnClicked"/>
</VerticalStackLayout>
</ContentPage>// MainPage.xaml.cs
private void OnClicked(object sender, EventArgs e) {
Counter.Text = $"Clicked {++count} times";
}Qt (C++ 또는 PyQt/PySide)
# PySide6 (Qt의 Python 바인딩)
import sys
from PySide6.QtWidgets import QApplication, QPushButton, QMainWindow
app = QApplication(sys.argv)
window = QMainWindow()
button = QPushButton('Click me')
button.clicked.connect(lambda: print('clicked'))
window.setCentralWidget(button)
window.show()
app.exec()수십 년 검증된 데스크톱 프레임워크. KDE, Telegram Desktop, OBS Studio, Krita 등이 Qt 기반.
순수 네이티브
| OS | 언어 | 프레임워크 | 사례 |
|---|---|---|---|
| macOS | Swift | SwiftUI / AppKit | Things, Reeder, Xcode |
| Windows | C# / C++ | WinUI 3 / WPF / Win32 | Visual Studio, Photoshop |
| Linux | C / C++ | GTK / Qt | GIMP, Inkscape |
사례 매트릭스
| 회사/제품 | 사용 도구 | 이유 |
|---|---|---|
| Telegram Desktop | Qt | 일관된 UX·고성능 |
| Discord | Electron | 웹 코드 재사용 |
| WhatsApp Desktop (구) | Electron → React Native | iOS/Android 코드 재사용 |
| Xcode | Native macOS | OS 깊은 통합 |
| Visual Studio | Native Windows | OS 깊은 통합 |
| VS Code | Electron | 웹 생태계 통합 |
| Figma Desktop | Electron | 웹 앱 그대로 |
| Spotify Desktop | CEF (Chromium Embedded Framework) | 웹 코드 + Chromium |
| Adobe XD/Photoshop | Native + CEP (Chromium) | 하이브리드 |
| Krita | Qt | OpenGL 픽셀 정확도 |
| Notion Desktop | Electron | 웹 앱 wrapping |
What-if — 잘못 쓰면
- 함정 1: Flutter Desktop을 대규모 데스크톱 앱으로 → *데스크톱 패턴(트레이·메뉴·다중 창)*이 첫 솔루션이 아님. 작은 도구나 단일 창 앱에 적합.
- 함정 2: 순수 네이티브로 3 OS 동시 → 코드베이스 3배·인력 3배. *코어가 정말 OS 통합인가?*가 절대 기준.
- 함정 3: .NET MAUI를 macOS-primary로 → macOS 지원은 후순위. Mac은 Catalyst 기반.
- 함정 4: Qt 라이센스 — 상용 라이센스가 비쌈. LGPL 옵션이 있지만 동적 링크 제약.
Insight — 흥미로운 이야기
“Telegram Desktop과 WhatsApp Desktop의 정반대 선택”
2014년 Telegram Desktop은 Qt를 골랐다. Pavel Durov는 “우리는 사용자가 다른 어떤 메신저보다 빠르게 반응한다고 느껴야 한다”고 했고 — Qt의 60fps GPU 렌더가 그 약속을 가능하게 했다. Telegram Desktop은 오늘날도 startup 200ms 미만, 메모리 50MB대로 동작한다.
같은 시기 WhatsApp Desktop은 Electron을 골랐다 — 모바일과 같은 웹 코드를 desktop에 가져오는 것이 우선이었다. 결과는 같은 메신저인데 시작 1.5초, 메모리 150MB+. 사용자 인식도 따라갔다 — *“Telegram이 더 빠르고 가볍다”*는 평이 굳어졌다.
그러나 2021년 WhatsApp이 React Native로 재작성하기 시작했다. 이유는 모바일 코드의 완전한 재사용. Telegram은 여전히 Qt — 데스크톱 제품 성능이 코어 가치인 회사의 선택이다.
교훈은 — 도구는 제품의 첫 가치가 무엇인지를 가린다. 빠른 데스크톱이면 Qt/네이티브. 모바일 통합이면 RN/Capacitor. 웹 코드 재사용이면 Electron. 픽셀 정밀도면 Flutter.
요약
- Flutter Desktop = Skia GPU 렌더, 픽셀 정밀.
- .NET MAUI = Microsoft 생태계 + WinUI 깊은 통합.
- Qt = 검증된 고성능 데스크톱, 임베디드까지.
- 네이티브 = OS 통합이 코어 가치일 때.
- 제품 첫 가치 결정 → 도구 결정. 도구가 먼저 정해진 결정은 대개 후회한다.