As of August 5th, 2025 and wrangler
4.28.0
, Cloudflare Workers extends its Node.js compatibility efforts, and now supports running Express.js apps directly and natively (in local development, production availability coming soon)!
Express.js has long provided the Node.js ecosystem with an incredibly ergonomic way to build web applications and APIs. While these didn't previously work directly with Cloudflare Workers, Hono, itty-router and others provided a familiar experience to end-users, but at the cost of some slight ergonomic differences. Now, you can use Express.js, as well as many other Node.js frameworks directly on Workers!
http
support
The biggest unlock for Cloudflare Workers running express
apps directly now, is the support of http.createServer
via the enable_nodejs_http_server_modules
compatibility flag, and then the new httpServerHandler
API made available via cloudflare:node
imports.
Example
Below is an example express
app that when paired with modern Workers ergonomics like importable env
, make for some really nice DX for those already familiar with these libraries.
Express.js Worker
import { httpServerHandler } from 'cloudflare:node';
import { env } from 'cloudflare:workers';
import express from 'express';
const app = express();
app.get('/hello', (req, res) => res.send('Hello, World!'));
type SaveDataRequest = express.Request<
{},
{},
{ value?: string; }
>;
app.post('/save-data', express.json(), async (req: SaveDataRequest, res) => {
const { value } = req.body;
if (!value) {
return res.status(400).json({ error: 'Value is required' });
}
await env.KV.put('something', value);
return res.send();
});
app.get('/get-data', async (req, res) => {
const data = await env.KV.get('something');
return res.json({ data });
});
app.use((req, res) => res.status(404).send('Not Found'));
app.listen(8080);
export default httpServerHandler({ port: 8080 });
wrangler.toml
name = "test"
account_id = "xxx"
workers_dev = true
compatibility_date = "2025-07-30"
compatibility_flags = [
"nodejs_compat",
"enable_nodejs_http_modules",
"enable_nodejs_http_server_modules",
"experimental"
]
main = "src/worker.ts"
kv_namespaces = [
{ binding = "KV", id = "abc" }
]
And then with curl http://127.0.0.1/hello-world
after running via wrangler dev
, you'll see Hello, World!
- a full express.js app with all of the ergonomics of wrangler and the Cloudflare ecosystem!
So should I migrate away from Hono?
Probably not. Support for more Node.js frameworks lowers the barrier to entry for new Workers users coming from Node.js, but frameworks like Hono are still the gold standard in my opinion for modern Cloudflare Workers development.
It's incredibly cool and exciting however that older Node.js projects are now able to migrate to Workers much more quickly and seamlessly! Cloudflare's workerd runtime team continue to improve their Node.js compatibility all the time, and I look forward to a time where we can hopefully build truly runtime agnostic applications.