BunSai
Bonsai is a japanese art of growing and shaping miniature trees in containers
Quick start
BunSai is a full-stack agnostic framework for the web, built upon Bun (in fact, it has Nunjucks and Sass as optional dependencies). You can install it:
bun add bunsai
And use it as a handler:
import BunSai from "bunsai";
const { fetch } = BunSai({
loaders,
});
Bun.serve({
fetch,
});
How it works?
Powered by Bun.FileSystemRouter
and some fancy tricks, BunSai takes an approach where you declare the files you want to become "routes"
loaders: {
".ext": loader
}
And all files with that file extension will be served as routes.
Example
Lets say you have the following files:
pages
├── index.njk
├── settings.tsx
├── blog
│ ├── [slug].svelte
│ └── index.ts
└── [[...catchall]].vue
You can configure BonSai to serve those files:
BunSai({
loaders: {
".njk": nunjucksLoader,
".ts": apiLoader,
".tsx": reactLoader,
".svelte": svelteLoader,
".vue": vueLoader,
},
});
Check the Loader
interface
You can also specify file extensions that will be served staticly (return new Response(Bun.file(filePath))
), like so:
staticFiles: [".jpg", ".css", ".aac"];
There is a caveat around staticFiles
: as all files are served using the FileSystemRouter, pages/pic.jpeg
will be served as /pic
Built-in loaders
BunSai is 100% flexible, but this does not mean that it cannot be opinionated. BunSai ships with built-in (optional) loaders:
Since v0.1.0
Nunjucks is a rich powerful templating language with block inheritance, autoescaping, macros, asynchronous control, and more. Heavily inspired by jinja2.
bun add nunjucks @types/nunjucks
import getNunjucksLoader from "bunsai/loaders/nunjucks";
const { loader, env } =
getNunjucksLoader();
BunSai({
loaders: {
".njk": loader,
},
});
<body>
{# 'server', 'route' and 'request' #}
<p>
All those objects are passed to the Nunjucks renderer to be available
globally
</p>
</body>
Since v0.1.0
Sass is the most mature, stable, and powerful professional grade CSS extension language in the world.
bun add sass @types/sass
import getSassLoader from "bunsai/loaders/sass";
const loader = getSassLoader();
BunSai({
loaders: {
".scss": loader,
},
});
Module
Since v0.1.0
BonSai offers a simple module implementation to handle .ts
, .tsx
, .js
and .node
files:
import { ModuleLoader } from "bunsai/loaders";
BunSai({
loaders: {
".ts": ModuleLoader,
},
});
A server module is a regular TS/TSX/JS/NAPI (anything that Bun can import) file that have the following structure:
export const headers = {
};
export function handler(data: ModuleData) {
}
Recommended
Since v0.1.0
If you liked BunSai's opinion and want to enjoy all this beauty, you can use the recommended configuration:
import getRecommended from "bunsai/recommended";
const { loaders, staticFiles, nunjucksEnv } =
getRecommended();
BunSai({
loaders,
staticFiles,
});
Check the Recommended
interface.
Middlewares
Since v0.1.0
You can use middlewares to override or customize the response given by the loader.
const { addMiddleware, removeMiddleware } = BunSai();
addMiddleware(
"name it so you can remove it later",
(response, request, server) => {
return new Response();
return response;
}
)
.addMiddleware();
removeMiddleware(
"name it so you can remove it later"
)
.removeMiddleware();