Show HN: Flutter를 통한 Rust GUI 라이브러리
(cjycode.com)- Rust로 GUI 프로그램을 만들고 싶은 개발자를 위해 Rust 상태·로직은 그대로 두고 Flutter UI를 붙이는 방식을 제안함
- Flutter의 성숙한 크로스플랫폼 SDK와 위젯 생태계, 픽셀 단위 제어, hot reload가 UI 반복 작업을 빠르게 만듦
- 100% 순수 Rust 접근은 아니지만, HTML/CSS/Slint나 매크로 기반 DSL처럼 UI 계층을 분리하는 기존 Rust UI 절충안과 비슷함
flutter_rust_bridge는 임의 타입,&mut, async, traits, results, closure, lifetimes 등을 자동 변환해 Rust와 Flutter 사이의 브리지가 됨- 카운터 앱과 todo-list 앱 예제로 구조를 확인할 수 있으며, 전체 코드는
flutter_rust_bridge저장소의 예제 디렉터리에 있음
Rust GUI에 Flutter를 붙이는 방식
- Rust는 StackOverflow와 GitHub 기준으로 8년 동안 “가장 원하는 프로그래밍 언어”로 꼽혔고, Rust로 GUI 프로그램을 만들고 싶어 하는 수요가 큼
- 제안된 방식은 Flutter와 flutter_rust_bridge를 사용해 Rust 프로그램에 GUI를 붙이는 것임
- 직접 실행하려면 GitHub 저장소나 데모 폴더를 활용할 수 있음
Flutter를 쓰는 이유
- Flutter는 StackOverflow 기준 “가장 인기 있는 크로스플랫폼 모바일 SDK”로 꼽혔고, 여러 개발자와 브랜드가 사용 중임
- 풍부한 위젯 생태계 덕분에 원하는 UI 기능을 구현하기 쉬움
- confetti 애니메이션 같은 패키지도 존재함
- 다양한 위젯과 기능, 픽셀 단위 제어 유연성을 제공함
- hot reload는 UI 조정이 잦은 개발 과정에서 반복 속도를 높임
- 코드 변경 후 상태를 잃지 않고 거의 즉시 업데이트된 UI를 볼 수 있음
- 재컴파일을 기다리는 시간이 줄어듦
- 같은 코드베이스를 Android, iOS뿐 아니라 Linux, MacOS, Windows, Web에서도 실행할 수 있음
순수 Rust가 아니라는 절충
- 이 접근은 100% 순수 Rust가 아님
- Rust가 상태와 로직을 담당하고, Flutter가 UI를 담당하는 구조임
- 매크로로 만든 커스텀 DSL, HTML/CSS/Slint 같은 다른 언어를 쓰는 Rust UI 방식과 유사함
- 이런 분리는 관심사 분리에 맞고, 다른 사례에서도 채택된 방식임
- Flutter는 Rust를 이해하고 있다면 배우기 쉽다고 봄
- Web 플랫폼에는 일부 비판이 있으며, 정적 웹페이지보다는 Google Earth나 Rive 애니메이션 에디터 같은 “앱” 형태에 더 적합해 보임
- Flutter에는 보일러플레이트와 스캐폴드 코드가 많음
- 작은 프로젝트에서는 대개 해당 파일들을 바꾸지 않아 없는 것과 비슷하게 볼 수 있음
- 큰 프로젝트에서는 수정 가능성이 곧 커스터마이즈 가능성으로 이어짐
flutter_rust_bridge가 연결하는 것
flutter_rust_bridge의 목표는 Rust와 Flutter 사이를 하나의 언어처럼 자연스럽게 연결하는 것임- 여러 요소를 자동 변환함
- 임의 타입
&mut- async
- traits
- results
- closure(callback)
- lifetimes
- “Flutter를 통한 Rust GUI”는 가능한 사용 사례 중 하나임
- 다른 사용 예로는 Flutter에서 임의의 Rust 라이브러리를 쓰거나, 알고리듬 같은 코드는 Rust로 작성하고 나머지는 Flutter로 작성하는 방식이 있음
카운터 앱 예제
- 예제는 Rust와 Flutter를 통합하는 여러 방법 중 하나임
flutter_rust_bridge는 특정 구조를 강제하지 않는 범용 도구라서 Redux식 또는 Elm식 접근도 가능함- Rust 쪽은
#[frb(ui_state)]로 상태를 정의하고,#[frb(ui_mutation)]으로 변경 메서드를 표시함RustState는count: i32를 가짐new()는count를100으로 초기화함increment()는count를 1 증가시킴
#[frb(ui_state)]와#[frb(ui_mutation)]은 매우 가벼우며, 내부에 숨겨진 마법은 없고 코드도 10여 줄 정도라고 함- Flutter UI는 선언형으로 작성됨
- 현재 카운트를 보여주는
Text state.increment를 호출하는TextButton- 두 요소를 컬럼으로 묶고 padding을 적용함
- 현재 카운트를 보여주는
- 실행 중 UI를 수정하면 hot reload로 변경 사항을 즉시 확인할 수 있음
Todo-list 앱 예제
- todo-list 앱은 완결성을 위한 선택 섹션이며,
flutter_rust_bridge가 지원할 수 있는 여러 접근 중 하나임 - Rust 상태는 todo 항목과 입력 텍스트, 필터, 다음 ID를 포함함
items: Vec<Item>input_text: Stringfilter: Filternext_id: i32
Item은id,content,completed를 가짐Filter는All,Active,Completed를 가짐- 상태 변경 동작은
#[frb(ui_mutation)]아래에 구현됨add()는 현재 입력 텍스트로 항목을 추가하고 입력을 비움remove(id)는 해당 ID의 항목을 제거함toggle(id)는 완료 상태를 반전함
- 비즈니스 로직은
filtered_items()와Filter::check()로 구성됨All은 모든 항목을 통과시킴Active는 완료되지 않은 항목만 통과시킴Completed는 완료된 항목만 통과시킴
- Flutter UI는 텍스트 필드, 리스트 뷰, 필터 버튼 row를 컬럼으로 배치함
SyncTextField는 입력 변경과 제출을 Rust 상태 변경에 연결함- 각 todo 항목은 체크박스, 텍스트, 삭제 버튼으로 구성됨
코드 위치와 실행
- 전체 코드는 flutter_rust_bridge 저장소에 있음
frb_example/rust_ui_counterfrb_example/rust_ui_todo_list
- 대부분은 Flutter 기능 때문에 생기는 자동 생성 보일러플레이트 파일임
- 핵심 파일은
src/app.rs와ui/lib/main.dart임 - 데모 실행은
ui디렉터리에서 다음 명령을 실행함flutter_rust_bridge_codegen generate && flutter run
댓글과 토론
Hacker News 의견들
-
지난 몇 년간 이걸로 앱[0]을 만들고 있는데, 약간 거친 부분은 있어도 전반적으로 쓰기 즐거웠고 만족스러웠음
v1에서 v2로 올리는 것도 어렵지 않았고, v2는 유용한 기능이 많아 큰 업그레이드였음
특히 코드 생성 경험 개선과 tokio 비동기 지원이 큰 전환점이었음
앱의 비즈니스 로직은 Rust로 쓰고 프런트엔드는 Dart로 두는 구성이 잘 맞았고, HN에서 Flutter/Dart가 별로 사랑받지 못하는 건 알지만 React 같은 시스템보다 추론하기 훨씬 쉽다고 봄
React는 Flutter처럼 전체 위젯 트리를 렌더링하는 접근에 비해 추상화 수준이 맞지 않는다고 느낌
[0]: https://saveoursecrets.com- Flutter 자체는 나쁘지 않지만, Google이 통제하는 제품이라는 점 때문에 깊게 들어가기가 망설여짐
Google 제품을 쓰면 언제 사라질지 모른다는 위협을 계속 받는 느낌임
또 여전히 모바일과 손가락 중심의 흔적이 남아 있고, 데스크톱과 마우스 지원 개선은 내 경험상 거의 없었음 - Flutter와 React가 컴포넌트 접근에서 꽤 비슷하다고 생각했는데, 이 부분을 조금 더 설명해 줄 수 있는지 궁금함
Flutter 경험이 많지 않아서 실제로 어떻게 느꼈는지 듣고 싶음 - Flutter와 React는 둘 다 UI가 상태의 함수라는 방식으로 동작함
사실 Flutter도 처음에는 명령형으로 시작했지만 React 출시 이후 선언형으로 바뀌었고, Android도 Jetpack Compose를 통해 같은 원칙의 선언형으로 가는 중임
flutter_hooks나 ReArch 같은 패키지를 쓰면 상태 캡슐화가 훨씬 쉬워지고, 기능마다 initState를 쓰고 dispose를 잊지 않아야 하는 방식은 견디기 어려웠음 - Flutter/Dart가 정말 마음에 듦
React 자체보다 HTML/CSS/JavaScript 생태계와 도구 체인이 더 큰 문제였고, Flutter는 UI를 위해 목적에 맞게 만들어진 생태계라 신선함
SDK를 설치하면 핫 리로드 같은 기능이 기본으로 준비되어 있고, 여러 도구를 조합해 동작 방식을 파악할 필요가 없음
HTML + CSS가 필요 없다는 점도 큼
더 인기가 없는 이유는 이미 HTML/CSS/JS에 익숙한 프런트엔드 개발자가 너무 많기 때문으로 보이고, 전통적인 GUI 패러다임에 익숙한 사람에게는 Flutter가 처음부터 훨씬 단순하고 쉽다고 봄
- Flutter 자체는 나쁘지 않지만, Google이 통제하는 제품이라는 점 때문에 깊게 들어가기가 망설여짐
-
Rust로 UI를 쓰는 게 Dart보다 어떤 장점이 있는지는 잘 모르겠지만, flutter_rust_bridge는 매우 좋아함
fzyzcjy와 커뮤니티가 Dart에서 Rust 코드를 매끄럽게 호출할 수 있게 만든 작업은 Flutter 앱에 큰 자산임
webp가 지원되지 않아서 인기 이미지 압축 앱 ImageOptim을 Flutter로 주말 동안 다시 만들었는데, 초기 설정에서 약간 고생한 뒤 flutter_rust_bridge와 작은 래퍼[0]로 성숙한 Rust 이미지 라이브러리를 호출할 수 있었고 병렬 처리도 알아서 처리해 줬음
결과적으로 앱은 ImageOptim보다 기능도 많고 더 빨랐는데, 대부분 Rust 통합 덕분이었음
[0]: https://github.com/blopker/alic/blob/main/rust/src/api/compr...- flutter_rust_bridge를 처음 개발할 때의 개인 사용 시나리오도 비슷했음
일부 고성능 알고리즘에는 Rust를 쓰는 방식이었음
- flutter_rust_bridge를 처음 개발할 때의 개인 사용 시나리오도 비슷했음
-
훌륭한 노력임
지금 프로젝트에서 Tauri를 쓰고 있는데, 둘 사이의 장단점을 아는 사람이 있는지 궁금함- JavaScript를 쓰는 앱에서는 Tauri가 Electron을 대체해 가고 있고 요즘 인기가 있다는 얘기를 들었음
다만 Tauri는 아직 Rust와 JavaScript가 아주 매끄럽게 통신하게 해 주지는 못하는 듯하고, 예를 들어 https://tauri.app/v1/guides/features/command/도 주로 기본 기능 위주로 보임
아래에서 언급된 것처럼 Tauri는 아직 모바일을 일급 지원 대상으로 보지 않는다는 점도 있음
앞으로 Tauri의 브리지가 개선되고 모바일 지원도 좋아지길 기대함 - 내가 보기에는 Tauri를 써 보지는 않았고 Flutter도 몇 년 전이 마지막이지만, Tauri는 현재 모바일과 Linux 지원이 약한 편임
Linux 쪽은 WebkitGtk 상태 때문임
Flutter는 Dart를 쓰는데, Dart는 다른 곳에서 널리 쓰이지 않음
MDN, w3schools, 표준 명세 같은 학습 기준이 없어 배우기 더 어렵고, Flutter Web은 DOM 대신 Canvas를 쓰기 때문에 문제가 있음
개인적으로는 크로스 플랫폼 앱에는 여전히 Electron이 맞다고 봄
- JavaScript를 쓰는 앱에서는 Tauri가 Electron을 대체해 가고 있고 요즘 인기가 있다는 얘기를 들었음
-
흥미로움
내가 이해한 게 맞다면 이건 소스 간 변환으로 동작하는 건가 싶음
문서만 봐서는 기술적 접근을 이해하기 조금 어렵지만, 사용자 대상으로 잘 쓰였고 인상적임
더 깊이 보기 전에 접근 방식과 wasm 기반 Rust 웹 프레임워크와의 비교를 알고 싶음
Rust와 Flutter를 결합하는 장점 중 하나는 Flutter가 이미 완성된 프레임워크라서 서버와 클라이언트 사이에서 코드와 자료 구조를 공유할 수 있다는 점으로 보임- Rust 코드를 파싱해서 “여기에 함수가 있고 저기에 구조체가 있다”는 식으로 이해한 뒤, 일부 Rust 코드와 Flutter 코드를 생성하는 방식임
비교에 대해서는 블로그에서 몇 가지 장단점을 다루고 있음
- Rust 코드를 파싱해서 “여기에 함수가 있고 저기에 구조체가 있다”는 식으로 이해한 뒤, 일부 Rust 코드와 Flutter 코드를 생성하는 방식임
-
잘 만들었음
rust_flutter_bridge에 대해 좋은 얘기만 들었음
다만 Flutter 질문에 가깝지만, 간단한 앱 기준으로 모바일 네이티브(Java, Swift?)와 비교했을 때 Flutter의 최종 앱 크기가 얼마나 커지는지, 그리고 UI 성능은 어떤지 궁금함- 앱 크기는 구체적인 시나리오에 따라 달라짐
예를 들어 Flutter는 사용하지 않는 라이브러리 코드를 자동으로 제거함
기억이 흐릿하지만 단순 앱은 대략 5MB 정도였던 것 같고, ABI별로 .so 파일을 나누는 것도 기억해야 함
UI 성능은 개인적으로 꽤 좋다고 느꼈고, Flutter(Dart)는 JIT나 인터프리터가 아니라 AOT로 어셈블리 코드로 컴파일되므로 이론적으로도 빠름
둘 다 정확히 보려면 특정 사례에 맞는 데모를 만들어 보는 게 좋고, Flutter 커뮤니티에 물어보는 것도 도움이 될 듯함
- 앱 크기는 구체적인 시나리오에 따라 달라짐
-
이 경우 접근성은 어떤지 궁금함
문서에서 관련 정보를 찾지 못했는데, 2024년에 광범위한 접근성 지원 없이 GUI 키트를 내놓는 건 상상하기 어려우니 왜 언급이 없는지 의아함- Flutter 전반을 말하는 거라면 꽤 좋다고 봄
위젯 단위로 쉽게 넣을 수 있고, 빌드를 실행하면서 확인하고 테스트하기도 매우 쉬움
- Flutter 전반을 말하는 거라면 꽤 좋다고 봄
-
데스크톱 UI에는 Flutter를 쓰고 백엔드에는 Rust를 쓰지만, 브리지 대신 gRPC로 둘을 분리했음
이렇게 하면 양쪽 언어에 덜 묶이고, 프런트엔드에서 백엔드를 모킹하기 위한 인터페이스도 더 깔끔해질 것 같음
UI와 백엔드를 다른 머신에 두기도 쉬워져 진짜 클라이언트/서버 구조를 만들 수 있음
단점은 인터페이스가 더 장황해질 가능성이 크다는 점임- UI가 실행되는 데스크톱에서 gRPC 서비스를 띄우고 둘을 localhost로 연결하는 방식인지 궁금함
-
Chrome 셸이나 웹 위젯에 기대는 것보다 훨씬 나아 보이고, 노력에 박수를 보냄
-
좋음
Flutter의 UI 구축 방식은 정말 즐거웠지만, Dart 자체는 그다지 마음에 들지 않았음
이론적으로는 UI 전용 프로그래밍 언어를 만들 수 있지 않을까 싶음
주요 프로그래밍 언어 어디서든 연결할 수 있고, protobuf의 IDL 형식처럼 데이터를 정의하는 대신 사용자 인터페이스를 선언하는 식임
말도 안 되거나 멍청한 아이디어일까?
QT와 XAML이 떠오르지만, QT는 닫힌 소스라고 알고 있고 틀렸을 수도 있음
XAML은 오래전부터 정체된 것처럼 보이는데 이것도 틀렸을 수 있음- Qt에는 상용 라이선스 전용 컴포넌트가 일부 있지만, 대부분은 오픈소스임
실제로 KDE Free Qt Foundation이 프레임워크가 항상 GPL+LGPLv3로 제공되도록 보장함[0]
UI 제작을 위해 특별히 설계된 언어도 몇 가지 있고, Qt에는 그런 언어인 QML[1]이 있음
QML은 UI 개발을 위해 만들어진 “단순한” 언어이며 C++와 연결할 수 있어서, 비즈니스 로직은 범용 언어로 쓰고 UI는 UI에 집중하게 할 수 있음
더 흥미로운 건 Slint[2]임
이 언어와 회사는 QML 개발자 출신들이 QML이 겪게 된 함정을 피하고 설계를 개선하려고 만든 것임
핵심은 Rust로 작성됐고 C++, JS, 이제는 Python 바인딩도 있음
임베디드 기기에 초점을 두기 때문에 성능과 메모리 사용량을 항상 신경 쓰는 쪽으로 이어져 좋음
Slint 개발자 중 한 명은 ogoffart임: https://news.ycombinator.com/user?id=ogoffart
[0]: https://www.qt.io/faq/tag/qt-open-source-licensing
[1]: https://en.wikipedia.org/wiki/QML
[2]: https://slint.dev - XAML은 Avalonia[0], Uno[1], MAUI[2], 그리고 WPF 안에서 여전히 매우 살아 있음
다만 C#[3]와 F#[4]로 정의하는 선언형 UI 지원과 인기도 커지고 있음
[0]: https://docs.avaloniaui.net/docs/basics/user-interface/intro...
[1]: https://platform.uno/docs/articles/getting-started/counterap...
[2]: https://learn.microsoft.com/en-us/dotnet/maui/xaml/fundament...
[3]: https://github.com/AvaloniaUI/Avalonia.Markup.Declarative
[4]: https://github.com/fsprojects/Avalonia.FuncUI - Dart의 어떤 점이 마음에 들지 않았는지 궁금함
나도 싫어할 줄 알았는데 의외로 꽤 괜찮았음 - CSS를 말하는 건가?
- Qt에는 상용 라이선스 전용 컴포넌트가 일부 있지만, 대부분은 오픈소스임
-
Google이 시간이 지나면서 Flutter 전체 프레임워크를 종료할 계획이 있는지 아는 사람이 있나?
내부에서 작업하던 사람들을 거의 다 해고했다면, 3~5년 뒤에도 Flutter가 Google 지원을 받을 거라는 확신이 크지 않음
장기 생존성을 보장하기 위해 포크해서 독립 재단 아래에 두자는 얘기가 있었는지도 궁금함
Google이 여러 기술을 장기 지원해 온 기록을 보면, Flutter가 너무 일찍 역사 속 폐기물로 들어가면 아쉬울 것 같음- 무슨 얘기인지 모르겠음
Flutter 팀에서는 아무도 해고되지 않았음
잠재적으로 관련이 있었던 건 Flutter 빌드 파이프라인을 운영하던 Google Cloud 팀 사람들이었을 뿐이고, 그들도 Flutter를 직접 작업한 건 아니었음
게다가 역할이 유럽으로 외주화된 것에 가까워서 Flutter 자체가 실제로 영향을 받은 건 아님 - 대체 무슨 소리를 하는 건지 모르겠음
그런 일은 말 그대로 일어난 적이 없음
- 무슨 얘기인지 모르겠음