Skip to content

Project Structure

A Bunny project follows a simple, flat structure:

my-app/
src/
index.html # HTML entry point
index.tsx # React entry point
main.css # Global styles
api.ts # API definition
client.ts # Typed fetch client
app/
app.tsx # Root React component
api/
hello.ts # Route handler
bunny.config.ts # Optional Bunny/Vite config
package.json

The HTML shell. Must include a <div id="__bunny"></div> mount point and a script tag pointing to index.tsx:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./main.css" />
<title>My App</title>
<script type="module" src="./index.tsx" async></script>
</head>
<body>
<div id="__bunny"></div>
</body>
</html>

Calls startBunnyClient to mount your React app with StrictMode, Suspense, and service worker registration:

import { startBunnyClient } from "@farbenmeer/bunny/client";
import { App } from "app/app";
startBunnyClient(<App />);

Defines your API routes using TApi’s defineApi. Each route points to a module that exports HTTP method handlers:

import { defineApi } from "@farbenmeer/bunny/server";
export const api = defineApi()
.route("/hello", import("./api/hello"))
.route("/users", import("./api/users"));

Creates a typed fetch client for your API:

import { createFetchClient } from "@farbenmeer/bunny/client";
import type { api } from "./api";
export const client = createFetchClient<typeof api.routes>("/api");

Route handlers export named HTTP methods (GET, POST, etc.) using defineHandler:

import { defineHandler, TResponse } from "@farbenmeer/bunny/server";
export const GET = defineHandler(
{ authorize: () => true },
async () => {
return TResponse.json({ message: "Hello, world!" });
}
);

Optional configuration file. Currently supports extending the Vite config:

import { defineConfig } from "@farbenmeer/bunny";
export default defineConfig({
vite: {
// Custom Vite configuration
},
});

Running bunny build produces:

.bunny/prod/
dist/ # Static files (SPA + assets)
index.html
sw.js # Service worker
assets/ # Hashed JS/CSS chunks
api.cjs # Bundled API server
buildId.txt # Unique build identifier

In standalone mode (bunny build --standalone), a server.cjs is produced that includes all dependencies.