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-adapter
Create 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 changes
Check that it works:
curl http://localhost:3000/ping
for 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.