- Rust GUI 프레임워크 Dioxus 0.5는
dioxus-core재작성과 unsafe 제거를 중심으로, 웹·데스크톱·모바일·Fullstack 개발 흐름을 크게 단순화함 - 0.4.3에서 0.5.0 사이에 100,000줄 이상의 코드와 1,400개 이상 커밋이 들어갔고, 새 코어는 수명과
Scope의존을 없애는 방향으로 바뀜 - 기존
use_state·use_ref중심 상태 관리는 Copy 가능한SignalAPI로 대체되어, 이벤트 핸들러와 future에서 반복적인Clone부담이 줄어듦 - 하나의
dioxus::launch와dx serve --platform흐름으로 웹, 데스크톱, Fullstack 앱을 실행하며, CLI가 대상 플랫폼에 맞는 빌드 feature를 자동 전달함 - 자산 핫 리로드, 이벤트 재작성, 데스크톱 렌더링 개선, 서버 함수 스트리밍까지 함께 바뀌어 단일 Rust 코드베이스의 적용 범위가 넓어짐
Dioxus 0.5의 릴리스 방향
- Dioxus는 Rust로 GUI를 만드는 라이브러리이며, 웹 앱·데스크톱 앱·모바일 앱 배포에 사용되고 있음
- 0.5 릴리스는 커뮤니티가 요구한 단순화, 견고함, 완성도 향상을 목표로 설계됨
- 주요 변화는 다음과 같음
dioxus-core완전 재작성 및 unsafe 코드 제거use_state,use_ref대신Signal기반 API 도입- 모든 수명과
cx: Scope상태 제거 - 모든 플랫폼에서 앱을 시작하는 단일
launch함수 - Tailwind와 Vanilla CSS를 지원하는 자산 핫 리로드
- 네이티브
WebSys이벤트 타입 접근을 허용하는 이벤트 재작성 - Error Boundary, Server Future, Suspense 통합
- 데스크톱 reconciliation 5배 개선
- 서버 함수 스트리밍과 Fullstack 핫 리로드
- Dioxus 0.4에서 업데이트하는 사용자를 위한 migration guide가 제공됨
수명과 Scope 제거
- Dioxus 0.1부터 0.4까지는 컴포넌트 내부 값이
'bump수명을 가졌고, 이를 통해 이벤트 리스너에서 훅, props, scope를 복제 없이 사용할 수 있었음 - 이벤트 핸들러에서는 대체로 잘 동작했지만, Dioxus의 future는
'static이어야 해서 값을 future 안으로 옮기기 전에clone이 필요했음 - 수명 오류가 발생하면 hook 자체가 아니라
cx가'static보다 오래 살아야 한다는 식의 메시지가 나와 혼란을 만들 수 있었음 - Dioxus 0.5는
Scope와'bump수명을 제거하고,Element를 수명 없는 형태로 바꿈 - 컴포넌트는 이제 scope 매개변수 없이 props를 직접 받을 수 있음
- 예:
fn MyComponent(name: String) -> Element
- 예:
- 런타임 함수는 컴포넌트 내부뿐 아니라 future와 이벤트 핸들러 내부에서도 직접 사용할 수 있음
Element가'static이 되면서 hook 안에서 사용하거나 context API를 통해 제공하는 것도 가능해짐- 이 변화는 가상 리스트나 오프스크린 렌더링 같은 API를 구현하기 쉬운 기반이 됨
dioxus-core의 unsafe 제거
'bump수명과 scope 제거는 Dioxus 내부의 unsafe 코드를 줄일 기회를 만들었음dioxus-core 0.5에는 unsafe 코드가 없음- 일부 의존성에는 소량의 unsafe가 남아 있으며, Dioxus 팀은 0.5 릴리스 사이클 동안 이를 제거할 계획임
- 남은 unsafe는 단순히 제거 가능한 것들이거나 FFI 때문에 필요한 것들로 분류됨
Signal 기반 상태 관리
- Dioxus 0.5는 컴포넌트의 핵심 상태 원시 타입으로 Signal을 도입함
- Signal은 기존
use_state,use_ref대비 두 가지 장점을 가짐- 항상
Copy가능함 - 수동 구독이 필요 없음
- 항상
-
Copy 상태
Signal<T>는 내부의T값이Copy가 아니어도Copy임- 이 동작은 unsafe 없이 구현된 generational-box 크레이트로 가능해짐
- 필요하면 Signal을
Send+Sync로 만들 수 있어 스레드 사이로 옮길 수 있음 - Copy 상태,
Send+SyncSignal, static 컴포넌트 조합으로 상태를 future, 이벤트 핸들러, 스레드 등 필요한 위치로 쉽게 이동할 수 있음 - 메모리 사용 방식은 0.4와 거의 같지만, 명시적
Clone이 필요하지 않음
-
스마트 구독
- Signal은 값이 바뀌었을 때 어떤 컴포넌트를 다시 실행할지 더 세밀하게 판단함
- 컴포넌트가 Signal 값을 읽은 경우에만 해당 컴포넌트가 다시 실행됨
- async 작업이나 이벤트 핸들러에서 읽은 경우는 컴포넌트 재실행 구독으로 취급되지 않음
- 부모가 버튼 클릭으로 Signal을 변경하지만 값을 직접 읽지 않고, 자식만 값을 읽으면 자식만 다시 렌더링됨
- 이 구조 덕분에 별도 상태 관리 크레이트였던 Fermi가 필요 없어짐
- Fermi는 static을 키로 쓰는
use_state유사 API를 제공했음 - Dioxus 0.5에서는
GlobalSignal을 static에 두고 일반 Signal처럼 사용할 수 있음 - Signal은 context API와도 동작해 별도의
use_shared_state훅 없이 컴포넌트 간 상태 공유가 가능함 use_future,use_memo같은 hook 안에서 Signal을 읽으면 해당 Signal이 hook 의존성에 자동 추가됨
CSS와 자산 핫 리로드
- Dioxus 0.5는 자산 시스템 개편의 일부로 자산 디렉터리의 CSS 파일 핫 리로드를 구현함
- CSS 파일이 RSX 안에 나타나면
dxCLI가 해당 파일을 감시하고 실행 중인 앱으로 업데이트를 즉시 스트리밍함 - 지원 대상은 Web, Desktop, Fullstack이며, 모바일 지원은 향후 모바일 중심 업데이트에서 제공될 예정임
- Tailwind watcher와 함께 사용하면 Tailwind CSS 핫 리로드도 지원됨
- VSCode에서는 custom regex extension을 통해 Tailwind class 힌팅도 받을 수 있음
- 여러 기기에 변경 사항을 동시에 스트리밍해 대상 기기 전체에서 핫 리로드할 수 있음
이벤트 시스템 재작성
- Dioxus는 출시 이후 크로스플랫폼 이벤트 API를 만들기 위해 synthetic event 시스템을 사용해 왔음
- Synthetic event는 플랫폼 간 이벤트 동작과 네트워크 직렬화에 유용하지만 한계도 있었음
- Dioxus 0.5는 각 플랫폼의 기반 이벤트 타입을 노출하고, 크로스플랫폼 API를 위한 trait도 함께 제공함
- 이 변화의 장점은 두 가지임
- 플랫폼 이벤트 타입에서 필요한 정보를 직접 얻거나 다른 라이브러리에 전달할 수 있음
- 앱이 사용하지 않는 이벤트 코드를 bundle splitting할 수 있음
- hello world 예시에서 gzipped 크기가 약 25% 감소함
- 작은 번들을 만드는 팁은 Dioxus optimization guide에 포함됨
크로스플랫폼 실행 API
- Dioxus 0.5는 앱 실행을 위한 새 크로스플랫폼 API를 도입함
- 별도 renderer 패키지를 가져오는 대신
dioxuscrate에서 feature를 활성화하고 prelude의launch함수를 호출하면 됨 - 하나의 앱에서 다음 플랫폼을 대상으로 실행할 수 있음
- Desktop:
dx serve --platform desktop - SPA Web:
dx serve --platform web - Fullstack:
dx serve --platform fullstack
- Desktop:
- CLI는 대상 플랫폼에 따라 적절한 빌드 feature를 자동으로 전달함
자산 시스템 베타와 Manganis
- Dioxus와 웹 앱에서 자산 경로는 오래되기 쉽고, 데스크톱과 웹에서 링크가 다를 수 있으며, 번들에 포함할 자산을 수동으로 추가해야 하는 문제가 있음
- 자산은 성능 병목이 될 수도 있음
- Dioxus Mobile 가이드 예시에서 0.4 버전은 로딩에 7초가 걸리고 9MB 리소스를 전송했음
- 0.5 모바일 가이드는 같은 이미지를 사용하면서도 1초 미만에 로드되고 필요한 리소스가 1/3로 줄어듦
- Dioxus 0.5는 새 자산 시스템 manganis 를 도입함
- CLI와 통합되어 앱 자산을 확인, 번들링, 최적화함
- API가 아직 불안정해 별도 crate로 배포됨
mg!매크로로 자산을 감싸면 CLI가 자동으로 감지함- 자세한 내용은 manganis docs에 있음
- 0.5 릴리스가 진행되는 동안 manganis 자산에도 핫 리로드를 추가할 계획임
데스크톱 렌더링 5배 개선
- Dioxus는 렌더링 diff를 빠르게 만들기 위해 여러 최적화를 사용함
- Templates는
rsx!매크로의 정적 부분 diff를 건너뛰게 함 - Dioxus Web에서는 sledgehammer를 통해 Rust에서 DOM 변경을 빠르게 적용함
- Dioxus 0.5는 같은 방식을 네트워크를 통한 변경 적용에도 사용함
- Desktop과 LiveView renderer가 변경 사항을 JSON 대신 바이너리 프로토콜로 통신함
- 렌더링 부하가 큰 작업에서 새 renderer는 브라우저에 변경을 적용하는 시간이 1/5로 줄고 지연 시간은 1/2로 줄어듦
- Dioxus 0.4에서 renderer가 계속 멈추던 벤치마크가 Dioxus 0.5에서는 부드럽게 실행됨
컴포넌트 작성 편의 기능
- Dioxus 0.5는 특정 element를 확장하고 속성을 element에 펼치는 기능을 지원함
- 예:
imgelement 속성을 확장한ImgPlus컴포넌트에서width,height,src같은 일반img속성을 그대로 받을 수 있음
- 예:
- 속성과 컴포넌트에 값을 전달할 때 구조체 초기화 축약 문법을 사용할 수 있음
class: class대신class처럼 쓸 수 있음
- 축약 속성은
IntoAttribute를 구현하는 모든 항목에 동작하며 Signal도 이 혜택을 받음 - Signal 속성이 아직 diffing을 건너뛰지는 않지만, 0.5 릴리스 사이클 동안 성능 최적화로 추가될 계획임
- 여러 줄에 나뉜 속성은 병합될 수 있음
- 같은
class속성에 조건부 값을 추가하면 공백을 구분자로 병합됨 - Tailwind처럼 컴파일 타임 파싱이 필요하면서 런타임 동적 처리도 필요한 라이브러리에 중요함
- 이 문법은 Tailwind compiler와 통합되어
tailwind-merge같은 라이브러리의 런타임 오버헤드를 제거함
- 같은
서버 함수 스트리밍과 Fullstack
- Dioxus 0.5는 스트리밍 데이터를 지원하는 최신 server functions crate를 지원함
- 서버 함수는 클라이언트로 데이터를 스트리밍하거나 클라이언트에서 서버로 데이터를 스트리밍할 수 있음
- 스트리밍 서버 함수는 출력 타입을 정의하고 서버 함수에서
TextStream을 반환하는 방식으로 만들 수 있음 - 오래 걸리는 작업 중 클라이언트를 업데이트하는 데 적합함
- Kalosm과 로컬 LLM을 사용해 일반 하드웨어에서 OpenAI ChatGPT endpoint와 유사한 기능을 제공하는 예제가 있음
- CLI는 이제
fullstack플랫폼을 지원하고, 클라이언트와 서버의 핫 리로드 및 병렬 빌드를 제공함dx servedx serve --platform fullstack
LiveView, 자산 핸들러, 파일 처리
- Dioxus 0.5에서는 router가 LiveView 앱에서 기본 동작함
- Dioxus Desktop은 custom asset handler를 지원함
- Custom asset handler는 Rust 코드에서 JavaScript를 거치지 않고 브라우저로 데이터를 효율적으로 스트리밍할 수 있게 함
- 비디오 스트리밍처럼 대역폭이 큰 통신에 적합함
- gstreamer나 webrtc 데이터를 직접 webview로 전달할 수 있어 프레임을 직접 인코딩·디코딩할 필요를 줄임
- 데스크톱의 파일 드롭도 이벤트 시스템에 네이티브로 통합됨
에러 처리
- Dioxus는 Error Boundary와
throwtrait를 통해 상위 컴포넌트에서 에러를 쉽게 처리할 수 있게 함 throw방식은 에러 상태와 조기 반환의 장점을 결합함Debug를 구현하는Result타입에서throw를 호출해 에러 상태로 바꾸고,?로 조기 반환할 수 있음ErrorBoundary컴포넌트는 자식에서 던져진 에러가 있을 때 다른 컴포넌트를 렌더링함ErrorBoundary는 중첩할 수 있어 앱의 여러 수준에서 에러를 잡을 수 있음- 이 패턴은 복구 불가능한 에러가 생겼을 때 panic하거나 에러마다 상태를 직접 관리하지 않고 전역 에러 상태를 처리하는 데 유용함
개발 경험과 템플릿
- Dioxus는 0.3에서 핫 리로드를 도입했고, 0.4에서 Desktop에 추가했으며, 0.5에서는 기본 활성화함
dx serve로 앱을 실행하면 개발 모드에서 기본적으로 핫 리로드가 켜짐- Desktop 앱에서 핫 리로드가 불가능해 전체 재컴파일이 필요할 때도 열린 창의 상태를 보존하고 복원함
- 앱 창 크기와 위치가 유지됨
- 편집할 때마다 앱이 전체 화면을 막는 상황을 줄임
- 새 템플릿은 Web, Desktop, Mobile, TUI, Fullstack 앱을 하나의 명령으로 만들 수 있게 정리됨
dx new의 기본 앱은 create-react-app에 가까운 형태로 바뀜- assets, CSS, 기본 배포 설정을 포함함
- dioxus-std, VSCode Extension, 문서, 튜토리얼 등 유용한 리소스 링크를 포함함
Dioxus Community와 생태계
- Dioxus Community는 0.5 릴리스를 위해 중요한 생태계 crate를 업데이트함
- icons, charts, Dioxus 전용 표준 라이브러리 같은 crate가 0.5 출시 시점에 바로 사용할 수 있도록 준비됨
Dioxus Community프로젝트는 원래 maintainer가 물러나도 중요한 crate를 최신 상태로 유지하기 위한 새 GitHub 조직임- Dioxus용 라이브러리를 만드는 경우, Dioxus 측은 이를 유지보수하는 데 도움을 줄 수 있으며 사실상 “Tier 2” 지원으로 유지하는 것을 목표로 함
앞으로 계획된 기능
- 0.5 이후 계획에는 다음 항목이 포함됨
- 자산 시스템 안정화와 더 깊은 통합
- lazy component와 함께 출력
.wasm직접 bundle splitting - Islands와 resumable interactivity, Signal 직렬화
- Server component와 LiveView를 Fullstack으로 병합
- 향상된 Devtools와 테스트 프레임워크
- 전체 Mobile 개편
- WebSocket, SSE, progressive form 등을 포함한 Fullstack 개편
Servo 기반 Dioxus-Blitz 미리보기
- Dioxus-Blitz의 “Blitz 2.0”에서는 Servo를 통합해 Firefox를 구동하는 것과 같은 CSS 엔진으로 WGPU 네이티브 렌더링을 목표로 함
- Taffy layout library를 만든 Nico Burns가 이 작업을 추진하기 위해 풀타임으로 합류함
- 데모에서는
google.com을 GPU에서 900 FPS로 렌더링함 - 현재 구현은 아직 완전하지 않고
google.com렌더링도 다소 어색하지만, 사용 가능한 수준에 빠르게 접근 중임 - 저장소는 https://github.com/jkelleyrtp/stylo-dioxus에서 확인할 수 있음
기여 방법
- Dioxus 프로젝트는 다음 기여를 원함
- 문서 번역
- “Good First Issues” 시도
- 문서 개선
- CLI 기여
- Discord 커뮤니티 질문 답변
- Dioxus 팀은 2024년 남은 기간 동안 커뮤니티 지원에 감사하며 앱 개발을 바꾸는 데 도움을 요청함