Curveball - a TypeScript micro-framework
I’ve been doing Node.js development for a little while, and I wanted to try my hand at writing a framework. It’s probably a rite of passage to do this, although it’s not really my first.
By releasing it today, I want to see if this is worth investing time in in the future, or if I should focus my energy elsewhere.
The project is called Curveball, and these are it’s differentiating features:
Project goals
I’m a big fan of micro-frameworks. Express was great when it came out, but
it now feels a little dated. Koa was written by the team behind express.
Koa makes a lot more sense in codebases that are Promise-, rather than
callback-oriented, and that’s not the only improvement. The team waited with
releasing a stable version, until the very moment Node.js released a stable
async
/await
support.
I would recommend everyone to check it out. I doubt you’ll want to go back to Express after using Koa for a bit.
Koa has been my framework of choice for a while, but there were a few things I would have liked. I thought it would be an interesting to to write something that checks those boxes.
- Curveball is a very minimal, like Koa.
- It largely follows Koa architecture and API design, with some subtle changes. Middlewares will look very familiar.
- It’s completely written in Typescript.
- It embraces modern HTTP features, it has built-in support for HTTP/2 Push,
and
103 Early Hints
and integrates these in a way that feel like they are a native part of the framework. - It’s easy to do ‘mock’ HTTP requests inside the framework, without having to go through a real HTTP stack.
Points 3-5 are something I missed from other frameworks I’ve looked at, and why I think it might be useful to others.
Some examples:
Hello world
import { Application, Context } from '@curveball/core';
const app = new Application();
app.use((ctx: Context) => {
ctx.response.body = 'Hello world! You used the following HTTP method: ' + ctx.request.method;
});
app.listen(4000);
A router
import { Application } from '@curveball/core';
import router from '@curveball/router';
app.use(router('/contact', ctx => {
ctx.response.body = 'Contact us!';
});
app.listen(4000);
HTTP/2 Push
Whenever you have access to the Context
object, you can also push. Push will
be ignored for HTTP/1 connectinons.
Truncated by Planet PHP, read more at the original (another 8046 bytes)