trpc-bun-adapter is a tRPC adapter for Bun.
Start both HTTP and WebSockets transports with ease.
Install packages:
bun install @trpc/server trpc-bun-adapterCreate a server.ts file with the following content:
import {initTRPC} from '@trpc/server';
import {createBunServeHandler} from 'trpc-bun-adapter';
const t = initTRPC.create();
export const router = t.router({
ping: t.procedure.query(() => "pong"),
});
Bun.serve(createBunServeHandler({ router }));To start the server, run:
bun run server.ts
bun run --watch server.ts # to restart on file changesCheck that it works:
curl http://localhost:3000/pingfor a full example, see the example directory.
Ensure you have created a router.ts file as outlined in the tRPC documentation: Define Routers.
Creates a Bun serve handler:
import {createBunServeHandler, CreateBunContextOptions} from 'trpc-bun-adapter';
import {router} from './router';
const createContext = (opts: CreateBunContextOptions) => ({
user: 1,
});
Bun.serve(
createBunServeHandler(
{
router,
// optional arguments:
endpoint: '/trpc', // Default to ""
createContext,
onError: console.error,
responseMeta(opts) {
return {
status: 202,
headers: {},
}
},
batching: {
enabled: true,
},
},
{
// Bun serve options
port: 3001,
fetch(request, server) {
// will be executed if it's not a TRPC request
return new Response("Hello world");
},
},
),
);To add response headers like Cross-origin resource sharing (CORS) use responseMeta option:
Bun.serve(
createBunServeHandler({
router: appRouter,
responseMeta(opts) {
return {
status: 200,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization"
}
};
}
}
)
);Creates a Bun HTTP handler for tRPC HTTP requests:
import {createBunHttpHandler, CreateBunContextOptions} from 'trpc-bun-adapter';
import {router} from './router';
const createContext = (opts: CreateBunContextOptions) => ({
user: 1,
});
const bunHandler = createBunHttpHandler({
router,
// optional arguments:
endpoint: '/trpc', // Default to ""
createContext,
onError: console.error,
responseMeta(opts) {
return {
status: 202,
headers: {},
}
},
batching: {
enabled: true,
},
emitWsUpgrades: false, // pass true to upgrade to WebSocket
});
Bun.serve({
fetch(request, response) {
return bunHandler(request, response) ?? new Response("Not found", {status: 404});
}
});Creates a Bun WebSocket handler for tRPC websocket requests:
import { createBunWSHandler, CreateBunContextOptions } from './src';
import { router } from './router';
const createContext = (opts: CreateBunContextOptions) => ({
user: 1,
});
const websocket = createBunWSHandler({
router,
// optional arguments:
createContext,
onError: console.error,
batching: {
enabled: true,
},
});
Bun.serve({
fetch(request, server) {
const data = {
req: request // This is required for the adapter to work properly.
};
if (server.upgrade(request, { data })) {
return;
}
return new Response("Please use websocket protocol", {status: 404});
},
websocket,
});Note that it is required to store the request object on the socket data context in order for this adapter to work.
To ensure your router recognizes the context type, define a createContext function utilizing the CreateBunContextOptions type:
import { initTRPC } from '@trpc/server';
import type { CreateBunContextOptions } from "src/createBunHttpHandler";
export const createContext = async (opts: CreateBunContextOptions) => {
return {
authorization: req.headers.get('Authorization')
};
};With createContext defined, you can use it in your router to access the context, such as the authorization information:
const t = initTRPC.context<typeof createContext>().create();
export const router = t.router({
session: t.procedure.query(({ ctx }) => ctx.authorization),
});Finally, pass your createContext function besides router to createBunHttpHandler.
This integrates your custom context into the HTTP handler setup:
createBunHttpHandler({
router,
createContext,
})Read more documentation about tRPC contexts here: Contexts
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Feel free to open issues and pull requests.