WebAssembly 프로젝트가 10년 동안 표준화와 생태계 확장을 거치며 웹과 서버, 임베디드로 퍼져 나간 과정을 초기 공동 설계자들의 회고로 돌아본다.
2026년 1월 22일 Eric Gregory
2015년 4월, Luke Wagner는
plaintextWebAssembly/design
라는 새 저장소에 처음 커밋을 올렸고, “웹 컴파일 타깃으로 쓰일 바이너리 포맷”을 위한 고수준 설계 문서를 추가했습니다.
그로부터 4년 뒤인 2019년 12월, World Wide Web Consortium(W3C)은 WebAssembly(Wasm)를 ‘웹의 네 번째 언어’로 공식 채택했습니다. 오늘날 Wasm은 Google Earth와 Adobe Photoshop 같은 웹 애플리케이션, Amazon Prime Video와 Disney Plus 같은 스트리밍 비디오 서비스, 그리고 Unity 같은 게임 엔진에서 사용됩니다. Wasm은 수많은 임베디드 장치에서 동작하며, 클라우드 컴퓨팅 제공업체들은 Wasm을 이용해 FaaS(Functions-as-a-Service) 및 서버리스 기능을 제공합니다.
표준화(그리고 과소평가된 보편성)에 이르는 길은, 과거에 많은 이들이 시도했다가 실패한 문제를 해결하기 위한 접근법을 두고 주요 브라우저 뒤의 팀들이 하나로 뭉치는 과정을 필요로 했습니다.
프로젝트 10주년(정확히는 10년 조금 넘은 시점)을 맞아, 저는 초기에 함께 설계했던 여러 공동 설계자들과 이야기를 나눴습니다. 그들은 프로젝트의 기원에 대한 기억, 그리고 앞으로 10년의 WebAssembly에 대한 상상을 아낌없이 들려주었습니다.
2013년 3월, Wagner, Alon Zakai, Dave Herman 등을 포함한 Mozilla 엔지니어 그룹은 asm.js를 공개했습니다. asm.js는 기존 JavaScript 언어의 부분집합을 정의했는데, 여기에는 충분한 정적 타입 정보가 암묵적으로 포함되어 있어 브라우저의 기존 JS 엔진이 “최적화기가 이를 염두에 두고 보도록” 만들면 훨씬 더 좋은 성능을 낼 수 있었습니다. Wagner의 표현으로는 “엄청 해키하다(Super hacky)”는 것이었죠.
한편 Google은 Chrome에서 네이티브 코드를 샌드박싱해 실행하기 위한 Native Client(NaCl)와 그 후속인 Portable Native Client(PNaCl)을 개발하고 있었습니다.
JF Bastien은 당시 Chrome 팀에 있었고, NaCl의 Armv7 버전을 마무리하는 데 기여했습니다. Bastien에 따르면 NaCl은 안전한 샌드박스였지만 이식성이 없었고, 웹의 ‘정신(ethos)’을 “완전히 존중하지” 않았습니다.
PNaCl은 신뢰할 수 없는 코드를 웹 페이지의 나머지 부분 및 JavaScript와 분리된 별도 프로세스에 두었습니다. 이는 샌드박싱 관점에서 합리적 선택이지만, JavaScript가 PNaCl 코드를 호출하거나 그 반대를 하기가 어려웠습니다. PNaCl과 브라우저 나머지 부분의 연결은 메시지 패싱에 의존했는데, 이는 그래픽, 오디오, 네트워킹에 대해 완전히 별도의 API 표면을 요구했습니다. 또한 프로그래밍 모델로서 비동기를 강제했으며, 이를 성공적으로 해내려면 부담이 매우 컸습니다. 이런 점들이 더 넓은 채택에 장애물이 되었습니다. PNaCl이 웹에서 네이티브 코드를 다루기 위한 멀티 브라우저 접근의 기반이 되려면, 어떤 표준화 기구가 API들을 관장해야 할까요?
asm.js는 다른 접근을 취했습니다. 당시 Mozilla에 있던 Dan Gohman은 이를 “신뢰된 호출 스택(trusted call stack)”이라고 설명합니다. 컴파일된 코드와 JavaScript가 같은 스택을 공유할 수 있다는 뜻입니다.
“즉 asm.js는 JavaScript와 공존할 수 있었죠,”라고 그는 말합니다. “JavaScript로 들어갈 수도 있고, JavaScript가 당신 쪽을 호출할 수도 있어요.” 이 설계 결정은(이후 WebAssembly가 계승) 기반이 되는 요소가 되었고, 브라우저와의 매끄러운 통합부터 컴포넌트 모델에서 격리 경계를 넘나드는 함수 호출까지 가능하게 했습니다.
2013년 말이 되자 개발자들은 이미 Alon Zakai가 만든 Emscripten 툴체인을 이용해 C++ 게임을 asm.js로 컴파일하고 있었습니다. Mozilla 팀은 네이티브 코드를 실행하기 위한 해법으로서 asm.js를 브라우저에 어떻게 통합할지(그리고 통합해야 할지) 고민하고 있었습니다.
Google에서는 V8 팀이 TurboFan이라는 새 최적화 컴파일러의 벤치마크 중 하나로 asm.js 워크로드를 사용했습니다. Ben Titzer가 TurboFan 노력을 이끌었습니다. 다른 많은 Wasm 공동 설계자들처럼, 그는 Mozilla, Apple, Microsoft의 엔지니어들과도 교류했습니다. 때로는 한 회사의 브라우저 팀에서 다른 회사 팀으로 이직하는 경우도 있었고, 이 분야에서 일하다 보면 자연스럽게 협업과 보다 캐주얼한 교류가 생기곤 했습니다. Bastien의 표현을 빌리면 “술 마시며 웹 이야기를 하는(drinking and talking about the web)” 식이었죠.
어느 날 Titzer는 Wagner와 asm.js에 대한 Mozilla 팀의 계획을 두고 대화를 나누게 되었습니다.
“우리가 Google 사람들과 이야기했는데,” Wagner는 말합니다. “그들은 ‘우린 이거 싫다. 이상하고, 지저분하고, 즉흥적이고… 왜 이런 걸 하냐? 이런 걸 하고 싶으면 진짜 바이트코드를 만들라’고 했죠. 우리는 ‘그래, 만들 수도 있다. 그러면 asm.js는 그에 대한 폴리필이 될 거다’라고 답했고요.”
“Titzer는 “[asm.js]는 근본적으로 ArrayBuffer 같은 것들이 효율적이라는 전제에 의존했어요,”라고 회상합니다. “Luke와 리사이즈 가능한 ArrayBuffer(resizable array buffer)와 그것이 detach될 수 있는지에 대해 대화했던 기억이 나요. 그는 기본적으로 이게 좋은 거라고 우리를 설득하려고 했죠. 그리고 툭 던지듯이 Mozilla가 asm.js가 올바른 길이 아닐지도 모른다고 생각하고 있다, 바이트코드를 설계해야 할지도 모른다고 말했어요. 그 말에 귀가 번쩍 뜨였죠.”
Titzer와 Wagner는 함께 일하기로 합의했지만, 이제는 더 넓은 동의를 확보해야 했습니다. Wagner에 따르면, 두 사람은 이렇게 계획을 세웠습니다. “서로의 매니저에게 상대방이 이미 동의했다고 말할 거예요.”
Titzer는 프로토타입을 만들기 시작했고, 2014년 말쯤 V8 팀의 관심이 이 노력에 결정적인 추진력을 제공했습니다. 곧이어 Google의 PNaCl 팀도 합류했고, Bastien은 프로젝트의 핵심 조직자 중 한 명이 되었습니다.
누군가 WebAssembly를 정의할 때, 고대 로마 제국(신성 로마 제국)에 관한 오래된 농담을 변주해 “웹도 아니고, 어셈블리도 아니다(neither web, nor assembly)”라고 말할 확률이 꽤 높습니다. 즉, 웹에만 국한된 것도 아니고 엄밀히 어셈블리 언어도 아니라, 가상 명령어 집합 아키텍처를 대상으로 하는 바이트코드 포맷이라는 뜻입니다.
그렇다면 이름은 정확히 어디서 왔을까요?
“asm.js의 유산이 있으니 이름에 _asm_이 들어가길 원했고,” Wagner는 말합니다. “그리고 _web_을 원했던 건, 당시 멋진 표준들 이름에 WebGL, WebGPU처럼 _web_이 들어갔기 때문이에요… 이게 친(親)웹(pro-web)인 것임을 아주 분명히 하고 싶었죠.”
공동 설계자들은 잠시 “WebAsm”을 고려했지만(아마도 현명하게) 그 이름은 넘겼습니다. 그래서 “Asm”을 풀어 써서 “Assembly”가 되었고, WebAssembly가 됐습니다.
Bastien은 이름에 대한 내부 반발을 떠올립니다. “이게 웹 밖에서도 쓰일 걸 알고 있었죠,”라고 그는 말합니다. “우리는 웹 밖에서도 쓰이도록 _설계_하고 있었고요.” 하지만 다른 대안이 딱히 나오지 않았고, 결국 “WebAssembly”가 굳어졌습니다.
저 역시 “웹도 아니고 어셈블리도 아니다”라는 말을 여러 번 써왔고, 제가 인터뷰한 Wasm 공동 설계자들 중 몇 명도 그랬습니다. 하지만 Wagner는 그 표현에 대해 조심스레 반박합니다.
“asm.js라는 경로 의존성을 잠시 제쳐두면, ‘바이트코드’나 ‘중간 언어’가 좀 더 정확했을지도 모르죠,”라고 그는 말합니다. “하지만 웹 밖에서 쓰인다는 이유로 ‘웹’이 아니라고들 말하는데… 그럼 웹의 정의는 무엇일까요? 브라우저 안의 것만 웹인가요? W3C는 오픈 웹 플랫폼에 대해 훨씬 더 넓은 그림을 그리고 있고, 그 정의는 WebAssembly가 오늘날 실행되는 많은 장소와, 앞으로 실행되길 원하는 더 많은 장소를 포괄한다고 생각합니다.”
Chrome과 Firefox 팀이 같은 방향을 보게 되자, 공동 설계자들은 Apple과 Microsoft 팀으로 눈을 돌렸습니다.
Edge 브라우저의 JavaScript 엔진을 담당하던 Microsoft Chakra 팀은 이미 asm.js 최적화를 구현해 둔 상태였습니다. Wagner는 채택을 쉽게 만들기 위해 Mozilla 소스 코드를 직접 재라이선스(relicense)하기도 했습니다. Wagner의 말로는 “강도 높은 Q&A” 끝에 Chakra 팀도 합류했습니다. Apple에서는 JavaScriptCore 팀 리드 Fil Pizlo(바로 Fil-C의 그 Fil)가 동의를 확보하는 데 핵심적인 역할을 했습니다.
네 개의 브라우저 엔진—Mozilla의 SpiderMonkey, Google의 V8, Microsoft의 Chakra, Apple의 JavaScriptCore—은 서로 몇 달 차이로 WebAssembly 지원을 출시하게 됩니다. 이 시기 WebAssembly Community Group의 의장을 맡았던 Bastien은 W3C 표준화 과정의 조직 구조와 운영 속도를 잡는 데 도움을 줬습니다. Wagner가 첫 공개 커밋을 하기 전에도, 팀은 공유 Google Doc에서 프로젝트의 기본 윤곽을 정리했습니다. 이후 Wagner가 그 합의를 공개 마크다운 파일로 옮겨 적었습니다.
공식 발표는 조율되어 진행됐습니다. 2015년 6월 17일, 네 브라우저가 동시에 서로를 링크하는 블로그 글을 공개했습니다. Brendan Eich는 자신의 블로그 글을 올려 JavaScript 창시자로서 프로젝트에 권위를 더했고, 발표를 마무리할 때 자주 하던 농담을 변주했습니다.
저는 보통 농담으로 “항상 JS에 베팅하라(Always bet on JS)”로 마무리합니다. 그 문장에 “그리고 wasm(and wasm)”을 끼워 넣어 일할 날을 기대합니다 — 농담이 아니라요.
프로젝트가 진행되는 동안 Lin Clark의 커뮤니케이션은 커뮤니티의 이해를 쌓는 데 큰 역할을 했습니다. 예를 들어 Mozilla 블로그의 WebAssembly 모듈 생성 및 사용 같은 글들이 그랬습니다.
Wasm을 만들던 그룹에게 출시 압박은 매우 컸습니다. Wagner에 따르면 당시 지배적인 정서는 “이 연합이 무너지기 전에, 인간이 할 수 있는 한 최대한 빨리 출시하라”였습니다. 돌아보면 그 긴급함은 선견지명이었습니다. 만약 WebAssembly가 지연됐다면, 2018년 초 공개된 Spectre 취약점이 스레딩 관련 이야기를 복잡하게 만들었을 수도 있고, 프로세스 밖(out-of-process) 격리 모델을 선호하던 이들에게 PNaCl 쪽의 논리를 강화해 주었을지도 모릅니다. Firefox가 2017년 3월 가장 먼저 출시했고, Chrome이 몇 주 뒤 뒤따랐습니다. 그해 말까지 네 주요 브라우저 모두 WebAssembly를 지원했습니다.
Wagner는 Facebook이 조용히 asm.js를 사이트에 통합해 업로드 전에 JPEG를 압축하고 있다는 사실을 알게 됐던 일을 기억합니다. “그들은 우리에게 말하지 않았어요,”라고 그는 말합니다. “그냥 해버렸죠.”
Wasm이 아이디어에서 스펙, 그리고 현실로 넘어가면서 점점 더 많은 조직이 관심을 갖기 시작했습니다. 브라우저 벤더 간 두 번째 오프라인 미팅에서는, 스펙이 완성되려면 한참 남았던 시점임에도 Zynga의 대표가 나타났습니다. 당시 Farmville 등 Facebook 게임으로 가장 잘 알려져 있던 Zynga는 Flash 위에 수십억 달러 규모의 비즈니스를 쌓아올렸습니다. 하지만 Flash가 폐지 수순에 들어가면서 대안을 찾고 있었던 것입니다.
게임은 처음부터 대화의 일부였습니다. 초기 데모에는 Unity의 “Angry Bots”가 여러 브라우저에서 동작하는 모습이 포함돼 있었습니다. 이제 다른 웹 애플리케이션 팀들의 관심이 커지며 프로젝트 개발에도 영향을 주기 시작했습니다. Adobe 엔지니어 Sean Parent는 웹에서 Photoshop을 제공하려는 노력에 의해 스레드와 강력한 연산 기능 같은 특성이 필요하다는 점을 초기에 피드백해 주며 중요한 역할을 했습니다.
“Zynga뿐만 아니라 Unity도 그렇고, Adobe가 Photoshop을 출시하려 하고 Google Earth가 새 버전의 Google Earth를 출시하려 한다는 걸 깨달았죠,”라고 Titzer는 말합니다. “플랫폼으로 들어오려는 이런 거대한 애플리케이션들이 많았고, 그들이 이를 진짜로 취급하고 있었어요. 그때가 아마도, 이게 정말 큰 차이를 만들어낼 무언가가 되겠구나라고 깨달았던 지점이었던 것 같아요.”
asm.js는 WebAssembly MVP를 위한 가장 어려운 질문들에 답을 주는 데 도움이 됐습니다. 보안 모델은 무엇인가? 어떤 기능이 범위 안인가? 누군가 코루틴이나 스택 스위칭을 추가하자고 제안하면, Gohman에 따르면 답은 간단했습니다. “그건 asm.js에 없어요. 범위 밖. 끝.” Bastien의 말처럼 팀은 “asm.js에서 1급으로 취급되지 않던 몇 가지”는 허용했지만, asm.js는 길잡이 역할을 했습니다.
WebAssembly 진화의 다음 단계에는 그런 발판이 없었습니다. 코어 스펙이 출시되고 브라우저들이 합류하자, 관심은 브라우저 밖—서버, 엣지, 임베디드 시스템—에서 WebAssembly를 실행하는 것으로 옮겨갔습니다. 이는 WebAssembly System Interface(WASI)를 정의하고, 결국 컴포넌트 모델로 나아가는 것을 의미했습니다. 이 스펙들이 함께하면 Wasm 바이너리들끼리 서로 통신할 수 있습니다. 이런 “Wasm 컴포넌트”는 어떤 언어로 작성됐든 상관없이 안전하게 상호운용할 수 있게 됩니다.
설계 공간은 갑자기 엄청나게 넓어졌습니다.
“가장 놀랐던 건, 브라우저 밖에서 Wasm으로 무엇을 해야 할지—POSIX를 그대로 베끼지 않으면서—결정하는 게 얼마나 어려웠는가였어요,”라고 Wagner는 말합니다. 유닉스 스타일 접근은 유혹적이었습니다. WebAssembly 모듈에 파일, 소켓, 프로세스 접근을 익숙한 방식으로 그냥 제공하면 되니까요. 하지만 Wagner는 함정을 봤습니다. “POSIX를 그대로 복사하면, 결국 Wasm을 내부에 넣은 컨테이너를 다시 구현하게 될 뿐이에요.” 이는 명확한 이점이 아닙니다. 이식성은 다소 좋아지겠지만 실행 오버헤드를 강제합니다. 그리고 개선 폭이 크지 않다면, 왜 그렇게 많은 일을 해야 할까요?
WASI 설계 작업의 상당 부분을 이끌게 된 Gohman은 초기의 분위기를 위압적이었다고 회상합니다. “WASI를 섞는 순간, 이제 모든 것에 API를 추가하겠다는 얘기가 되죠,”라고 그는 말합니다. “그래픽, 네트워킹, 입력 장치—브라우저에서 할 수 있는 모든 것. 그런데 이제 서버까지 들어오니 데이터베이스도 얘기해야 하죠. 세상에 있는 API를 하나만 말해 봐요. 전부 WASI 범위 안이에요.”
이 난제는 기존 표준이라는 발판 없이, 언어 간 API를 설계해야 한다는 요구로 더 커졌습니다. WASI는 C 스타일 인터페이스를 제공해야 할까요? JavaScript 스타일이어야 할까요? 아니면 RPC 프로토콜일까요? 결론적으로 답은 그 어느 것도 아니었습니다. 팀은 어떤 대상 언어에도 관용적인(idiomatic) 바인딩을 생성할 수 있는 인터페이스 정의 언어인 WebAssembly Interface Type(WIT)을 개발했습니다.
2019년 3월, Mozilla는 WASI를 발표했고, Docker의 창시자 Solomon Hykes의 관심을 끌었습니다. Hykes는 트위터에 다음과 같이 유명한 글을 올렸습니다.

이후 “WASI Preview 1”로 불리게 된 첫 번째 이터레이션은 파일 I/O와 환경 변수 같은 기본 역량을 제공했지만, 네트워킹과 스레딩은 부족했습니다. Lin Clark은 웹 밖에서 WebAssembly를 실행하기 위한 시스템 인터페이스, WASI 표준화 같은 블로그 글로 프로젝트의 비전을 계속 전달하는 데 도움을 줬습니다.
5년 뒤인 2024년 1월, WASI 서브그룹은 WASI 0.2(Preview 2라고도 함)를 출시했는데, 여기에 컴포넌트 모델이 통합되고 사용 가능한 API들이 확장되었습니다.
2026년에는 네이티브 async와 협력적 스레드(cooperative threads)를 도입하는 WASI 0.3이 예정되어 있으며, 그 다음으로 1.0 릴리스가 뒤따를 계획입니다.
Titzer는 현재 카네기멜런(Carnegie Mellon) 대학의 소프트웨어 및 사회 시스템(Software and Societal Systems) 학과에서 부교수로 재직하며, 임베디드 시스템과 인공지능이라는 두 영역에 관심을 두고 있습니다. 이 두 영역은 WebAssembly의 핵심 속성이 변혁적 역할을 할 수 있는 분야이기도 합니다. 그는 산업용 컨트롤러와 사이버-물리 시스템에 WebAssembly를 통합하는 프로젝트를 진행해 왔습니다.
“[산업 자동화 회사들]은 모바일 코드 문제를 갖고 있어요,”라고 그는 설명합니다. 이는 네트워크를 통해 전송된 뒤 원격 머신에서 실행될 수 있는 소프트웨어를 말합니다. “핵심적으로, Wasm이 어떤 문제를 해결했다면 그건 신뢰할 수 없는 모바일 코드를 실행하는 문제예요.” 같은 원리는 AI가 생성한 애플리케이션을 샌드박싱하는 데도 적용됩니다. “AI가 코드를 생성하잖아요—그게 무슨 일을 하는지 누가 알겠어요? 그 코드를 신뢰하나요? 아니요.”
Bastien도 동의합니다. “AI 코딩 에이전트는 지금 꽤 불안정해요(보안 면에서), 특히 서드파티 플러그인은요. 단순히 인젝션만의 문제가 아니죠. 예컨대, 신뢰하지 않는 코드를 한가득 실행하게 되는 거예요. Wasm은 꽤 흥미로운 적합성을 갖고 있죠.”
한편, 브라우저 밖 맥락에서 얻은 Wasm의 혁신 일부가 다시 ‘집’으로 돌아올 수도 있습니다. Wagner는 컴포넌트 모델이 브라우저에서 실행되도록 원하는 언어를 컴파일하는 웹 개발자 경험의 질을 개선할 것이라고 봅니다. 기존의 대체로 JS인 웹 앱에 섞어 넣는 방식이든, 웹 앱 전체를 구현하는 방식이든 말입니다.
오늘날 WebAssembly는 수십억 사용자들의 브라우저에서 실행될 뿐 아니라, 엣지 네트워크, 클라우드, 임베디드 시스템에서도 동작합니다. 이 프로젝트는 표준화를 이루었고, 과장 없이도 널리 퍼져 있습니다. 지금 이 순간에도, 여러분이 가장 자주 쓰는 앱 중 하나가, 여러분이 매일 쓰는 기기 중 하나에서, 거의 확실히 WebAssembly를 실행하고 있을 겁니다. 10년 뒤의 Wasm은 무엇이, 어디에 있을까요? asm.js까지 거슬러 올라가는 아키텍처의 기본 원리들은 방대한 가능성의 공간으로 향하는 문에 발을 걸쳐 둔 셈이었습니다.
Gohman의 관점에서 WebAssembly는 “컴퓨팅 산업이 진정으로 클라우드 네이티브한 실행 환경을 실제로 구축할 수 있는 몇 안 되는 기회 중 하나”입니다. Wasm은 전통적인 운영체제가 설계된 방식과는 다른 아키텍처—신뢰된 호출 스택부터 시작해—와, 웹에서 출발해 넓은 관련성을 함께 갖고 있습니다. 그는 끈기가 필요하겠지만, 어쩌면 50년 만에 처음으로 커널과 사용자 공간의 경계에서 혁신할 기회가 생겼다고 말합니다.
“긴 여정이 될 거예요,”라고 그는 말합니다. “우리는 멋진 것들을 많이 만들 겁니다. 그리고 아주 즐거운 시간을 보낼 거예요.”
정관 | IP 정책 | Copyright © 2019-2023 the Bytecode Alliance contributors.