Since 2014 I've been building several REST API backends with Node.js, mostly with Express.js. Over the years, I've learned a lot about how to structure a project and select the right tools to build a solid foundation for a REST API backend. More recently, I've been exploring Bun and Hono, which are modern alternatives to Node.js and Express.js, respectively.
Even though one of Bun's best-selling points is its performance, the main reason it caught my attention is its tooling and its TypeScript support out of the box. I've been working for several startups and I give a lot of importance to TCO and I believe that Bun can be part of the solution to reduce the TCO of a project.
Consequently, I decided to create a boilerplate that combines Bun and Hono, as well as other tools that I find useful for building a REST API backend. I try to keep the complexity as low as possible without sacrificing important aspects like testing, documentation, security and maintainability.
- Why Bun and Hono?
- Features
- Step-by-Step Installation Guide
- Start the API server
- Conclusion
- License
- Contributing
Bun is a modern JavaScript runtime that is fast and efficient. It is designed to be a drop-in replacement for Node.js, but with a focus on performance and developer experience.
Hono is a fast and lightweight web framework that is compatible with Bun.
This boilerplate should provide a solid foundation for building a REST API backend with the following features:
- Bun
- Hono
- TypeScript
- Biome (Linting and formatting)
- OpenAPI/Swagger
- Prisma (ORM)
- Better-Auth (Authentication)
- hey-api (Client SDK generation)
- MCP (Model-Context-Protocol) server for LLMs
Both hey-api and MCP server leverage the OpenAPI specs document to generate a client SDK and a server that can be used to interact with LLMs.
Before going further, keep a tab open to the GitHub repository of this boilerplate. I won't copy the code of every file here, but for each step I will tell you where to look in the repository to find the code you need to copy or adapt.
To run this project, you will first need to install the Bun runtime. Bun also comes with a package manager and some utilities that I believe will simplify the project by having fewer packages to install and maintain.
Step-by-step guide to install Bun, Hono and other dependencies:
1. Install Bun
curl -fsSL https://bun.sh/install | bash
To validate the installation, run:
bun --version
To upgrade, run:
bun upgrade
Create a new directory for your project, navigate into it and run the following command:
bun init
This will create the following files:
- index.ts
- tsconfig.json
- package.json
3. Install Hono
Hono is the framework that will be used to build the API. To install it, run the following command:
bun add hono
We will use environment variables to configure the API. Create a .env
file with
the following command:
touch .env
And add the following content:
API_PORT=3000
DATABASE_DIR=./data
BETTER_AUTH_SECRET=better-auth-secret
TRUSTED_ORIGINS=http://localhost:3000
5. Install Zod
Zod is a TypeScript-first schema declaration and validation library. It will be used to validate the data sent to the API.
bun add zod
The configuration file will be used to load the environment variables.
mkdir src
touch ./src/config.ts
Copy the content of the config.ts
file from this boilerplate repository to
your project. This file will load the environment variables from the .env
file
and provide a type-safe way to access them throughout the application.
From the boilerplate repository, open the package.json
file and copy the scripts
and prisma
sections to your project's package.json
file.
Swagger-JSDoc is a tool that allows you to generate OpenAPI specs document from comments in your code. It is useful for many reasons :
- It allows you to document your API in a standard way.
- It allows other developers to understand your API without having to read the code.
- It allows generating a client SDK for your API. (React, Angular, Vue, etc.)
- It allows generating an MCP (Model-Context-Protocol)
bun add -d swagger-jsdoc @types/swagger-jsdoc
bun add @hono/swagger-ui
Create a scripts
folder in the root of your project:
mkdir scripts
Then copy the file generate-openapi.ts
from this boilerplate repository to
your project. This script will generate the OpenAPI specs document from the comments
in the code. It uses Swagger-JSDoc to parse the comments and generate the OpenAPI
specs document.
To generate the OpenAPI specs document, you can run the following command:
bun run openapi
This will generate the OpenAPI specs document in the ./docs/openapi.json
file.
9. Install Biome (linting and formatting tool)
Biome is a modern linting and formatting tool that replaces ESLint and Prettier. It's easier to use and configure than ESLint and Prettier, and it's also a lot faster. If you currently use ESLint and Prettier, you can replace them with Biome.
bun add -D -E @biomejs/biome
To generate the configuration file, run:
bunx --bun biome init
This will create a biome.json
file in the root of your project.
10. Install Pino
Pino is a fast and lightweight logging library.
Winston is also a good option, it has a better documentation and broader support, but it's also a bit heavier
bun add pino pino-pretty
bun add -d @types/pino
Create a src/services/
directory:
mkdir -p src/services
Copy the file ./src/services/logger.ts
from this boilerplate
repository to your project.
11. Install Prisma
Prisma is a modern ORM that allows you to interact with your database in a type-safe way. It offers a great migration system, a modern query API and good documentation.
bun add -d typescript @types/node
bun add prisma
PGLite is a lightweight, file-based database. It's suitable for demo projects
like this one, but not for production use. If you're planning to build a
production-ready application, you should consider using a docker service instead.
A docker service is more similar to what you will use in production. You can
refer to the file docker-compose.yml
in this repository for an example of how
to set up a Postgres database with Docker.
skip this step if you plan to use a docker service instead of PGLite.
Run this command to create the data directory:
mkdir data
Then install the PGLite Prisma adapter and the PGLite database:
bun add pglite-prisma-adapter
bun add @electric-sql/pglite
Copy the file prisma.config.ts
from this boilerplate repository to your
project.
Note: PGLite is used as an example for this boilerplate. You can replace it with any other database adapter that is compatible with Prisma.
If you prefer to use a Docker service instead of PGLite, you can use the
docker-compose.yml
file in this repository. To start the Docker service, run:
docker compose up -d
Create a new directory src/prisma/
:
mkdir -p src/prisma
Then copy the file src/prisma/schema.prisma
from this boilerplate
repository to your project.
Run the following command to generate the Prisma client:
bun --env-file=.env prisma generate --schema=./src/prisma/schema.prisma
Run the following command to create the database and tables:
bun --env-file=.env prisma db push --schema=./src/prisma/schema.prisma
Finally, copy the file src/services/database.ts
from this boilerplate
repository to your project.
14. Install Better-Auth
Better-Auth is a modern authentication library that provides a simple and secure way to handle user authentication in your application. There are several authentication strategies available, such as email/password, social logins and more. It can do a lot, therefore, I recommend you to check the documentation to understand how it works and how to configure it.
bun add better-auth
mkdir -p src/lib
mkdir -p src/services/error
Copy all the files from src/services/error/
from this boilerplate repository
to your project.
Then copy the file src/lib/auth.ts
from this boilerplate repository to
your project.
Create a new folder src/api/
:
mkdir -p src/api
Then copy all the files from the api
folder from the boilerplate repository to
your project.
If you open src/post.ts
you will see that it is a simple Hono route that
handles the /post
endpoint.
You will also see that it contains Swagger comments that will be used to generate
the OpenAPI specs document.
Also copy src/index.ts
and src/server.ts
files from this boilerplate
repository to your project.
To generate the OpenAPI specs document, you can run the following command:
bun run openapi
It will generate the OpenAPI specs document in the ./docs/openapi.json
file.
This document can be used to generate a client SDK or to generate an MCP server for LLMs.
To ensure the quality of your code, it's important to write tests.
First, create a tests folder at the root of your project:
mkdir tests
Now copy the content of the tests
folder from this boilerplate repository.
Then add faker package to generate fake data for testing:
bun add -d @faker-js/faker
You can run the tests with the following command:
bun test
Or if you want to run the tests with coverage, you can run:
bun test --coverage
If you want to run tests only for a specific section, like the API tests, you can run:
bun test ./tests/api
17. Install Hey-API
Hey-API is a tool that can generate a client SDK from your OpenAPI specs document.
bun add -d @hey-api/client-fetch
bun add @hey-api/openapi-ts
Copy the file openapi-ts.config.ts
from this boilerplate repository to your project.
Then execute the following command to generate the client SDK:
bun run openapi:client:hey-api
This will generate the client SDK in the ./dist/client/hey-api
folder.
If you want to generate the client SDK for Next.js, refer to this documentation.
I won't go into the details about how to use the client SDK. Check Hey-API's website for the documentation and examples.
Only do this step if you want to run the MCP server for LLMs.
This MCP server is a simple server that can be used to interact with LLMs (Large Language Models). It is based on the OpenAPI specs document generated by Swagger-JSDoc.
Copy the file start-mcp-server.sh
from this boilerplate repository to your
project.
You don't need to install anything, run the following command:
./start-mcp-server.sh
This will start the MCP server on port 4000.
I won't go into the details about how to use the MCP server; this is a subject for another article.
To start the API server, run the following command:
bun run dev
This will start the server on the port defined in the .env
file (default is 3000).
You can then access the API at http://localhost:3000
.
You can also access the Swagger UI at http://localhost:3000/docs
to see the
API documentation and test the endpoints.
I will continue to improve this boilerplate over time. I'm planning to use it as a base for my future projects. Feel free to use it as you wish, and if you have any suggestions or improvements, please open an issue or a pull request on the GitHub repository.
This project is licensed under the MIT License
See the LICENSE file for details.
Contributions are welcome! Please read the CONTRIBUTING.md file for details on how to contribute to this project.