Porting Curveball to Bun – Evert Pot

Bun is the hot new server-side Javascript runtime, in the same category
as Node and Deno. Bun uses the JavascriptCore engine from
Webkit, unlike Node and Deno which use V8. A big selling point is that
it’s coming out faster in a many benchmarks, however the things I’m personally
excited about is some of it’s quality of life features:

  • It parses Typescript and JSX by default (but doesn’t type check), which
    means there’s no need for a separate ‘dist’ directory, or a separate tool
    like ts-node.
  • It loads .env files by default.
  • It’s compatible with NPM, package.json, and many built-in Node modules.

I also like that it’s ‘Hello world HTTP server’ is as simple as writing this
file:

// http.ts
export default { port: 3000, fetch(request: Request): Promise<Response> { return new Response("Hello world!"); },
};

And then running it with:

bun run http.ts

Bun will recognize that an object with a fetch function was default-exported,
and start a server on port 3000. As you can see here, this uses the standard
Request and Response objects you use in a browser, and can use
async/await.

These are all things that didn’t exist when Node and Express were first
created, but seem like pretty good ideas for something built today. I don’t think
using Request and Response are good for more complex use-cases (streaming
responses, 1xx responses, trailers, upgrading to other protocols, getting tcp
connection metadata like remoteAddr are some that come to mind),
because these objects are designed for clients first.

But in many cases people are just building simple endpoints, and for that it’s
great.

Bun supports a ton of the standard Node modules, but it’s also missing some
such as support for server-side websockets and the node http/https/https
packages, which for now makes it incompatible with popular frameworks like
Express.

Porting Curveball

Curveball is a Typescript micro-framework we’ve been developing since
mid-2018 as a modern replacement for Express and Koa. A key difference between
Curveball and these two frameworks is that it fully abstracts and encapsulates
the core ‘Request’ and ‘Response’ objects Node provides.

This made it very easy to create a lambda integration in the past; instead of
mapping to Node’s Request and Response types, All I needed was simple mapping
function for Lambdas idea of what a request and response looks like.

To get Express to run on AWS Lambda the Node http stack needs to be emulated, or
a full-blown HTTP/TCP server needs to be started and proxied to. Each of these
workarounds require a ton of code from libraries like serverless-express.

So with Bun up and coming, either the same work would need to be done to emulate
Node’s APIs, or Bun would would need to add full compability for the Node http
module (which is eventually coming).

But because of Curveball’s message abstractions it was relatively easy to get
up and running. Most of the work was moving the Node-specific code into a new
pa

Truncated by Planet PHP, read more at the original (another 6665 bytes)