Thanks to visit codestin.com
Credit goes to oxide.build

Skip to content
Oxide
Esc
navigateopen⌘Jpreview

oxide@build:~ship the backend, skip the framework

Turn Vite or Rsbuild into a full-stack build. Import server functions in client code with end-to-end types, then deploy one server bundle anywhere.

[ok] 1 plugin · 1 build · 1 deployable tree

oxide 0.5
runtime
node / bun / deno
agentic
llms.txt
deploy
vps / workers / vercel

server code in. deployable app out.

Five files. No controllers, client SDK, or second build pipeline.

▶ run
// Looks local. Runs on the server. // Your server code never reaches the browser. import { create, watch } from "./notes.server"; const note = await create("Ship Oxide"); console.log(note); // { id: "…", title: "Ship Oxide" } // Stream actions return an async generator after await. for await (const n of await watch()) console.log(n);
// Only action()-wrapped exports are callable over the wire. import { action, useRequest } from "oxidejs"; export const create = action(async (title: string) => { return { id: crypto.randomUUID(), title }; }); export const watch = action(async function* () { useRequest(); // inbound Request inside the stream yield { id: "1", title: "Ship Oxide" }; });
// Every request hits this first. Return nothing to let // static files take over — no extra setup needed. export default { fetch(request: Request) { if (new URL(request.url).pathname === "/api/ok") return new Response("ok"); }, };
<!doctype html> <html lang="en"> <body> <div id="app"></div> <script type="module" src="/src/client.ts"></script> </body> </html>
import { defineConfig } from "vite"; import oxide from "oxidejs/vite"; export default defineConfig({ plugins: [oxide()], });
[ok]5 files · effect rpc · chunked streams

[01] // less plumbing. more shipping.

call server code directly

Import a *.server.ts function in the browser. Oxide turns the call into typed RPC and keeps the implementation on the server.

stream by yielding

Export an async generator to stream values over chunked JSON-RPC. Consume it with for await and cancel with an abort signal.

deploy boring output

Get one ESM server bundle plus optional client assets. Run it on a VPS, celld, Cloudflare, or Vercel.

[02] // one build. no backend side project.

$ tree dist/
dist/
├── client/        # if you have a page
└── server.js      # your backend

Build once with vite build. Oxide emits the browser assets and a server you can run withnode dist/server.js. Server actions use typed Effect RPC over HTTP or WebSocket.

build your first app →
import { defineConfig } from "vite"; import oxide from "oxidejs/vite"; export default defineConfig({ plugins: [oxide()], });
import { defineConfig } from "@rsbuild/core"; import oxide from "oxidejs/rsbuild"; export default defineConfig({ plugins: [oxide()], });

[03] $ ship something

Add one plugin. Write one server function. Call it from the browser. Your backend is ready to ship.