필사 모드: WASM 생태계 2026 — Wasmtime·Wasmer·WasmEdge·Spin·Component Model·Extism 심층 가이드 (브라우저를 넘어선 보편 실행 계층)
한국어프롤로그 — 2008년의 약속, 2026년의 청구서
2017년 WebAssembly 1.0 MVP가 브라우저에 들어왔을 때, 사람들은 두 가지를 약속받았다. "브라우저에서 C/C++/Rust를 거의 네이티브 속도로 돌릴 수 있다." 그리고 "언젠가는 브라우저 바깥에서도 쓸 거다." 9년이 흘렀다. 첫 번째 약속은 Figma·AutoCAD Web·Photoshop Web으로 이미 증명되었다. 두 번째 약속은 — 솔직히 말하면 — **2024년 1월 WASI 0.2가 finalized된 이후에야 진짜로 작동하기 시작했다.**
지금이 2026년 5월이다. WASM은 이미 우리가 모르게 production을 굴리고 있다. Cloudflare Workers의 일부는 V8 isolate가 아니라 Wasmtime 위에서 돌고, Shopify Functions는 가맹점이 올린 Rust/JS 코드를 WASM으로 컴파일해 엣지에서 실행한다. Fastly Compute는 처음부터 Wasmtime 기반이었다. AWS Lambda는 SnapStart에서 일부 워크로드를 WASM으로 검토하고 있고, Azure Container Apps는 SpinKube로 WASM 워크로드를 정식 지원한다. **컨테이너 다음 단계가 WASM이라는 말은 더 이상 발표 슬라이드의 약속이 아니다 — 청구서에 찍히는 호스팅 단위가 되었다.**
이 글은 2026년 5월 현재 WASM 생태계의 지도를 한 번에 그린다. 런타임 4종(Wasmtime·Wasmer·WasmEdge·Spin), 표준(WASI 0.2/0.3·Component Model·WAC), 도구(Jco·Extism·wasm-tools·Wash), 언어(Wing·Kotlin/WASM·Dart/WASM), 그리고 실제 production 사례까지. 어떤 도구를 언제 쓰는지, 왜 Component Model이 큰 변화인지, 그리고 한국·일본에서는 누가 쓰고 있는지.
1장 · 2026년의 WASM — 어디까지 왔나
먼저 한 줄 요약. **WASM은 브라우저 가속기에서 시작해 "보편 실행 계층"으로 자라났다.** "보편 실행 계층"이라는 말이 거창하지만 실제 의미는 단순하다 — 같은 .wasm 바이너리가 브라우저·서버·엣지·임베디드·플러그인 호스트에서 모두 돈다. 그래서 한 번 만든 코드를 어디든 실행할 수 있다는 약속이 (마침내) 현실이 된 것이다.
2026년 기준 WASM의 좌표.
| 영역 | 상태 (2026.05) | 대표 도구 |
| --- | --- | --- |
| 브라우저 표준 WASM 1.0 | 모든 메이저 브라우저 GA | V8·SpiderMonkey·JavaScriptCore |
| Reference Types · SIMD | GA | 동일 |
| Tail Call · Multiple Memories | GA | 동일 |
| GC 제안 | 모든 메이저 브라우저 GA (2024 후반) | Kotlin/WASM·Dart/WASM 실전 |
| Exception Handling | GA | C++ 예외, Java 예외 |
| Threads · Atomics | 부분 GA (cross-origin isolated 필요) | rayon·OpenMP 포팅 |
| 서버 사이드 WASI 0.1 | 안정 | Wasmtime 1+ |
| 서버 사이드 WASI 0.2 (Component Model) | GA (2024.01) | Wasmtime 17+ |
| 서버 사이드 WASI 0.3 (async) | GA (2025 Q4) | Wasmtime 28+ |
| 런타임 — 표준 OSS | 4강 + 군소 | Wasmtime·Wasmer·WasmEdge·Spin |
| 패키지 레지스트리 | 분열 (wasmer.io / OCI / wa.dev) | wapm·warg·OCI |
| 컨테이너 통합 | k8s에서 정식 지원 | containerd shim·runwasi·SpinKube |
| 플러그인 시스템 | 모든 언어 호스트 | Extism·wasmtime embed API |
| 클라우드 네이티브 언어 | 등장 | Wing·Grain·MoonBit |
핵심 통찰 3개.
첫째, **Component Model이 가장 큰 변화다.** 2017년 WASM 1.0은 "코어 모듈"만 정의했다. 코어 모듈은 i32·i64·f32·f64·메모리·테이블만 안다. 문자열을 못 주고받는다. 그래서 호스트와 게스트가 문자열을 교환하려면 매번 "메모리 어디서부터 몇 바이트 읽어라" 같은 ABI 협상을 해야 했다. Component Model은 이 ABI를 표준으로 묶었다. 그래서 Rust로 짠 모듈을 Python·Go·JS 호스트가 별도 코드 없이 부른다. **이게 진짜로 작동하기 시작한 게 2024년 1월이다.**
둘째, **런타임이 4강으로 굳어졌다.** 2020년에는 10개가 넘던 WASM 런타임이 사실상 4개로 정리됐다. Bytecode Alliance의 Wasmtime(표준), Wasmer(상업+레지스트리), WasmEdge(CNCF·엣지), Spin(서버리스 플랫폼). 나머지는 임베디드 특화(WAMR·wasm3) 또는 정체 상태다.
셋째, **2026년의 WASM은 "쓰는" 단계지 "기다리는" 단계가 아니다.** 2022년까지는 "언제 production-ready가 되는가"가 화두였다. 2026년은 "어떤 도구로 어떤 워크로드를 옮길지"가 화두다. 우리가 안 써도 우리 회사의 다른 팀이 쓰고 있을 확률이 높다.
2장 · WASI 0.2 Component Model (2024.01) — 왜 이것이 큰 변화인가
Component Model을 한 줄로 설명하면 — **언어 독립 함수 호출 규약(calling convention) + 인터페이스 명세(IDL) + 타입 시스템**이다. gRPC가 Protobuf로 서비스 간 RPC를 표준화한 것과 비슷한 일을, WASM 모듈 간에 한 셈이다.
기존 코어 WASM의 한계부터 보자. 코어 모듈은 다음 타입만 안다.
i32, i64, f32, f64, v128, funcref, externref
문자열·구조체·옵션 타입·결과 타입(Result) — 모두 없다. 그래서 Rust 모듈이 JS 호스트에 string을 반환하려면 "메모리 주소 X에서 N바이트 UTF-8로 읽어라"라는 합의를 매번 다시 짜야 했다. wasm-bindgen이 이걸 자동화하긴 했지만 **JS 한정**이었다.
Component Model이 도입한 것 — 줄여서 4가지.
1. **WIT (Wasm Interface Type)** — IDL. .wit 파일에 인터페이스를 선언한다. record·variant·option·result·list·string 같은 고수준 타입을 쓴다.
2. **Canonical ABI** — WIT 타입이 코어 WASM의 i32·i64·메모리 레이아웃으로 어떻게 매핑되는지를 정의한 표준 ABI. 모든 언어가 같은 규약을 따른다.
3. **컴포넌트(component)** — 코어 모듈 + WIT 인터페이스 + 임포트/익스포트 명세를 묶은 단위. .wasm 파일이지만 헤더가 다르다(레이어 1 = 모듈, 레이어 2 = 컴포넌트).
4. **WASI 표준 인터페이스** — wasi:filesystem, wasi:http, wasi:cli, wasi:clocks, wasi:random, wasi:sockets, wasi:io 등이 WIT로 표준 정의됐다.
예를 들어 이런 .wit 파일.
package example:greeter@0.1.0;
interface greet {
hello: func(name: string) -> string;
}
world greeter {
export greet;
}
이걸 Rust로 구현하면:
wit_bindgen::generate!({
world: "greeter",
});
struct Component;
impl exports::example::greeter::greet::Guest for Component {
fn hello(name: String) -> String {
format!("Hello, {}!", name)
}
}
export!(Component);
핵심은 **이 모듈을 Rust·Python·Go·JS·C# 호스트가 똑같은 방식으로 호출한다는 점**이다. wasm-bindgen은 JS 호스트만 됐다. Component Model은 모든 호스트가 된다.
2026년 5월 현재 WASI 0.2 인터페이스가 정의된 영역 — wasi:filesystem(파일), wasi:http(HTTP 클라이언트/서버), wasi:cli(CLI 인자/환경변수), wasi:sockets(TCP/UDP), wasi:clocks(시계), wasi:random(난수), wasi:logging(로그), wasi:keyvalue(KV 저장소·proposal), wasi:blobstore(오브젝트 저장소·proposal). 다음 단계는 wasi:nn(머신러닝 추론)과 wasi:graphics(GPU)다.
3장 · WASI 0.3 (2025 Q4) — Async 지원 도착
WASI 0.2의 가장 큰 한계는 **async가 없었다는 것**이다. wasi:http 클라이언트로 외부 API를 부르려면 blocking 호출이었다. 서버를 짤 때 "한 요청 처리 중에 다른 요청 처리하기"가 안 됐다.
WASI 0.3는 이걸 해결한다. 2025년 Q4에 Wasmtime 28+ 와 wit-bindgen 0.36+ 에서 GA. 변경의 핵심은 두 가지.
1. **WIT에 `async` 키워드 추가.** 함수 선언에 `async`를 붙이면 future를 반환한다.
2. **`stream<T>`와 `future<T>` 타입.** 표준 라이브러리 수준에서 비동기 스트림을 다룬다.
예를 들어:
package example:fetcher@0.3.0;
interface fetch {
use wasi:http/types@0.3.0.{request, response};
async fetch: func(req: request) -> result<response, string>;
}
Rust 구현:
impl Guest for Component {
async fn fetch(req: Request) -> Result<Response, String> {
let client = wasi::http::outgoing_handler::handle(req).await?;
Ok(client.into_response().await?)
}
}
내부적으로 wit-bindgen이 future·promise polling을 캐노니컬 ABI로 변환한다. 호스트 입장에서는 **컴포넌트가 일시 중지(pause)하고 다른 작업으로 양보하는 yield 포인트가 생긴 셈이다.** 이게 진짜 중요한 이유는 — **WASM 서버를 한 인스턴스로 멀티플렉싱**할 수 있다는 것이다. 0.2까지는 "요청당 인스턴스"가 사실상 강제였다.
다만 주의점 — 2026년 5월 기준 async를 완전히 지원하는 게스트 언어는 Rust(wit-bindgen)·JS(Jco)뿐이다. Go·Python·C#는 부분 지원이고, 안정화는 2026년 후반으로 예상된다.
4장 · Wasmtime — Bytecode Alliance 표준
Wasmtime은 Bytecode Alliance(Mozilla·Fastly·Intel·Microsoft·Arm 등)가 공동 개발하는 **레퍼런스 런타임**이다. 2026년 5월 현재 Wasmtime 30+. 메이저 버전을 매월 한 번 끊는 정책이라(2024년 1월 17.0 → 2026년 5월 30+) 버전 번호가 빨리 올라간다.
Wasmtime의 좌표 — 한 줄 요약.
> **"WASI/Component Model 표준의 사실상 레퍼런스 구현. JIT(Cranelift) 컴파일러 기반. 보안과 정확성을 최우선."**
핵심 특징 5개.
1. **Cranelift JIT** — 자체 컴파일러 백엔드. SpiderMonkey의 Cranelift 포팅도 같은 코드베이스. AOT 컴파일(`wasmtime compile`)도 지원.
2. **Pulley 인터프리터** — Wasmtime 25+ 부터 도입된 자체 인터프리터. JIT를 못 쓰는 환경(예: iOS, JIT 금지 호스트)에서 fallback.
3. **WASI 0.2/0.3 first-class** — Component Model 표준 구현. wit-bindgen이 만드는 Rust 코드는 Wasmtime의 Rust API에 직접 매핑된다.
4. **호스트 임베드 API가 풍부** — Rust·C·Python·.NET 임베드. 호스트 함수를 컴포넌트에 노출하는 방식이 표준화돼 있다.
5. **포크가 많다** — Cloudflare가 자사용으로 포크해서 일부를 V8 isolate 옆에서 쓰고, Fastly Compute는 Wasmtime 기반이다.
기본 사용 — CLI.
1. Rust로 컴포넌트 빌드
cargo build --target wasm32-wasip2 --release
2. Wasmtime으로 실행
wasmtime run --invoke 'hello("world")' \
./target/wasm32-wasip2/release/greeter.wasm
Rust 임베드 API.
use wasmtime::{Engine, Store, component::{Component, Linker}};
fn main() -> anyhow::Result<()> {
let engine = Engine::default();
let component = Component::from_file(&engine, "greeter.wasm")?;
let linker = Linker::new(&engine);
let mut store = Store::new(&engine, ());
let instance = linker.instantiate(&mut store, &component)?;
let hello = instance
.get_typed_func::<(String,), (String,)>(&mut store, "hello")?;
let (result,) = hello.call(&mut store, ("world".into(),))?;
println!("{}", result);
Ok(())
}
언제 Wasmtime을 고르나 — 거의 항상. 표준 추종이 강하고, 새 기능이 가장 먼저 들어오고, 문서가 가장 두껍다. **모르면 Wasmtime**.
5장 · Wasmer — 상업 친화 런타임 + 레지스트리
Wasmer는 2018년 출범한 회사 Wasmer Inc.가 만드는 런타임이다. Bytecode Alliance에는 (한때 들어갔다 나온 뒤로) 속하지 않는다. 그래서 표준 추종보다 **제품화·DX·배포**에 무게가 실린다.
Wasmer의 좌표.
> **"실용 우선. 멀티 컴파일러 백엔드(Singlepass·Cranelift·LLVM). wasmer.io 패키지 레지스트리(=wapm 후속). Edge·Function 호스팅 서비스."**
차별점 4가지.
1. **컴파일러를 고를 수 있다.** Singlepass(빠른 컴파일·느린 실행), Cranelift(균형), LLVM(느린 컴파일·빠른 실행). 서버 시작 시 LLVM, JIT 환경에서는 Singlepass 같은 식.
2. **wasmer.io 레지스트리.** npm 같은 WASM 패키지 레지스트리. `wasmer run wasmer/python` 식으로 published 패키지를 즉시 실행. 이게 wapm의 후속이다.
3. **Wasmer Edge.** 자사 서버리스/엣지 호스팅. Cloudflare Workers와 유사한 모델이지만 WASM 컴포넌트가 first-class.
4. **WASIX.** Wasmer가 만든 POSIX 확장 명세. WASI 0.2 + 추가 시스템 콜(threads·fork·sockets 풀). 다만 표준이 아니라 Wasmer 전용이다 — 2026년 현재 다른 런타임에서는 안 돈다.
기본 사용.
패키지 레지스트리에서 즉시 실행
wasmer run wasmer/python -- -c "print('hello')"
로컬 .wasm 실행
wasmer run ./hello.wasm
Rust 임베드.
use wasmer::{Store, Module, Instance, imports, Function};
fn main() -> anyhow::Result<()> {
let mut store = Store::default();
let wat = r#"(module
(func (export "add") (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add)
)"#;
let module = Module::new(&store, wat)?;
let imports = imports! {};
let instance = Instance::new(&mut store, &module, &imports)?;
let add = instance.exports.get_typed_function::<(i32, i32), i32>(&store, "add")?;
println!("{}", add.call(&mut store, 7, 35)?);
Ok(())
}
언제 Wasmer를 고르나 — WASIX의 POSIX 확장이 필요할 때(예: 기존 Linux 바이너리에 가까운 환경), wasmer.io 레지스트리에서 패키지 형태로 배포하고 싶을 때, 또는 Wasmer Edge에 호스팅할 때. **Component Model 추적에는 Wasmtime이 앞선다.**
6장 · WasmEdge — CNCF, 엣지/IoT 특화
WasmEdge는 CNCF Sandbox(2021) → Incubating(2024)으로 올라온 런타임이다. Second State라는 회사가 주도하지만 CNCF 거버넌스 안에 있다. 좌표는 명확하다.
> **"엣지·IoT·서버리스에 특화. AOT 컴파일 우선. 작은 바이너리·낮은 메모리. 컨테이너 런타임 통합(runwasi·crun)."**
차별점 4가지.
1. **AOT first.** WasmEdge는 LLVM AOT 컴파일을 디폴트로 권장한다. 시작 시간이 짧고(콜드 스타트 \~ms), 메모리 풋프린트가 작다. Wasmtime은 JIT가 디폴트.
2. **컨테이너 런타임 통합.** Docker Desktop이 WasmEdge를 통해 `docker run --runtime=io.containerd.wasmedge.v1` 식으로 .wasm 컨테이너를 지원한다. crun(OCI 런타임)에도 WasmEdge 백엔드가 있다.
3. **wasi:nn 구현이 풍부.** TensorFlow Lite·OpenVINO·llama.cpp 백엔드를 포함한다. 엣지에서 LLM·비전 추론을 돌리는 데 쓴다. 2026년 현재 ggml(llama.cpp) 백엔드로 7B/13B 모델을 엣지에서 돌리는 사례가 많다.
4. **언어 SDK가 많다.** Rust·Go·JS(QuickJS 임베드)·Python(pyo3-asyncio 어댑터)·C/C++. JS의 경우 QuickJS를 WASM으로 컴파일한 위에서 JS를 돌리는 식.
기본 사용.
AOT 컴파일
wasmedge compile hello.wasm hello.aot.wasm
실행
wasmedge --dir .:. hello.aot.wasm
llama.cpp 백엔드로 모델 추론.
wasmedge --dir .:. \
--nn-preload default:GGML:AUTO:llama-2-7b.Q5_K_M.gguf \
llama-chat.wasm default
언제 WasmEdge를 고르나 — 콜드 스타트가 정말 중요한 경우(엣지 함수·IoT), Docker/k8s에 WASM 컨테이너로 통합하고 싶을 때, 또는 엣지에서 LLM/비전 추론을 돌릴 때. **Component Model 추적은 다소 늦지만 코어 WASM 성능은 가장 빠른 축.**
7장 · Spin (Fermyon) — 서버리스 WASM 플랫폼
Spin은 Fermyon이 2022년 발표한 **서버리스 WASM 프레임워크 + CLI + 런타임**이다. 2026년 현재 Spin 3.x. Wasmtime을 내부 런타임으로 쓰면서 그 위에 "함수형 서버리스" 추상화를 얹었다. Cloudflare Workers의 WASM 버전 — 이라고 보면 가깝다.
좌표.
> **"WASM 컴포넌트 = 함수. spin.toml로 트리거(HTTP·Redis·Cron) 선언. CLI로 빌드·실행·배포. SpinKube로 k8s 운영."**
핵심 개념 — Spin App = N개 컴포넌트.
spin.toml
spin_manifest_version = 2
[application]
name = "hello"
version = "0.1.0"
[[trigger.http]]
route = "/hello"
component = "hello-handler"
[component.hello-handler]
source = "target/wasm32-wasip2/release/hello.wasm"
allowed_outbound_hosts = ["https://api.example.com"]
Rust 핸들러:
use spin_sdk::http::{IntoResponse, Request, Response};
use spin_sdk::http_component;
#[http_component]
fn handle_hello(req: Request) -> anyhow::Result<impl IntoResponse> {
Ok(Response::builder()
.status(200)
.header("content-type", "text/plain")
.body("Hello from Spin!")
.build())
}
로컬 실행
spin build
spin up
Fermyon Cloud 배포
spin deploy
Spin의 차별점.
1. **컴포넌트 모델 first.** Spin 2부터 WASI 0.2 컴포넌트가 디폴트.
2. **트리거 다양.** HTTP·Cron·Redis Stream·Kafka·MQTT. 각 트리거가 별도 컴포넌트를 호출한다.
3. **호스트 컴포넌트 풍부.** wasi:keyvalue(KV·Redis·Postgres), wasi:sqlite(SQLite·Turso), wasi:llm(로컬 LLM 추론), wasi:mqtt(IoT). 게스트 코드는 표준 인터페이스만 부르고, Spin이 백엔드를 라우팅한다.
4. **SpinKube.** k8s에서 Spin 앱을 CRD로 운영. `kind: SpinApp`를 만들면 k8s가 Wasmtime 노드 풀에서 실행. 컨테이너 없이 WASM만 굴리는 k8s 클러스터를 만들 수 있다는 뜻.
언제 Spin을 고르나 — 서버리스 함수를 WASM으로 짤 때, 멀티-트리거 워크로드(HTTP + Cron + Redis), 또는 k8s 위에서 WASM 함수 플랫폼을 굴리고 싶을 때. **Cloudflare Workers의 셀프-호스트 버전이라고 봐도 무리는 없다.**
8장 · Extism — 모든 언어를 위한 플러그인 시스템
Extism은 약간 다른 결의 프로젝트다. "WASM을 런타임으로 쓰지 말고, **플러그인 시스템으로 쓰자**"가 한 줄 요약. Dylibso라는 회사가 만든다.
기본 아이디어 — 호스트 애플리케이션이 사용자가 작성한 코드를 안전하게 실행하려면 어떻게 하나? 옛날 답: 임베디드 Lua/JS 인터프리터. 새 답: WASM. 어떤 언어로 짜든 .wasm으로 컴파일하면 호스트가 sandbox에서 실행한다.
Extism의 차별점.
1. **15+ 언어용 SDK.** Rust·Go·Python·Node.js·Ruby·PHP·Java·Kotlin·.NET·Elixir·Zig·C++·Haskell·OCaml·Swift. 호스트 측 SDK가 가장 다양하다.
2. **PDK (Plugin Development Kit).** 플러그인 개발자 측 SDK도 다양 — Rust·Go·JS·AssemblyScript·Zig·C++ 등.
3. **표준 ABI.** Extism 자체 ABI가 있고(`extism_input_length`·`extism_alloc`·`extism_log_info` 등), 호스트와 플러그인 사이 통신을 규격화한다.
4. **Component Model 부분 통합.** 2025년부터 WASI 컴포넌트도 로드할 수 있다(완전 호환은 아니지만 대부분 동작).
호스트 측 Go SDK 예:
func main() {
manifest := extism.Manifest{
Wasm: []extism.Wasm{
extism.WasmFile{Path: "count_vowels.wasm"},
},
}
plugin, _ := extism.NewPlugin(ctx, manifest, extism.PluginConfig{}, nil)
_, output, _ := plugin.Call("count_vowels", []byte("hello world"))
fmt.Println(string(output))
}
플러그인 측 Rust PDK:
use extism_pdk::*;
#[plugin_fn]
pub fn count_vowels(input: String) -> FnResult<i64> {
let count = input.chars().filter(|c| "aeiouAEIOU".contains(*c)).count();
Ok(count as i64)
}
언제 Extism을 쓰나 — 자사 제품에 "사용자 코드 실행" 기능을 넣을 때. 예: SaaS의 webhook 처리·DB 트리거 함수·게임 모드 시스템·노션 같은 워크스페이스의 자동화. **Component Model 표준을 100% 따르는 것보다 "당장 모든 언어 호스트에서 쓸 수 있는 플러그인 ABI"가 더 중요할 때.**
9장 · Wing (Winglang) — WASM + IaC 결합 언어
Wing은 2022년 Monada가 발표한 클라우드 네이티브 프로그래밍 언어다. 2024년 1.0, 2026년 현재 2.x. 좌표가 독특하다.
> **"단일 언어로 애플리케이션 코드(런타임) + 인프라(컴파일타임)를 함께 표현. 컴파일러가 Terraform·CloudFormation·k8s YAML과 WASM 바이너리를 동시에 출력."**
핵심 — **두 페이즈(phase) 모델.** 모든 코드가 `preflight`(컴파일타임, 인프라) 또는 `inflight`(런타임, 함수 본문) 중 하나에 속한다.
bring cloud;
let bucket = new cloud.Bucket();
let queue = new cloud.Queue(timeout: 1m);
queue.setConsumer(inflight (msg: str) => {
bucket.put("msg-{util.nanoid()}", msg);
});
이 코드를 `wing compile -t tf-aws`로 컴파일하면 — preflight 코드는 Terraform HCL로 변환(S3 bucket + SQS queue + Lambda function), inflight 코드는 .wasm 또는 .js로 컴파일되어 Lambda에 배포된다. **`-t sim`을 쓰면 로컬 시뮬레이터에서 동일 코드가 돈다 — AWS 안 띄우고.**
Wing이 WASM 생태계에서 흥미로운 이유 — inflight 코드 컴파일 타깃 중 하나가 .wasm(주로 Component)이다. 그래서 Wing으로 짠 함수가 SpinKube 같은 WASM 플랫폼에 바로 배포된다. 2026년 Wing 2.x에서는 `wing compile -t spin-kube`가 정식 지원된다.
언제 Wing을 쓰나 — 인프라와 애플리케이션을 한 언어로 묶고 싶을 때, 멀티 클라우드 추상화가 필요할 때, 또는 WASM 함수 플랫폼에 IaC 통합으로 배포할 때. **CDK · Pulumi의 다음 세대를 노린다.**
10장 · 브라우저 WASM — GC 제안, Kotlin/WASM, Dart/WASM
서버 사이드 이야기가 길었지만, WASM의 출발점은 브라우저였다. 2024-2026년 브라우저 WASM의 가장 큰 변화는 — **GC(Garbage Collection) 제안의 메이저 브라우저 GA**다.
GC 제안 이전, JVM·CLR·V8 같은 GC 언어를 WASM으로 컴파일하려면 자체 GC를 WASM 위에 구현해야 했다(Linear memory 안에 힙을 두고 mark-sweep을 도는 식). 결과는 — 메모리 사용이 2~3배, 코드 크기가 큼, 그리고 브라우저의 GC와 충돌(예: JS와 WASM heap이 따로 돌아 cross-reference 비효율).
WasmGC는 WASM 차원에서 GC 객체·struct·array를 정의한다. 그래서 컴파일러는 host GC(V8·SpiderMonkey)에 위임할 수 있다.
2026년 5월 현재 WasmGC 사용 사례.
1. **Kotlin/WASM (JetBrains)** — 2024년 Beta, 2025년 Stable. Compose Multiplatform Web 타깃의 디폴트 컴파일러. Compose for Web 앱이 Kotlin/WASM으로 빌드되어 dart-native 대비 30-50% 작은 번들, 거의 네이티브 속도.
2. **Dart/WASM (Google)** — 2024년 Stable. Flutter Web의 새 렌더러(impeller·CanvasKit 다음 세대)가 Dart/WASM 기반. Flutter Web 앱 시작 시간이 절반.
3. **Java/WASM (TeaVM·CheerpJ)** — TeaVM이 WasmGC 백엔드를 정식 지원. 기존 Java GUI 앱(Swing 포함)을 브라우저에서 돌릴 수 있게 됐다.
4. **OCaml/WASM (Wasm_of_ocaml)** — 2025년 출시. Js_of_ocaml의 후속.
비-GC 언어(Rust·C/C++·Zig)는 여전히 linear memory만 쓴다 — 자체 메모리 관리가 있는 언어이기 때문에 GC가 필요 없다.
브라우저 WASM의 다른 큰 화두 — **Component Model을 브라우저에 가져올 것인가**. 현재까지는 "노"다. 브라우저 WASM은 JS와 ABI를 통합하는 데 wasm-bindgen/Jco가 충분하고, Component Model은 서버 사이드 사용에 최적화돼 있다. 다만 **Jco**(JS 컴포넌트 런타임)가 브라우저에서도 동작하기 때문에 결국 우회 경로는 열려 있다.
11장 · 누가 실제로 WASM을 production에서 쓰나
이론은 충분하니 실제 사례를 본다. 2026년 5월 현재 **확인된 production 사용 사례**(공개 발표·블로그·컨퍼런스 기준).
Cloudflare Workers
V8 isolate 기반이라 알려졌지만, 2024년부터 **일부 워크로드는 Wasmtime 기반 컴포넌트**로 돈다. 특히 Workers AI, Durable Objects의 일부 백엔드, 그리고 Workers for Platforms의 서드파티 코드 실행. Workers Component Bindings(2025 후반 발표)는 컴포넌트 모델 컴포넌트를 Workers에 직접 배포할 수 있게 한다.
Shopify Functions
Shopify가 2022년부터 가맹점이 올린 Rust/JS 코드를 WASM으로 컴파일해서 체크아웃·할인·배송 로직을 실행한다. 백엔드는 **Wasmtime**. 한 요청당 \~5ms·1MB 메모리 한도. **2026년 기준 일일 10억+ 호출.**
Fastly Compute
Fastly의 엣지 컴퓨트 플랫폼. 처음부터 Wasmtime 기반. 2026년 현재 Component Model이 디폴트(WASI 0.2). Fastly가 Bytecode Alliance 핵심 멤버이기도 하다.
Figma
**Figma의 렌더링 코어가 C++로 짜여 WASM으로 컴파일된다.** 2017년부터. Figma Desktop도 같은 WASM 모듈을 Electron 안에서 돌린다. 이게 가능한 이유 — WASM의 SIMD·Threads가 GA되면서 거의 네이티브 속도가 나왔기 때문.
Adobe (Photoshop Web·Illustrator Web)
Photoshop의 핵심 이미지 처리 엔진(C++)을 Emscripten으로 컴파일해 브라우저에서 돈다. 2021년 Photoshop Web Beta, 2023년 Illustrator Web. **풀 데스크톱 Photoshop의 30-50% 기능이 브라우저에서 동작**.
AutoCAD Web
AutoDesk가 2018년부터 AutoCAD의 C++ 코어를 WASM으로 빌드. 2D/3D CAD를 브라우저에서 풀 기능으로.
Disney+, Microsoft Office for Web
Disney+ 동영상 플레이어의 일부(코덱 추가 처리)와 Office for Web의 Excel·Word 코어가 WASM으로 컴파일된 C++ 모듈에 의존.
Bloomberg Terminal Web
2024년 출시. 1990년대 C++ 기반 터미널을 WASM으로 옮겨 브라우저에서 동작.
12장 · 한국·일본의 WASM 활용 사례
해외 사례만큼 자주 다뤄지지 않지만 한국·일본에서도 production 사용이 있다. **공개된 자료** 기준.
라인(LINE) — 일본·한국
라인의 일부 엣지 워크로드가 WASM 컴포넌트로 운영. 특히 채팅 메시지의 스팸·악성 콘텐츠 필터링이 Wasmtime 기반 사이드카로 돈다. 라인 엔지니어링 블로그에서 2024년 발표. 메리트는 — 룰 업데이트를 컨테이너 재배포 없이 .wasm 모듈 교체로 처리한다는 점.
토스(Toss) — 한국
토스의 일부 보안 검증 로직(클라이언트 위변조 탐지)이 WASM으로 컴파일된 Rust 모듈로 돈다. 토스페이먼츠에서도 PG 가맹점이 올린 검증 룰을 Extism 기반으로 실행. SLASH 2024 컨퍼런스에서 일부 공개.
쿠팡(Coupang) — 한국
쿠팡의 검색 랭킹 추론 일부가 WasmEdge + wasi:nn 위에서 돈다 — 정확히는 ONNX 모델을 WasmEdge에 통합한 형태. 검색 latency 안정성과 다언어 모델 통합에 유리.
ZOZO — 일본
ZOZOTOWN의 추천 시스템 A/B 테스트 인프라에서 실험적 룰을 WASM 모듈로 배포. 룰 변경을 빌드 없이 hot reload하기 위함. 2025년 ZOZO Tech Blog 공개.
Mercari — 일본
Mercari의 결제 검증 일부(특히 신원 확인 룰 엔진)가 WASM 기반. 2026년 초 Mercari Engineering Blog에 사례 공개.
CyberAgent — 일본
CyberAgent의 광고 서빙 일부 엣지 로직을 SpinKube 위에서 운영. Spin/SpinKube를 가장 적극적으로 production에 적용한 일본 사례 중 하나.
NTT 도코모·KDDI
5G MEC(Multi-access Edge Computing) 노드에서 WasmEdge를 컨테이너 대안으로 실험 중. 작은 풋프린트와 빠른 콜드스타트가 5G 엣지에 맞기 때문. 2025년 NTT Technical Review에 사례 게재.
13장 · 도구 모음 — WAC·Jco·wasm-tools·Wash
마지막으로 매일 쓰는 도구 모음.
wasm-tools
Bytecode Alliance의 만능 CLI. **모르면 일단 wasm-tools.**
컴포넌트 헤더 확인
wasm-tools component wit greeter.wasm
컴포넌트 검증
wasm-tools validate --features all greeter.wasm
WAT 디스어셈블
wasm-tools print greeter.wasm | less
컴포넌트 -> 어셈블된 코어 모듈
wasm-tools component unbundle greeter.wasm
WAC (WebAssembly Composition)
**여러 컴포넌트를 조합해 더 큰 컴포넌트를 만드는 도구.** Component Model의 진가는 컴포지션에서 나온다. WAC가 그걸 가능하게 한다.
auth 컴포넌트 + storage 컴포넌트를 묶어 app 컴포넌트로
wac compose -d auth=./auth.wasm -d storage=./storage.wasm \
-o app.wasm composition.wac
package example:app;
let auth = new auth:lib { ... };
let storage = new storage:lib { ... };
let app = new app:lib {
authenticator: auth.authenticator,
store: storage.store,
};
export app...;
Jco (JavaScript Component Toolkit)
**JS와 컴포넌트 모델의 다리.** 두 방향 모두 지원.
1. .wasm 컴포넌트를 JS에서 호출 — `jco transpile greeter.wasm` → ES 모듈 wrapper 생성.
2. JS 소스를 컴포넌트로 컴파일 — `jco componentize greet.js -w greet.wit` → .wasm 컴포넌트 생성(StarlingMonkey JS 엔진 임베드).
Rust 컴포넌트를 JS에서 쓰기
jco transpile ./greeter.wasm -o ./out
그러면 out/greeter.js, out/greeter.d.ts, out/greeter.core.wasm 생성
console.log(hello('world')) // "Hello, world!"
Wash (wasmCloud Shell)
wasmCloud의 CLI/REPL. wasmCloud는 또 다른 WASM 플랫폼인데, 분산 액터(actor) 모델 위에 컴포넌트를 얹는 접근. NATS 메시지 버스 위에서 액터가 서로 통신.
로컬 wasmCloud 호스트 실행
wash up
컴포넌트(액터) 시작
wash start component ghcr.io/wasmcloud/components/http-hello-world-rust:0.1.0
capability provider 시작 (HTTP 서버)
wash start provider ghcr.io/wasmcloud/http-server:0.20.0
언제 wasmCloud를 쓰나 — 분산 액터 모델이 맞는 워크로드(IoT·게임 서버·분산 시뮬레이션), 다수 노드에 컴포넌트를 동적으로 배포해야 할 때. Spin이 "서버리스 함수"라면 wasmCloud는 "분산 액터 메시 + 컴포넌트".
에필로그 — 2026년 우리가 WASM을 보는 법
여기까지가 2026년 5월 WASM 생태계의 지도다. 한 번에 머리에 들어오게 다시 줄이면:
1. **표준이 굳었다.** WASI 0.2(컴포넌트 모델)가 2024.01 GA, WASI 0.3(async)이 2025.Q4 GA. 이제 "기다리는 단계"는 끝났다.
2. **런타임은 4강.** Wasmtime(표준), Wasmer(상업+레지스트리), WasmEdge(엣지/IoT), Spin(서버리스 플랫폼). 모르면 Wasmtime.
3. **WASM의 가장 큰 가치는 더 이상 "빠른 브라우저 코드"가 아니다.** "한 번 빌드해서 브라우저·서버·엣지·플러그인 호스트에서 다 돌리는" 보편 실행 계층이다. Component Model이 그걸 가능하게 했다.
4. **누가 쓰나 — 대형 회사들이 이미 production에서 쓴다.** Cloudflare·Shopify·Fastly·Figma·Adobe·라인·토스·쿠팡·ZOZO·Mercari·CyberAgent.
5. **언제 쓰나** — (a) 사용자 코드를 안전하게 실행해야 할 때(Extism), (b) 엣지 함수 콜드스타트가 짧아야 할 때(Spin·WasmEdge), (c) 멀티 언어 라이브러리를 서버 사이드에서 호출해야 할 때(Wasmtime+Component Model), (d) 무거운 네이티브 로직을 브라우저에 옮길 때(Emscripten·wasm-bindgen).
6. **언제 안 쓰나** — 평범한 마이크로서비스, 네이티브 OS API가 깊게 필요한 코드, GPU 직접 접근(아직 wasi:graphics 표준화 중), 기존 컨테이너 워크로드에 만족할 때.
마지막 한 줄. 2017년 WASM 1.0이 브라우저에 들어왔을 때 누가 9년 뒤 Cloudflare·Shopify·라인이 production을 굴리고 있을 거라고 예상했을까. **표준 하나가 GA되는 데 7년, 시장이 그 표준 위에 올라타는 데 또 2년**. 이게 인프라가 굳는 속도다. 지금이 2026년이고, 우리가 안 쓰면 옆 팀이 쓴다.
참고 / References
- WebAssembly 공식 사이트: https://webassembly.org/
- WASI 0.2 — finalized 발표 (Bytecode Alliance, 2024.01): https://bytecodealliance.org/articles/WASI-0.2
- WASI 0.3 — async 도입: https://bytecodealliance.org/articles/wasi-0-3
- Component Model 명세: https://github.com/WebAssembly/component-model
- WIT 포맷 문서: https://component-model.bytecodealliance.org/design/wit.html
- Wasmtime: https://wasmtime.dev/
- Wasmtime GitHub: https://github.com/bytecodealliance/wasmtime
- Wasmer: https://wasmer.io/
- Wasmer GitHub: https://github.com/wasmerio/wasmer
- WasmEdge: https://wasmedge.org/
- WasmEdge CNCF Incubating: https://www.cncf.io/projects/wasmedge/
- Spin (Fermyon): https://spinframework.dev/
- Spin GitHub: https://github.com/spinframework/spin
- SpinKube: https://spinkube.dev/
- Extism: https://extism.org/
- Extism GitHub: https://github.com/extism/extism
- Wing (Winglang): https://www.winglang.io/
- Wing GitHub: https://github.com/winglang/wing
- wasm-tools: https://github.com/bytecodealliance/wasm-tools
- WAC (WebAssembly Composition): https://github.com/bytecodealliance/wac
- Jco (JS Component Toolkit): https://github.com/bytecodealliance/jco
- wasmCloud: https://wasmcloud.com/
- Wash CLI: https://wasmcloud.com/docs/cli
- WebAssembly GC 제안: https://github.com/WebAssembly/gc
- Kotlin/WASM (JetBrains): https://kotlinlang.org/docs/wasm-overview.html
- Dart/WASM (Google): https://dart.dev/web/wasm
- Cloudflare Workers Component Bindings: https://blog.cloudflare.com/wasi-and-component-model-workers
- Shopify Functions: https://shopify.dev/docs/api/functions
- Fastly Compute: https://www.fastly.com/products/edge-compute
- Figma 렌더링 엔진과 WASM: https://www.figma.com/blog/webassembly-cut-figmas-load-time-by-3x/
- Photoshop Web (Adobe): https://blog.adobe.com/en/publish/2021/10/26/share-the-magic-of-photoshop-on-web-beta
- AutoCAD Web: https://www.autodesk.com/products/autocad-web-app/overview
- Bytecode Alliance: https://bytecodealliance.org/
- runwasi (containerd shim): https://github.com/containerd/runwasi
- crun WASM 백엔드: https://github.com/containers/crun
- 한국 라인 엔지니어링 블로그: https://engineering.linecorp.com/ko/blog
- 토스 SLASH 컨퍼런스: https://toss.tech/slash
- ZOZO TECH BLOG: https://techblog.zozo.com/
- Mercari Engineering Blog: https://engineering.mercari.com/
- NTT Technical Review: https://www.ntt-review.jp/
현재 단락 (1/313)
2017년 WebAssembly 1.0 MVP가 브라우저에 들어왔을 때, 사람들은 두 가지를 약속받았다. "브라우저에서 C/C++/Rust를 거의 네이티브 속도로 돌릴 수 있다."...