Welcome to the Bun-Node-Killer project. This project aims to demonstrate how to use Bun as a static page server, create a server for APIs, and use React 19 with Server Components.
Let's go through the steps.
First, make sure you have Bun installed. You can check the version with:
bun --version
For this project, we are using version 1.2.3 (canary for now).
bun upgrade --canary
To serve a static file with Bun, simply run:
bun index.html
If you want to use TailwindCSS in your HTML routes, follow these steps:
- Initialize your project with Bun:
bun init
name: whatever you want
entry point: src/tsx
- Add the necessary plugins:
bun add -D bun-plugin-tailwind
- Create a
bunfig.toml
file and add the configuration:
[serve.static]
plugins = ["bun-plugin-tailwind"]
To add React and other libraries, run:
bun add react react-dom @types/react-dom
Then, add an index.tsx
and a root
element in your index.html
:
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
Bootstrap React in index.tsx
:
import { createRoot } from "react-dom/client";
function App() {
return (
<div>
<h1>Gentleman Programming running from React</h1>
</div>
);
}
createRoot(document.getElementById("root")!).render(<App />);
To create a server, add a server.ts
file:
import index from "./index.html";
interface BunServe {
static: Record<string, string>;
}
const server = Bun.serve<BunServe>({
static: {
"/": index,
},
// we need to add this one for type safety, we will implement it later
async fetch(_req) {
return new Response("hi ! I'm Gentleman");
},
});
console.log(`Listening on http://${server.hostname}:${server.port}`);
Run it with:
bun server.ts
Let's modify the previous async fetch to add an API:
import index from "./index.html";
interface BunServe {
static: Record<string, string>;
}
export interface Character {
id: number;
name: string;
species: string;
image: string;
}
export interface ApiResponse {
results: Character[];
}
const server = Bun.serve<BunServe>({
static: {
"/": index,
},
async fetch(req) {
const path = new URL(req.url).pathname;
if (path === "/api/characters") {
const characters: Character[] = [
{ id: 1, name: "Harry Potter", species: "Human", image: "harry.jpg" },
{
id: 2,
name: "Hermione Granger",
species: "Human",
image: "hermione.jpg",
},
{ id: 3, name: "Ron Weasley", species: "Human", image: "ron.jpg" },
{
id: 4,
name: "Albus Dumbledore",
species: "Human",
image: "dumbledore.jpg",
},
{ id: 5, name: "Severus Snape", species: "Human", image: "snape.jpg" },
];
const result: ApiResponse = {
results: characters,
};
return new Response(JSON.stringify(result), {
headers: { "Content-Type": "application/json" },
});
}
return new Response("Not Found", { status: 404 });
},
});
console.log(`Listening on http://${server.hostname}:${server.port}`);
And that's it, folks. With this, you have a solid foundation to start working with Bun, React, and APIs.
Any questions, you know where to find me. Let's get coding!