Cloudflare y Google llevan Rust nativo a Workers con Emscripten

Rust nativo llega a Cloudflare Workers: qué cambia con el nuevo target Emscripten

Cloudflare y Google publicaron el primer preview experimental del soporte nativo para Rust —incluyendo aplicaciones basadas en Tokio— en Cloudflare Workers, gracias al nuevo target wasm32-unknown-emscripten para wasm-bindgen. La demostración más llamativa: un servidor de Minecraft escrito en Rust corre dentro de un Durable Object con sockets TCP reales, una proeza técnica que hasta ahora exigía máquinas dedicadas.

¿Qué problema técnico resuelve este anuncio?

Desde hace años, los desarrolladores que querían correr Rust en Workers tenían que compilar contra wasm32-unknown-unknown, un target mínimo que dejaba fuera a casi todo el ecosistema de crates de sistemas: nada de Tokio, nada de sockets, nada de sistema de archivos. El resultado era un Wasm funcional pero amputado, útil para lógica de negocio pero inútil para reusar librerías existentes.

El nuevo target wasm32-unknown-emscripten cambia esa ecuación. Emscripten —el toolchain de WebAssembly creado originalmente por Mozilla y mantenido hoy por ingenieros de Google— virtualiza timers, sistema de archivos y sockets sobre el entorno del host. Cloudflare Workers ya soporta las Web Platform APIs y la capa de compatibilidad Node.js, así que esa virtualización se monta directamente sobre las APIs de Node expuestas en Workers.

👥 ¿Quieres ir más allá de la noticia?

En nuestra comunidad discutimos las tendencias, compartimos oportunidades y nos ayudamos entre emprendedores. Sin humo, solo acción.

👥 Unirme a la comunidad

Para un founder técnico, la implicación es concreta: código Rust que ya tienes en tu backend monolítico ahora puede reusarse en el edge sin reescribirlo a JavaScript.

Una alianza técnica que arrancó hace más de un año

El trabajo de integrar wasm-bindgen con Emscripten lo inició el equipo de Portable Toolchains de Google, cuando un equipo interno quería usar las bindings de wasm-bindgen desde código C++. Mitch Foley y Yifan Yang, de Google, diseñaron un plan cooperativo: Emscripten conduce el build, carga el Wasm y genera el JavaScript acompañante; wasm-bindgen produce una versión portable de sus bindings para que Emscripten las pueda incluir.

El reto no era solo técnico: ambos proyectos tenían que aceptar mantener tests de integración que dependían del otro. Tras la revisión conjunta de los equipos de Portable Toolchains y Wasm Tools de Google, junto a los ingenieros de Cloudflare, aterrizaron dos configuraciones que ahora coexisten:

  • El flag -sWASM_BINDGEN: código C++/Emscripten puede linkear contra Rust estático compilado con wasm-bindgen.
  • El target Emscripten para Rust: aplicaciones wasm-bindgen pueden construirse contra el linker de Emscripten.

¿Cómo se mete Tokio dentro del event loop de un Worker?

Tokio es la librería async más usada en el ecosistema Rust, pero su modelo de hilos bloqueantes era incompatible con el event loop single-threaded de Workers. Cloudflare exploró dos rutas:

JSPI (JavaScript Promise Integration) permite que una llamada Wasm bloqueante suspenda su stack y devuelva el control al event loop, igual que un park de Tokio. El problema: el runtime context de Tokio vive en un thread-local, y JSPI no cambia de hilo, así que la nueva pila y la suspendida comparten el contexto y Tokio entra en pánico. La solución fue intercambiar el thread-local en cada enter, exit, suspend y resume —un time-multiplexing cooperativo donde cada stack suspendido carga su propio contexto.

LocalEventLoop rediseña el runtime para que el wait no sea un park sino un wake: el host posee el Waker y el runtime le avisa cuando hay trabajo. El siguiente drive() corre un batch de tareas listas y vuelve. block_on sigue existiendo pero entra en panic donde antes habría parqueado — porque ya no hay nada que pueda despertarlo desde dentro. Cloudflare señala que la misma arquitectura se podría embeber en un GTK main loop, un Win32 message pump o un Cocoa run loop.

El primer patch de soporte para wasm32-unknown-emscripten ya está mergeado upstream en Tokio; el resto se está revisando con los equipos de Tokio y Emscripten.

El bridge de sockets: 40+ PRs a Emscripten

Tokio construye su I/O driver sobre epoll_wait, pero Emscripten solo exponía poll() y una emulación sobre WebSockets. La opción obvia era implementar un bridge custom entre la virtualización de Emscripten y las APIs de sockets de Workers. La elegante fue reusar node:net, que Cloudflare ya soporta en su capa de compatibilidad Node.js.

El resultado, tras más de 40 pull requests a Emscripten, es el flag de compilación -sNODERAWSOCKETS, que habilita soporte para epoll, TCP, UDP y Unix sockets para aplicaciones Emscripten en Node.js — y, dado que Workers implementa la misma API node:net, también en Workers. Bajo JSPI, epoll_wait() simplemente suspende el stack hasta que haya readiness; bajo LocalEventLoop, se agregó una API propuesta emscripten_epoll_add_listener para que un callback JS alimente el Waker.

Minecraft como banco de pruebas extremo

Para probar el conjunto, se planteó un reto: levantar un servidor de Minecraft en Workers. Dan Lapid implementó Pumpkin —un servidor Minecraft en Rust construido sobre Tokio y diseñado para máquinas multi-core— dentro de un Durable Object en un fin de semana.

Pumpkin normalmente usa un thread pool dedicado para generación de mundo y OS threads separados para el tick loop y el scheduler de chunks. Dentro de un Durable Object hay un solo hilo, así que esos threads se convirtieron en tareas cooperativas sobre el event loop. Los jobs de Rayon pasaron a ser tareas Tokio, y la generación de mundo corre sobre el propio event loop, tomando un turno por chunk e intercalando con I/O de red y game ticks en lugar de bloquearlos.

Para persistencia, Pumpkin escribe su mundo vía std::fs; bajo -sNODERAWFS, las llamadas de sistema de archivos se reenvían a node:fs, que en Workers se sustituye por la librería worker-fs-mount de Dan, cuyo backend durable-object-fs guarda cada archivo como una fila en el SQLite del Durable Object. Cuando el objeto se reinicia, arranca directamente desde el mismo mundo — Pumpkin no sabe que no está en disco.

En red, cada conexión de jugador llega por TCP ingress al connect() del Worker, que la reenvía al Durable Object. handleAsNodeConnection() desde cloudflare:node despacha el socket a un net.Server escuchando dentro del objeto — el equivalente TCP de handleAsNodeRequest(). El backend -sNODERAWSOCKETS implementa TcpListener sobre net.Server, así que el servidor acepta jugadores exactamente como lo haría en Linux.

¿Qué significa esto para tu startup?

1. Reusá tu código Rust existente en el edge sin reescribirlo. Si tu backend monolítico está escrito en Rust sobre Tokio, este target te permite correr la misma lógica en Workers con cambios mínimos —útil para mover piezas específicas cerca del usuario (parsers, validadores, lógica de precios, microservicios de scoring) sin levantar infraestructura dedicada por región.

2. Probá las cargas extremas antes de comprometerte. Cloudflare publicó tres demos progresivas: construir un Worker Rust con Emscripten, correr el runtime async de Tokio dentro de un Worker, y usar sockets TCP en Workers con Emscripten y Tokio. Antes de migrar lógica de negocio, validá con un caso aislado: la compatibilidad de librerías mejoró de forma significativa según Cloudflare, pero los patches a crates como libc, socket2 y Mio todavía están en revisión upstream.

3. Diseñá pensando en event loops cooperativos. Si tu arquitectura ya asume un runtime single-threaded —como Node.js en Workers—, el patrón LocalEventLoop te resultará familiar: no esperes en block_on, estructurá tu código para que el host pueda drive() cuando esté listo. Este criterio se vuelve valioso a medida que más runtimes embebidos (UI, run loops nativos) adopten el mismo modelo.

4. Evaluá contexto de mercado. WebAssembly sigue madurando como plataforma: WASI 0.3, originalmente planificado para marzo de 2025 según InfoWorld, promete soporte nativo de async I/O — un habilitador clave para que desaparezcan este tipo de bridges ad-hoc. Estar cerca de la experimentación tempranera te da ventaja cuando esas APIs se estandaricen.

El estado del proyecto sigue siendo pre-release. Cloudflare pide feedback en GitHub y en el canal #rust-on-workers de su Discord — un buen lugar para founders evaluando migrar lógica de Rust al edge o que necesiten comparar proveedores edge para casos multi-cloud.

Fuentes

👥 ¿Quieres ir más allá de la noticia?

En nuestra comunidad discutimos las tendencias, compartimos oportunidades y nos ayudamos entre emprendedores. Sin humo, solo acción.

👥 Unirme a la comunidad

Daily Shot: Tu ventaja táctica

Lo que pasó en las últimas 24 horas, resumido para que tú no tengas que filtrarlo.

Suscríbete para recibir cada mañana la curaduría definitiva del ecosistema startup e inversionista. Sin ruido ni rodeos, solo la información estratégica que necesitas para avanzar:

  • Venture Capital & Inversiones: Rondas, fondos y movimientos de capital.
  • IA & Tecnología: Tendencias, Web3 y herramientas de automatización.
  • Modelos de Negocio: Actualidad en SaaS, Fintech y Cripto.
  • Propósito: Erradicar el estancamiento informativo dándote claridad desde tu primer café.

📡 El Daily Shot Startupero

Noticias del ecosistema startup en 2 minutos. Gratis, todos los días.

Share to...