🚀 Bunext Documentation
Bunext is a Next.js-inspired framework designed for the Bun runtime, providing high-performance SSR, CSR, static site generation, and multi-threaded HTTP workers. It is optimized for modern development workflows with built-in SQLite support, session management, and server actions.
🔧 Compatibility
- Bun Version:
1.1.0 - 1.2.10
- Supported OS: Linux, WSL (Windows support in progress)
- Note: Bun is evolving rapidly. New versions may cause compatibility issues. Watch for breaking changes before version
1.0.0
.

📦 Installation & Setup
To install Bunext, use:
bun i bunext-js
bun bunext init
bun create bunext-app
Then initialize your project:
bun run db:create
To start the development server:
bun run dev
For production builds:
bun run build
bun run start
📌 Features
✅ Multi-threaded HTTP workers (Linux only)
✅ SSR (Server-Side Rendering) & CSR (Client-Side Rendering)
✅ Server & client environment variables (process.env
)
✅ React 18 & 19 support
✅ Static assets & SVG support
✅ Server components ("use server" & "use client")
✅ Revalidation & caching
✅ Session management (public & private)
✅ SQLite database management
✅ Hot reload in development mode
✅ Production-ready mode (Beta)
📁 Routing System
Bunext follows Next.js-style file-based routing.
src/pages/index.tsx
→ Home Page
src/pages/[id].tsx
→ Dynamic route (/page/123
)
src/pages/layout.tsx
→ Layout for subroutes
src/pages/[segment]/[id].tsx
→ Dynamic route and segments (/user/10
)
📌 Example: Basic Page
export default function HomePage() {
return <h1>Welcome to Bunext!</h1>;
}
📌 Example: Dynamic Page
export async function getServerSideProps() {
return { foo: "bar" };
}
export default function DynamicPage({
params,
props
} : {
params: { id: string },
props: { foo: string }
}) {
return <h1>Page ID: {params.id} {props.foo}</h1>;
}
⚙️ Server Components
Bunext supports Server Components, which run only at build time and are re-executed only when revalidate()
is triggered.
✅ How It Works
- Any exported function without the
"use client"
directive is treated as a Server Component.
- Must have no props.
- Must be exported (not inline) and can be
async
.
revalidate()
will re-run all Server Components used on the page.
- Must not have hooks
📦 Example
export default async function Page() {
return (
<div>
{await Components()}
<NotValid />
</div>
);
}
export async function Components() {
const res = await (await fetch("https://some-api.com/api")).json();
return <div>{JSON.stringify(res)}</div>;
}
export function NotValid({ someProps }: { someProps: string }) {
return <div>{someProps}</div>;
}
🧩 Nested Server Components
You can also compose Server Components by nesting them.
export default async function Page() {
return (
<main>
{await Parent()}
</main>
);
}
export async function Parent() {
return (
<section>
<h2>Parent Component</h2>
{await Child()}
</section>
);
}
export async function Child() {
const data = await (await fetch("https://some-api.com/stats")).json();
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
🔁 Revalidating Components
Bunext allows scheduled and manual revalidation.
⏱ Scheduled Revalidation
import { revalidate } from "bunext-js/features/router/revalidate.ts";
export default function Page() {
revalidateEvery("/", 3600);
return (
<div>
<button onClick={() => ServerRevalidate(["/"])}>Revalidate / path</button>
</div>
);
}
🔄 Manual Revalidation
import { revalidate } from "bunext-js/features/router/revalidate.ts";
export async function ServerRevalidate(...paths: string[]) {
revalidate(...paths);
}
📝 Rules to apply
- ✅ Keep Server Components pure – no side effects.
- ✅ Fetch data server-side with async/await.
- ❌ Avoid using props.
- ❌ Don't mutate state or use hooks like useState or useEffect.
🚀 Static Pages with "use static"
You can cache pages for better performance using "use static"
.
"use static";
export async function getServerSideProps() {
return { data: await fetch("https://api.example.com").then((res) => res.json()) };
}
export default function Page({ props }: { props: { data: any } }) {
return <div>Data: {JSON.stringify(props.data)}</div>;
}
Revalidate static pages after a set time:
"use static";
import { revalidateStatic } from "bunext-js/router";
export async function getServerSideProps({request}: {request: Request}) {
revalidateStatic(request, 3600)
return { data: await fetch("https://api.example.com").then((res) => res.json()) };
}
export default function Page({ props }: { props: { data: any } }) {
return <div>Data: {JSON.stringify(props.data)}</div>;
}
Revalidate static pages in an Action:
import { revalidateStatic } from "bunext-js/router";
export async function ServerRevalidateStaticPage(path: string) {
revalidateStatic(path);
}
🔗 Navigation
Bunext provides two ways to navigate between pages:
import { navigate, Link } from "bunext-js/internal/router";
function NextPage() {
return (
<>
<button onClick={() => navigate("/new/location")}>Go to New Page</button>
<Link href="/new/location">
<button>Next Page</button>
</Link>
</>
);
}
API Endpoint
Define HTTP method handlers in files under src/pages
to automatically create API endpoints.
📁 Example: src/pages/api/v1/index.ts
import type { BunextRequest } from "bunext-js/internal/server/bunextRequest.ts";
export function POST(request: BunextRequest) {
request.response = new Response("POST");
return request;
}
export function GET(request: BunextRequest) {
request.response = new Response("GET");
return request;
}
export function PUT(request: BunextRequest) {
request.response = new Response("PUT");
return request;
}
export function DELETE(request: BunextRequest) {
request.response = new Response("DELETE");
return request;
}
🌐 Making Requests from the Client
You can send requests to this API using the native fetch
function:
await fetch("https://my.site.com/api/v1", {
method: "POST",
body: JSON.stringify({ foo: "bar" })
});
✅ Features
- Fully typed request with
BunextRequest
- Auto-routing based on file path
- Clean, REST-like interface using standard HTTP verbs
🛠️ Sessions
Bunext supports server-side and client-side session management.
📌 Set Session Data (Server-Side)
import { GetSession } from "bunext-js/features/session";
export async function ServerSetSession({ username }) {
const session = GetSession(arguments);
session.setData({ username }, true);
}
📌 Access Session Data (Client-Side)
import { useSession } from "bunext-js/features/session";
export default function UserStatus() {
const session = useSession();
return <span>{session.getData()?.username || "Not logged in"}</span>;
}
📌 Delete Session
export async function ServerDeleteSession() {
GetSession(arguments).delete();
}
🔄 Server Actions
Bunext supports Server Actions for secure API calls.
- function name must start with the keyword Server
- File & File[] must be at the first level of params.
- formData is supported without other params
- params must be serializable
export async function ServerUploadFile(file: File, data: string) {
await Bun.write(`uploads/${file.name}`, file);
console.log(data);
return { success: true, message: "File uploaded!" };
}
Call this function from a client component:
<form action={async (e) => await ServerUploadFile(e.get("file") as File, "picutre") }>
<input type="file" name="file" />
<button type="submit">Upload</button>
</form>
🗃️ Database Integration (SQLite)
📌 Define Schema
import { DBSchema } from "bunext-js/database/schema";
const schema: DBSchema = [
{
name: "Users",
columns: [
{ name: "id", type: "number", unique: true, primary: true, autoIncrement: true },
{ name: "username", type: "string", unique: true },
{ name: "role", type: "string", union: ["admin", "user"] },
],
},
];
export default schema;
Run the migration:
bun run db:create
📌 Query Database
import { Database } from "bunext-js/database";
const db = Database();
const users = db.Users.select({ where: { role: "admin" } });
🔧 Environment Variables
PUBLIC_API_KEY="123456"
→ Accessible in client & server
API_KEY="private-key"
→ Only accessible in server
Use in code:
console.log(process.env.PUBLIC_API_KEY);
console.log(process.env.API_KEY);
Dynamic import module
Experimental
Import module from directory you don't want to explicitly add to your code.
Exemple: templates, you does not want to import every of them,
Config
In config/server.ts add
const Config: ServerConfig = {
HTTPServer: {
port: 3010,
},
Dev: {
hotServerPort: 3005,
},
session: {
type: "database:hard",
},
router: {
dynamicPaths: ["src/dynamic"],
},
};
Usage
"use client";
export function getServerSideProps() {
return {
template_name: "component_1"
}
}
export default async function DynamicImport({props}:{props: {template_name: string}}) {
return (
<Bunext.plugins.onRequest.components.DynamicComponent
pathName={`/src/dynamic/${props.template_name}`}
elementName="default"
props={{ title: "foo-bar" }}
/>
);
}
export default function DynamicComponent({ title }: { title: string }) {
return (
<div>
<h1>{title}</h1>
<h1>Dynamic Component</h1>
<p>This component is loaded dynamically.</p>
</div>
);
}
📊 Benchmarks
Bunext is optimized for speed and efficiency.
🖥️ Single-Threaded Performance

🔥 Multi-Threaded (12 Threads)

📝 Contributing
Contributions are welcome! Submit issues and PRs on GitHub.
📜 License
Bunext is open-source under the MIT License.
This version improves readability, adds more examples, and organizes the content better. Let me know if you want any changes! 🚀
📌 Changelog
🔹 0.8.x Versions
📢 0.8.18
- Fix Database schema union type making number as string
- Database schema in JSON objects in arrays are considered unions
- Database schema union in JSON column type can be string or/and number
- Session strategy has changed and session timeout is automatically updated
- Database
LIKE
operator for SELECT
operation
- Direct access to the database for making custom requests (must be secured manually)
- Added tests for database
- Automatic session timeout update UI
📢 0.8.19
- Enforce tests
- Remove unused files in build after each build
- Router:
[segmentName].tsx
is now supported
- Previously: Only
[id].tsx
was supported
- Now: Any
[segmentName]
is supported (e.g., [foo].tsx
, [bar].tsx
)
- Update README
- SVG loader now uses SVGR (stable)
📢 0.8.20
- Caching SVG for a more fluid development experience
📢 0.8.21
- Update SVG caching strategy for cold start improvement and cache validation based on file hash
- New caching system for SSR Elements
- Fix a long-time bug where builds crashed when Server Components list was too large
- Improve build speed
- Added Single-Threaded & Multi-Threaded Benchmarks in README
📢 0.8.22
- Fix missing regex for
[segmentName]
- Fix Concurrent Read & Write of the Database
- Add utility functions to generate fake data
- Cache is cleared in the browser between dev versions
📢 0.8.23
- Fix crash in dev mode introduced in Bun version
1.1.43
📢 0.8.24
- Fix crash with the dev client WebSocket
- Fix Layout not working if inside a dynamic segment directory
📢 0.8.26
- Fix Layout not rendering when inside a dynamic segment directory and the request does not use the client-side router (direct access)
- Parallelized layout imports to reduce cold start & dev mode loading times
🔹 0.9.x Versions
📢 0.9.0
- Removed unused code → Performance upgrade
- CSS is now automatically imported into the
<head>
component
📢 0.9.2
- Fix Session not updating when modified outside an event
- Fix all TypeScript errors
- Fix false errors when compiling in dev mode with SSR component caching
- Dynamically update
<Head>
with useHead
- Added explicit exports → Projects may need to update imports
Head
data can be dynamic. Request object is parsed as props to the page element (default export of index.tsx
)
- Direct access to the
request
object from any component running on the server
- Dev builds are now more verbose and cleaner
📢 0.9.3
- Fix CSS auto-imports for dynamic segments
- Auto-imported CSS is rendered at first load, suppressing flickering on direct access or first load
📢 0.9.4
- Fix CSS not imported on direct access for CSS inside a
Page
element (worked for layouts)
- SVG and CSS files are now typed correctly
- NEW FEATURE:
"use static"
directive
- Caches pages for specific paths (even with dynamic segments)
- Example:
/a/path/[id]
caches /a/path/1
and /a/path/2
- Can be revalidated
- Router code cleaned
- Stronger fetch caching
📢 0.9.6
"use static"
performance upgrade
- Routes exporting
default
verified as SSR elements are now cached properly
- 80%+ performance boost (significantly reduces server load)
- New 0.8.x vs 0.9.5 benchmark
- Fix "use static" not caching for dynamic segments
- Dynamic pages now have a 100% performance upgrade (no joke)
"use static"
benchmark added
📢 0.9.7
- Fix
getServerSideProps
breaking when returning undefined
- Fix update issue where it overwrites existing React & React-DOM
- Default React & React-DOM versions updated to
19.0.0
📢 0.9.8
- Override session expiration using
session.setExpiration()
- Fix params not reaching
getServerSideProps
📢 0.9.10
- Added more tests to prevent previous errors from recurring
- Fix
getServerSideProps
breaking request when undefined
on route change/refresh in dev mode
- Faster development mode reducing build time exponentially
📢 0.9.16
- Fix Dev mode Reloading page on every file modification.
- adding code rabbit review
- Fix page wasn't reloading after a file change if it wasn't the index or layout
📢 0.9.17
- Redirection is now possible in a ServerAction
- Fix regression API Endpoint cannot be reach introduced in 0.9.10
📢 0.9.18
- New Global object Bunext for every Bunext features
- Dynamic Module loading feature. ( Load Module without knowing the name at first ). Exemple will follow + tooling, components
- HTTPServer options can be set from the config file config/server.ts
🔹0.10.x
📢 0.10.1
- Update Global Bunext object
- Refactor many components
- dynamic components method change ( only needs to add the server config )
- cleanup code for readability and maintainability
📢 0.10.3
- Fix regression introduced in 0.9.18 where the onRequest file was not imported correctly
- much more verbose CLI outputs and automatic benchmarking
📢 0.10.4
- Add a plugin system for altering the life cycle of the build, request and routing process
- Bunext global object updated
🔹0.11.x
📢 0.11.1
- Build process worker thread (improve build time by removing the overhead of triggering a new process each time)
📢 0.11.3
- Upgraded Version of Link element now is a Anchor element and ctrl+click will open in a new tab.
- Link and navigate has typeSafe route path
- BunextPlugin has onFileSystemChange new key (doc will follow)
- update Doc for missing section API endpoints and server components
- Head component for setting dynamic head data
📢 0.11.4
- Fix minor init type
- Upgrade typed Route paths
- other minor improvement
📢 0.11.5
- Fix useSession hook not updating properly after a ServerAction modify the session.
- fix typo in CLI
- remove unnecessary getSession props
- fix dev mode serverAction and serverComponents not transpiling correctly