🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more

bunext-js

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bunext-js

0.11.5
latest
Version published
Weekly downloads
39
-51.25%
Maintainers
1
Weekly downloads
 
Created

🚀 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.

CodeRabbit Pull Request Reviews

📦 Installation & Setup

To install Bunext, use:

bun i bunext-js
bun bunext init
# OR
bun create bunext-app

Then initialize your project:

bun run db:create  # Creates types and missing tables in the database  

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

// src/pages/index.tsx
export default function HomePage() {
  return <h1>Welcome to Bunext!</h1>;
}

📌 Example: Dynamic Page

// src/pages/[id].tsx

export async function getServerSideProps() {
    //server side
  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

// index.tsx

export default async function Page() {
  return (
    <div>
      {await Components()}
      <NotValid />
    </div>
  );
}

// ✅ Valid Server Component
export async function Components() {
  const res = await (await fetch("https://some-api.com/api")).json();
  return <div>{JSON.stringify(res)}</div>;
}

// ❌ Invalid - has props
export function NotValid({ someProps }: { someProps: string }) {
  return <div>{someProps}</div>;
}

🧩 Nested Server Components You can also compose Server Components by nesting them.

// index.tsx

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

// index.tsx
import { revalidate } from "bunext-js/features/router/revalidate.ts";

export default function Page() {
  revalidateEvery("/", 3600); // revalidate this page every hour

  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"; // Enables static page caching

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) // revalidate after 1 hour
  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) {
    // path ex: /page/345 ( /page/[id] )
    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" })
});
// Response will be: "POST"

✅ 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); // Accessible on both client & server
}

📌 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); // Available in client
console.log(process.env.API_KEY); // Server-only

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"], // base paths of dynamic components
  },
};

Usage

"use client";

export function getServerSideProps() {
  // make a Glob of files or get from the Database
  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" }}
    />
  );
}


// /src/dynamic/:template_name

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

Single-Threaded

🔥 Multi-Threaded (12 Threads)

Multi-Threaded

📝 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

FAQs

Package last updated on 04 May 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts