DEV Community

Cover image for Frameworks of BunJS: ElysiaJS and Hono
Vo Van Thanh
Vo Van Thanh

Posted on • Edited on

Frameworks of BunJS: ElysiaJS and Hono

BunJS is hot, but what about frameworks? This post dives into ElysiaJS and Hono, exploring how they can take your BunJS development to the next level.


What's BunJS

BunJS is a fast and versatile JavaScript runtime designed to be a drop-in replacement for Node.js. Similar to Node.js and Deno, it allows you to execute JavaScript code outside of a web browser. However, BunJS stands out for its focus on performance.

BunJS was built from scratch to focus on four key points:

  • Speed: BunJS utilizes the latest JavaScriptCore engine and is written in Zig, a language known for its efficiency. This combination contributes to BunJS's exceptional performance compared to Node.js and Deno used V8 engine.

  • All-in-one Toolkit: BunJS goes beyond just a runtime. It provides a built-in bundler, test runner, and package manager, streamlining the development workflow.

  • Node.js Compatibility: BunJS natively implements many Node.js APIs and Web APIs, making it easier to migrate existing Node.js projects.

  • TypeScript Support: BunJS offers seamless integration with TypeScript, allowing developers to write robust and maintainable code.

According to the official site

The goal of Bun is to run most of the world's server-side JavaScript and provide tools to improve performance, reduce complexity, and multiply developer productivity.

In summary, BunJS is a promising newcomer in the JavaScript runtime landscape, offering exceptional speed, a comprehensive toolkit, and compatibility with existing Node.js code. It's worth considering for projects that demand high performance and a smooth development experience.

Compare speed of NodeJS and BunJS

I found the performance benchmarking of 5 runtime: Bun, NodeJS, Go, C# and Python. You can read full post here

Compare speed of NodeJS, Bun, C# and Python

The result of the benchmarking according to requests per second shows that: in the beta version, Bun is almost twice as fast as NodeJS (with Fastify framework).

Next, we will explore the prominent frameworks currently available for BunJS.


ElysiaJS

Elysia is a HTTP API framework written on Bun with developer experience being the main motivation of the framework. Essentially, it’s a faster Express.js replacement.
You can create new Elysia project using command:



bun create elysia <name of the project>


Enter fullscreen mode Exit fullscreen mode

A basic Elysia endpoint could look like this:

Elysia

Routing

We can define a route by calling a method named after HTTP verbs, passing a path and a function to execute when matched.

Elysia routing

Elysia is using method chaining to synchronize type safety for later use. So, always use method chaining in Elysia.

Elysia method chaning

Addition, Elysia accept custom HTTP Methods with Elysia.route

Elysia custom method

Path

The path in Elysia can be grouped into 3 types:

  • Static paths - static string to locate the resource
  • Dynamic paths - segment can be any value
  • Wildcards - path until a specific point can be anything

The priorities are as follows: static > dynamic > wildcards

Elysia path

Handler & Context

After a resource is located, a function that respond is refers as handler

Elysia handler

Context is a request information passed to a route handler. Context is unique for each request, and is not shared except for store which is a global mutable state. Elysia context includes path, body, query, params, headers, request, redirect, store, cookie, set and error. You can see more information about it in the official documents of Elysia.

Life cycle event

Elysia's Life Cycle event can be illustrated as the following

Elysia life cycle

Plugin

The plugin pattern is a powerful approach to manage this complexity. It promotes modularity, which means breaking down functionality into smaller, reusable pieces.

We can use the plugin by passing an instance to Elysia.use.

Elysia plugin

The plugin will inherit all properties of the plugin instance, including state, decorate, derive, route, lifecycle....

Elysia will also handle the type inference automatically as well, so you can imagine as if you call all of the other instances on the main one.

You can find an officially maintained plugin at Elysia's plugins

I have created a boilerplate for Elysia. You can find it here. It's based on three repositories, thanks to its authors.


Hono

Hono is a lightweight, simple, and fast web framework for Cloudflare Workers, Deno, Bun, and other applications. It is a modern web application that is both fast and flexible. It offers inbuilt support for TypeScript, and easy development in a local environment.

Start Hono project with command



bun create hono <name of the project>
cd <name of the project>
bun install


Enter fullscreen mode Exit fullscreen mode

The basic project same as

Hono basic

Routing

Hono provides two main routing mechanisms:

  • TrieRouter: This is the default and recommended router. It utilizes a trie data structure for efficient pattern matching, leading to faster performance, especially for applications with a large number of routes.
  • RegExpRouter: it is the fastest router in the JavaScript world. They are using linear loops. Therefore, regular expression matching will be performed for all routes and the performance will be degraded as you have more routes.

Furthermore, Hono also has three other types of routers: SmartRouter, LinearRouter, and PatternRouter.

Hono routing

Context

To handle Request and Response, you can use Context object.
It includes:

  • req
  • body()
  • text()
  • json()
  • html()
  • notFound()
  • redirect()
  • res
  • etc…

You can read more information about it in the official document of Hono.

Exception

When a fatal error occurs, such as authentication failure, an HTTPException must be thrown.

This example throws an HTTPException from the middleware.

Hono throw exception

You can handle the thrown HTTPException with app.onError.

Hono handle exception

Middleware

Middleware works after/before Handler. We can get Request before dispatching or manipulate Response after dispatching.

Definition of Middleware:

  • Handler - should return Response object. Only one handler will be called.
  • Middleware - should return nothing, will be proceeded to next middleware with await next()

The user can register middleware using app.use or using app.HTTP_METHOD as well as the handlers. For this feature, it's easy to specify the path and the method.

Hono middleware

Execution order: The order in which Middleware is executed is determined by the order in which it is registered. The process before the next of the first registered Middleware is executed first, and the process after the next is executed last. See below.

Hono middleware execution order

Result is the following

Hono middleware execution order result

Hono has some built-in middlewares such as logger or basicAuth. You can write your own middleware directly inside app.use(). Besides, Hono also has some third-party middlewares of GraphQL Server, Sentry, Firebase Auth… (You can see more here) So with them, we may make a more complex application.

Client components

In Hono, you can write HTML with JSX syntax with hono/jsx.

On the server side, it supports some features of React such as Fragment, child props, optimizing components using memo, context, etc.

Hono client components

hono/jsx supports not only server side but also client side. It’s called Client Components or hono/jsx/dom. It has Hooks that are compatible or partially compatible with React: useState, useEffect, useRef, useCallback...

Here is an example of a simple counter, the same code works as in React.

Hono with react hook

Boilerplate

You can refer to my Hono API boilerplate here.


Speed test ElysiaJS, Hono, Express, Fastify and NestJS (Express)

Unit: req/s

Framework Runtime Average Get(/) Params, query & header Post JSON
ElysiaJS Bun 275,063.507 326,868.9 261,729.3 236,592.32
Hono Bun 257,532.08 320,757.07 233,769.22 218,069.95
Fastify Node 64,145.95 74,631.46 66,235.48 51,570.91
ExpressJS Node 16,301.823 17,974.35 17,090.62 13,840.5
NestJS (Express) Node 14,978.863 16,926.01 15,507.62 12,502.96

Reference


Conclusion

BunJS has emerged as a promising player in the JavaScript runtime landscape. Its focus on speed, efficiency, and a streamlined development experience makes it an attractive option for modern web development. In this post, we explored two exciting BunJS frameworks: ElysiaJS and Hono.

ElysiaJS provides a comprehensive solution for building full-fledged web applications, offering features like routing, templating, and form handling. If you're looking for a rapid development framework to jumpstart your BunJS project, ElysiaJS is a strong contender.

Hono, on the other hand, excels in lightweight routing and server-side functionality. Its flexibility and focus on performance make it ideal for building APIs and microservices. Whether you're building a complex web application or a performant API, BunJS, with frameworks like ElysiaJS and Hono, offers a powerful and versatile ecosystem for your next project.

Consider diving deeper into these frameworks and exploring the possibilities BunJS unlocks. With its focus on speed and a growing ecosystem, BunJS is definitely worth keeping an eye on for the future of JavaScript development.

Top comments (0)