
Security News
pnpm 10.12 Introduces Global Virtual Store and Expanded Version Catalogs
pnpm 10.12.1 introduces a global virtual store for faster installs and new options for managing dependencies with version catalogs.
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.
1.1.0 - 1.2.10
1.0.0
.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
✅ 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)
Bunext follows Next.js-style file-based routing.
src/pages/index.tsx
→ Home Pagesrc/pages/[id].tsx
→ Dynamic route (/page/123
)src/pages/layout.tsx
→ Layout for subroutessrc/pages/[segment]/[id].tsx
→ Dynamic route and segments (/user/10
)// src/pages/index.tsx
export default function HomePage() {
return <h1>Welcome to Bunext!</h1>;
}
// 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>;
}
Bunext supports Server Components, which run only at build time and are re-executed only when revalidate()
is triggered.
"use client"
directive is treated as a Server Component.async
.revalidate()
will re-run all Server Components used on the page.// 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
"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);
}
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>
</>
);
}
Define HTTP method handlers in files under src/pages
to automatically create API endpoints.
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;
}
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"
BunextRequest
Bunext supports server-side and client-side session management.
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
}
import { useSession } from "bunext-js/features/session";
export default function UserStatus() {
const session = useSession();
return <span>{session.getData()?.username || "Not logged in"}</span>;
}
export async function ServerDeleteSession() {
GetSession(arguments).delete();
}
Bunext supports Server Actions for secure API calls.
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>
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
import { Database } from "bunext-js/database";
const db = Database();
const users = db.Users.select({ where: { role: "admin" } });
PUBLIC_API_KEY="123456"
→ Accessible in client & serverAPI_KEY="private-key"
→ Only accessible in serverUse in code:
console.log(process.env.PUBLIC_API_KEY); // Available in client
console.log(process.env.API_KEY); // Server-only
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,
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
},
};
"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>
);
}
Bunext is optimized for speed and efficiency.
Contributions are welcome! Submit issues and PRs on GitHub.
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! 🚀
LIKE
operator for SELECT
operation[segmentName].tsx
is now supported
[id].tsx
was supported[segmentName]
is supported (e.g., [foo].tsx
, [bar].tsx
)[segmentName]
1.1.43
<head>
component<Head>
with useHead
Head
data can be dynamic. Request object is parsed as props to the page element (default export of index.tsx
)request
object from any component running on the serverPage
element (worked for layouts)"use static"
directive
/a/path/[id]
caches /a/path/1
and /a/path/2
"use static"
performance upgradedefault
verified as SSR elements are now cached properly
"use static"
benchmark addedgetServerSideProps
breaking when returning undefined
19.0.0
session.setExpiration()
getServerSideProps
getServerSideProps
breaking request when undefined
on route change/refresh in dev mode- 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
- Redirection is now possible in a ServerAction
- Fix regression API Endpoint cannot be reach introduced in 0.9.10
- 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
- Update Global Bunext object
- Refactor many components
- dynamic components method change ( only needs to add the server config )
- cleanup code for readability and maintainability
- Fix regression introduced in 0.9.18 where the onRequest file was not imported correctly
- much more verbose CLI outputs and automatic benchmarking
- Add a plugin system for altering the life cycle of the build, request and routing process
- Bunext global object updated
- Build process worker thread (improve build time by removing the overhead of triggering a new process each time)
- 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
- Fix minor init type
- Upgrade typed Route paths
- other minor improvement
- 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
Unknown package
The npm package bunext-js receives a total of 18 weekly downloads. As such, bunext-js popularity was classified as not popular.
We found that bunext-js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Security News
pnpm 10.12.1 introduces a global virtual store for faster installs and new options for managing dependencies with version catalogs.
Security News
Amaro 1.0 lays the groundwork for stable TypeScript support in Node.js, bringing official .ts loading closer to reality.
Research
A deceptive PyPI package posing as an Instagram growth tool collects user credentials and sends them to third-party bot services.