Build up a basic HTTP server with Bun and Hono

Bun and Hono are two relatively new products to the JavaScript ecosystem centered around being fast and lightweight. Using them you can create blazingly fast apps, beating out the performance of node.js and express.

Starting out

There are multiple different ways to install Bun. The recommended way is to run curl -fsSL https://bun.sh/install | bash. Another option is to install via npm with npm install -g bun. See other install options including Homebrew and Docker here.

After you've installed Bun you can create a Hono app and install dependencies by running the following commands(replace my-app with whatever you want your app to be named)

bun create hono my-app
cd my-app
bun install

You can then start your app by running bun run dev which will run the dev script in your package.json file. You could also just run bun run --hot src/index.ts in your terminal to start the server.

Congrats! You now have a basic server, go to http://localhost:3000 to see Hello Hono!

Configure environment variables

While we technically have a server running, it's not all that useful to use if it's just displaying a Hello World. Next we are going to configure the port through environment variables, add some routes, and return some data.

Using a .env file to control the port

To configure the port our server will run on, we need to download dotenv. Bun makes this super easy, just run bun add dotenv. We are then going to make a .env file at the root of our project, and add the following line to it

PORT=3001

In index.ts we are going to change it to the following

import "dotenv/config"
import { Hono } from "hono"

const app = new Hono()
const port = parseInt(process.env.PORT!)

app.get("/", (c) => c.text("Hello Hono!"))

export default {
  port,
  fetch: app.fetch,
}

Now, if you restart the server, you will see the port as whatever it's been assigned to in the .env file.

While not necessary for this application as the default port 3000 will work fine, it's nice to have this is as a configured option for if you were to run a frontend locally as well

Adding routes

Right now our server has a singular route returning some text to the user. Lets add some more routes. We're just going to make some simple GET requests, but we should understand the different types of data we can return off a GET request.

Hono has a few different options of what can be returned to the user, we are just going to focus on text(), json(), and html(). The rest of the options can be found here.

In our src/ folder, we are going to add a folder called routes and in that a file called users.ts. In the users file add the following:

import { Hono } from "hono"

const users = new Hono()

users.get("/", (c) => c.text("Alice, Bob"))

users.get("/json", (c) => c.json([{ name: "Alice" }, { name: "Bob" }]))

users.get("/html", (c) => c.html(" <ul><li>Alice</li><li>Bob</li></ul> "))

export default users

Then in index.ts add import users from "./routes/users" at the top and app.route("/users", users).

Now we can try out our new routes, accessible at http://localhost:3001/users, http://localhost:3001/users/json, and http://localhost:3001/html.

Finishing up

This is a very basic server with some simple routes to show how to set up a Hono server with a Bun runtime. Be sure to check out both their documentations at https://hono.dev/top and https://bun.sh/docs to learn more about what you can do with them.

Did you find this article valuable?

Support Elias Frieling by becoming a sponsor. Any amount is appreciated!