brpc is a minimal yet powerful router and server framework for Bun, inspired by tRPC but tailored for high performance and flexibility. It offers:
✅ End-to-end type safety with TypeScript and Zod validation
✅ Procedures with built-in middleware for structured route handling
✅ WebSocket subscriptions & real-time updates
✅ Automatic handling of file uploads and form-data
✅ Global middlewares for rate-limiting, path blocking, and more
✅ Streaming support for queries, mutations, and formMutations
import { createRouter } from "brpc";
import type { BaseContext } from "./types";
// Define custom context type
export interface CustomContext extends BaseContext {
user?: User;
}
const context = createContext<CustomContext>(...)
const router = createRouter({
context: context,
routes: routes,
globalMiddlewares: [],
prefix: "/",
});
// Start the server
router.listen(3000, () => {
console.log("🚀 brpc server running on http://localhost:3000");
});
Procedures allow structured route handling with middleware, similar to tRPC.
import { createProcedure } from "brpc";
// Base procedure
export const procedure = createProcedure<CustomContext>();
// Middleware-protected procedure
export const userProcedure = procedure.use(async (ctx) => {
if (!ctx.user) throw new Error("Unauthorized");
});
Middleware allows you to attach logic to a procedure, ensuring structured validation and security.
const routes = {
index: procedure.query(async ({ ctx }) => {
return "Hello from brpc";
}),
};
➡️ This will return {data:"Hello from brpc"}
when a GET
request is made to /
.
const routes = {
app: procedure.file(async () => Bun.file(".app/index.html")),
"client.js": procedure.file(async () => Bun.file(".app/client.js")),
};
➡️ Serve an HTML app and client-side JS files easily. brpc automatically sets appropriate headers.
brpc natively supports WebSocket subscriptions. Additionally, queries, mutations, and form mutations now support streaming responses, allowing real-time updates directly from server-side procedures.
const routes = {
getMessages: procedure.query(async ({ ctx, stream }) => {
for await (const message of messageStream()) {
stream.status({ event: "newMessage", data: message });
}
}),
sendMessage: procedure
.input(z.object({ username: z.string(), text: z.string() }))
.mutation(async ({ ctx, input, stream }) => {
const newMessage = await pushMessage(input);
stream.status({ event: "messageSent", data: newMessage });
return newMessage;
}),
":channelId": procedure
.input(
z.object({
username: z.string(),
text: z.string(),
pushed: z.boolean().nullish(),
})
)
.subscription(async ({ ctx, input }) => {
if (input.text === "withError") throw new Error("Message with error");
if (!input.pushed) await pushMessage(input);
return { ...input, timestamp: Date.now() };
}),
};
✅ Subscriptions are internal and automatically push messages to connected clients.
✅ Queries, mutations, and form mutations can stream data in real-time using stream.status
.
✅ Errors thrown in subscriptions will propagate to listeners, allowing UI rollback.
brpc makes file uploads seamless, automatically parsing form-data into structured input:
const routes = {
withFormData: procedure
.input(
z.object({
files: createFileSchema({
acceptedTypes: { audio: "*" },
maxSize: 5,
}).array(),
})
)
.formMutation(async ({ ctx, input, stream }) => {
console.log(input.files);
// Example: Upload to S3
const command = new PutObjectCommand({
Bucket: process.env.AWS_BUCKET_NAME!,
});
// Track upload progress
stream.status({ event: "upload", progress: 50, status: "uploading" });
return { success: true };
}),
};
✅ Automatic file validation with Zod
✅ Real-time upload progress tracking via the stream.status
helper
Feature | Description |
---|---|
✅ Middleware Support | Global and per-procedure middleware for security, validation, and more |
✅ WebSockets & Subscriptions | Real-time messaging and internal-only WebSocket topics |
✅ Streaming for Queries & Mutations | Live data updates for queries, mutations, and form mutations |
✅ Static File Serving | Serve HTML, JS, and other static assets effortlessly |
✅ Multipart/Form-Data Handling | File uploads with validation, streaming, and real-time progress tracking |
✅ Error Handling | Automatic handling of internal, context, and middleware errors |
✅ Rate Limiting & Security | Global middleware like rate limiting and path blocking |
✅ JSX Rendering Support (server-side rendering with Bun)
✅ Extended CORS Configuration
✅ Server-Sent Events (SSE) for streaming responses
✅ Advanced authentication middleware (JWT, OAuth, etc.)
✅ Edge compatibility for ultra-fast execution
📌 brpc is already powering production apps! It’s built for speed, flexibility, and maintainability. 🎯
Interested in contributing or using brpc? Let me know! 🚀