웹어셈블리에는 무슨 일이 있었나
(emnudge.dev)- WebAssembly(Wasm) 은 여전히 다양한 실제 제품에서 핵심 기술로 사용되고 있으며, 게임 엔진·디자인 툴·웹 컨테이너 등에서 중요한 역할을 수행
- 언어 자체는 하드웨어에 효율적으로 매핑되는 구조를 가지며, 안전성과 이식성을 중심으로 설계되어 있음
- 보안 모델은 ‘기본 거부(deny-by-default)’ 구조로, 프로세스 수준의 격리와 빠른 실행 속도를 가능하게 함
- 플러그인 생태계와 크로스언어 지원을 통해 다양한 환경에서 활용되지만, 브라우저 전체를 대체하는 수준의 채택은 아직 없음
- 현재 WebAssembly는 라이브러리와 런타임 수준에서 깊이 통합되어 있으며, 표준화와 기능 확장이 빠르게 진행 중인 기술임
실제 활용 사례
- WebAssembly는 Godot, Figma, Stackblitz, Squoosh.app, Zellij, Ruffle 등에서 핵심 기능을 담당
- Godot은 웹용 게임 빌드에, Figma는 C++ 코드를 브라우저에서 실행 가능한 형태로 변환하는 데 사용
- Stackblitz는 웹 컨테이너, Ruffle은 Flash 에뮬레이터로 Wasm을 활용
- 그러나 웹 전체를 Wasm 기반으로 구축한 대규모 사이트는 드뭄, 대부분은 특정 기능 단위에서 사용
WebAssembly의 정의와 속도
- WebAssembly는 언어(language) 로, 자체적인 속도 개념이 아닌 엔진 성능에 의존
- JavaScript처럼 런타임 엔진(V8, SpiderMonkey 등) 이 실행 속도를 결정
- WebAssembly는 현대 하드웨어에 효율적으로 매핑되는 구조를 가지며, 컴파일 또는 인터프리트 방식 모두 가능
효율적 매핑 구조
- Wasm은 어셈블리 언어에 가까운 바이트코드로, 대부분의 하드웨어에 손실 없이 컴파일 가능
- WAT(WebAssembly Text) 는 Wasm의 텍스트 표현으로, 거의 1:1 변환 가능
- JVM 바이트코드와 유사하지만, API가 작고 안전성 보장이 강함
- 메모리 접근은 명시적이며, 호스트 환경에서 허용된 자원만 사용 가능
컴파일 타깃으로서의 Wasm
- Rust, C, Zig, Go, Kotlin, Java, C# 등 다양한 언어가 Wasm으로 컴파일 가능
- Python, PHP, Ruby 같은 인터프리터 언어도 Wasm 빌드로 실행 가능
- 브라우저는 기본적으로 Wasm 엔진을 포함하며, Wasmtime, WasmEdge, Wasmer 등 독립 런타임도 존재
- 단일 Wasm 아티팩트는 하드웨어 비종속적 실행이 가능
보안 구조와 활용
- WebAssembly는 ‘deny-by-default’ 보안 모델을 채택, 외부 접근은 명시적 import만 허용
- 은닉된 제어 흐름 스택, 선형 메모리, 제한된 명령 집합으로 강력한 격리 보장
- Cloudflare는 V8 isolate를 이용해 Wasm 기반 코드 실행을 격리하며, Fermyon은 서브밀리초 수준의 기동 속도를 제공
- Ruffle은 Flash 콘텐츠를 안전하게 복원, Pyodide는 Python을 Wasm으로 실행, Figma는 Wasm 기반 QuickJS로 플러그인 실행
이식성과 임베딩
- Wasm 런타임은 가볍고, Zellij, Envoy, Lapce 등은 플러그인 시스템에 Wasm을 채택
- JavaScript 엔진이 있는 환경에서도 이미지 처리, OCR, 물리 엔진, 렌더링, 미디어 툴킷, 데이터베이스, 파서 등 다양한 Wasm 라이브러리 사용 가능
- 대부분의 경우 사용자는 Wasm 사용 여부를 인식하지 못함, 라이브러리 내부에서 투명하게 동작
속도와 크기 재검토
- 브라우저는 JS와 동일한 파이프라인으로 Wasm을 실행, 엔진 구조상 성능 한계 존재
- 언어의 타입 시스템과 컴파일러 최적화 수준에 따라 효율성 차이 발생
-
호스트-프로그램 경계 비용과 바이너리 부피 증가가 단점으로 지적
- WASI 표준이 이를 완화하려 하지만, 문자열 타입 표준화는 아직 미완성
- Zig이 가장 작은 Wasm 바이너리를 생성
- 네이티브 환경에서는 스레딩·IO·메모리 사용량으로 인해 성능 저하 가능
언어 및 표준 개발 동향
- Wasm 표준화는 W3C 워킹그룹과 Bytecode Alliance가 병행 진행
- 후자는 WIT, Component Model 등 도구 중심 개발을 주도
- 새 기능 제안이 빠르게 채택되고 있으며, 일부에서는 속도와 방향성에 대한 논쟁 존재
- Wasm은 JavaScript 대체보다는 내부 통합 기술로 확산
- Blazor, Leptos 같은 프레임워크는 JS를 직접 다루지 않고 Wasm을 활용
- 현재 Wasm은 라이브러리 제작자 중심으로 채택, 일반 개발자는 내부 동작을 인식하지 않아도 사용 가능
- 교육 자료의 난해함이 학습 장벽으로 지적되며, ‘watlings’ 같은 학습 프로젝트가 소개됨
Hacker News 의견들
-
나는 Wasm이 만들어질 때의 목표를 대부분 달성했다고 생각함
개인적으로 수십 개의 프로젝트에서 Wasm을 핵심 구성요소로 사용했음
JS 엔진이 매우 빠르지만, Wasm은 여전히 CPU 제어 수준이 높고 성능이 탁월함
다만 JS+HTML+CSS를 완전히 대체할 것이라는 기대에는 미치지 못했음. DOM 바인딩 부재가 큰 이유라고 봄
Yew 같은 Wasm 프레임워크도 써봤지만 JS 위에 덧붙인 어색한 레이어처럼 느껴졌음
Blazor는 아직 안 써봤지만, 나는 여전히 JS로 작성하는 게 더 편함
그래도 Wasm은 조용히 많은 곳에서 돌아가고 있으며, 그게 진정한 성공의 증거라고 생각함- 글이 Wasm을 앱 프레임워크처럼 평가한 것 같지만, 사실 Wasm은 CPU 최적화와 네이티브 코드 재사용을 위한 기술임
예를 들어 브라우저에서 오디오 속도 조절 기능은 C++ 라이브러리를 Wasm으로 돌려야만 가능한 수준의 성능을 냄 - 문제는 “근본적인 다른 이유”가 아니라, 확실히 DOM 접근 성능 부족 때문임
제대로 된 DOM 바인딩만 생기면 JS는 10년 안에 프론트엔드에서 밀려날 것임 - Blazor WASM은 현재 가능한 Wasm 활용 중 가장 완성도 높은 접근 중 하나임
C#은 백엔드와 프론트엔드 코드 공유가 쉽고, Razor 템플릿도 IDE 지원이 좋음
하지만 .NET CLR과 BCL을 통째로 실어야 해서 번들 크기가 큼
DOM 접근이 어려워 Blazor는 JS 쪽에 작은 Virtual DOM 렌더러를 두는 구조임
성능은 괜찮지만, 직접 작성한 JS보다는 여전히 느림
F# 기반의 Bolero도 흥미롭지만 팀 설득은 어려움 - 나는 처음부터 Wasm으로 전체 웹앱을 만드는 건 비현실적이라 생각했음
DOM과 상호작용하려면 그에 맞는 고수준 언어가 필요함
JS는 그 역할을 잘하고 있고, HTML/CSS/JS 조합은 이미 UI 개발의 공용어가 되었음
브라우저 렌더링을 버리고 캔버스 기반으로 가는 시도도 있지만, 여전히 틈새 영역임 - JS를 완전히 대체하지 못한 게 오히려 다행이라 생각함
단순한 웹사이트조차 수 MB짜리 런타임을 내려받아야 하는 세상은 끔찍함
실제 느림의 원인은 JS가 아니라 DOM임. 결국 DOM과 상호작용해야 하니까
- 글이 Wasm을 앱 프레임워크처럼 평가한 것 같지만, 사실 Wasm은 CPU 최적화와 네이티브 코드 재사용을 위한 기술임
-
나는 몇 년간 WebAssembly로 일했고, 곧 Wasm 기반 프레임워크를 공개할 예정임
생태계가 빠르게 발전하다가 갑자기 느려지면서 WASI와 Component Model 도입이 혼란을 초래했음
엔진마다 지원 수준이 달라 문서와 코드, 이슈를 전전해야 하는 상황이 많음
가장 큰 문제는 JS/TS 지원임. 현재는 해킹에 가까운 통합 방식이라 안정적이지 않음
Web Containers가 개선을 가져왔지만, 이미 많은 개발자가 Bun으로 이동했음- JS/TS 지원이 구체적으로 무엇을 의미하는지 궁금하다는 질문이 있었음
-
Wasm의 잠재력은 엄청남
이론적으로는 모든 플랫폼의 공통 컴파일 타깃이 될 수 있음
하지만 현실은 Figma의 일부 기능을 빠르게 만드는 수준이라 다소 실망스러움
위원회 중심의 개발 구조라 속도가 느린 것도 한계임- 잠재력만 이야기할 때가 아니라 결과를 보여줘야 함
Native Client 시절엔 네이티브 속도의 앱이 가능했는데, 지금 Wasm은 그보다 느림
JS 바인딩 구조를 Wasm에도 적용할 수 있었을 텐데 아쉬움
게다가 Wasm이 JS보다 빠르지도 않음 - “이론상 가능”만으로는 사람들이 Wasm을 채택하지 않음
HTML/CSS/JS는 이미 유용성이 입증된 반면, Wasm은 여전히 낯선 기술 스택임 - 컨테이너를 WASI로 대체해야 한다고 생각함
Docker 중심의 생태계가 발목을 잡고 있음 - The Birth and Death of JavaScript 영상을 추천함
- 잠재력만 이야기할 때가 아니라 결과를 보여줘야 함
-
JS 생태계의 많은 빌드 도구가 Rust로 작성되어 있고, 일부는 Wasm으로 브라우저에서 실행됨
React나 npm 생태계도 내부적으로 Wasm을 사용함
Wasm이 사라지면 JS 프론트엔드 세계가 크게 흔들릴 것임
다만 네이티브 Wasm UI 프레임워크는 아직 미비함
DOM과 CSS에 의존해야 하고, JS를 통해 브라우저 API에 접근해야 해서 비효율적임
Rust나 Kotlin으로 DOM을 제어할 수는 있지만, Rust는 프론트엔드엔 너무 저수준임
모바일 크로스컴파일이 점점 늘고 있고, JetBrains Compose Multiplatform이 그 예임- React가 Wasm 컴포넌트를 많이 쓴다는 건 잘못된 주장이라는 반박이 있었음
-
Wasm의 발전을 가로막는 건 툴링임
디버깅은 여전히printf수준이고, Chrome의 DWARF 플러그인도 오래전부터 업데이트가 없음
언어별로 .wasm 파일을 만들고 import/export를 설정하는 과정이 복잡함
GC 지원도 완전하지 않아 .NET 같은 생태계는 자체 GC를 실어야 함
WIT는 또 다른 COM/CORBA/gRPC 시도처럼 보임- 10년이 지나도 툴링은 여전히 미완성임
Emscripten은 복잡하고 불안정하며, wasi-sdk는 기능이 부족함
LLVM과 엔진 모두 최적화가 미흡하고, Rust의 Wasm 툴링도 사실상 중단됨
JS에서 Wasm 모듈을 표준 방식으로 import하는 방법조차 없음
멀티스레드 지원도 COOP/COEP 헤더 설정이 필요해 GitHub Pages에서는 불가능함
툴링이 “기술 데모” 수준을 벗어났다면 훨씬 더 많이 쓰였을 것임 - “WASM Components Model”이 이런 문제를 해결할 수 있지 않냐는 의견도 있었음
- 10년이 지나도 툴링은 여전히 미완성임
-
우리 회사 Leaning Technologies는 Wasm을 적극적으로 사용함
WebVM으로 브라우저에서 x86 바이너리를 실행하고,
BrowserCraft로 Java 앱(Minecraft 포함)을 돌리며,
BrowserPod로 Node.js 컨테이너를 브라우저에서 구동함
매우 강력하지만 파워 유저용 도구임. 일반 프론트엔드 로직을 Wasm으로 컴파일하는 건 비효율적임- Firefox에서 BrowserCraft가 안 돌아가지만 Brave에서는 잘 됐다는 피드백이 있었음
CheerpJ의 발전 속도가 인상적이며, 10년만 일찍 나왔어도 웹 플랫폼이 달라졌을 것 같다는 의견임 - “왜 프론트엔드 로직을 Wasm으로 컴파일하면 안 되냐”는 반론도 있었음
JS를 싫어하는 입장에서는 JS 없는 웹사이트를 만드는 게 Wasm의 진짜 매력임
- Firefox에서 BrowserCraft가 안 돌아가지만 Brave에서는 잘 됐다는 피드백이 있었음
-
나는 Rust 기반 Wasm 프레임워크 Dioxus에서 일함
프론트엔드 Wasm은 번들 분할, 핫리로드, 디버깅 심볼, 에셋 통합 등 기본 툴 부족이 문제였음
2025년에 이를 많이 개선했고, Vite 같은 도구와의 통합도 좋아짐
AI 도구 덕분에 Rust 개발 속도도 빨라졌고, 앞으로 Wasm 프레임워크가 더 주목받을 거라 기대함 -
Wasm의 바이너리 크기가 너무 크다는 지적이 있었음
DSL 환경에서는 다운로드에 수 초~수 분이 걸릴 수 있음
JS는 더 작고 다운로드 중에도 실행 가능하다는 주장임- 사실 Wasm은 JS보다 작을 때가 많음
Rust로 빌드하면 10~100KB 수준으로 줄일 수 있음
JS는 다운로드 중 실행되지 않으며, Wasm은 스트리밍 컴파일로 더 빠르게 시작할 수 있음 - Godot 같은 게임은 런타임 외에도 대용량 에셋을 내려받아야 해서 사용자 경험이 나쁨
브라우저가 이미 제공하는 기능을 중복 구현하는 셈임 - Wasm의 비효율은 포맷이 아니라 언어 런타임의 부피 때문임
예를 들어 FSHistory는 24KB로 x86 에뮬레이션을 구현함 - Wasm 포맷은 본래 크기 최적화를 고려해 설계되었음
다만 네이티브 생태계는 코드 크기 최적화에 익숙하지 않음 - GC 언어를 WasmGC로 컴파일하면 JS보다 커질 이유가 거의 없음
- 사실 Wasm은 JS보다 작을 때가 많음
-
기사에서 “Wasm으로 만든 대형 웹사이트가 없다”는 말은 내 경험과 다름
Wasm 프로젝트의 목표가 웹앱 전체를 대체하는 게 아니었음
사람들이 잘못된 기대를 품고 “왜 그게 안 됐냐”고 묻는 것 같음 -
나는 실제로 Wasm을 여러 실무 사례에 적용했음
- 코덱 지원: 브라우저에서 지원하지 않는 비디오·오디오 코덱을 Wasm으로 구현
- 코드 공유: C로 작성된 비즈니스 로직을 프론트엔드와 백엔드에서 동일하게 사용
- 난독화: JS의 핵심 로직을 Rust+Wasm으로 옮겨 성능과 보안을 동시에 확보함
- JS를 숨기려면 아예 브라우저로 보내지 않는 게 낫다는 의견도 있었음
백엔드에서 필요한 부분만 잘라내는 식으로 처리 가능함 - 오픈소스 코덱이 있는지 묻는 댓글도 있었음. 브라우저 기반 VLC 같은 프로젝트 아이디어로 연결됨