Enhanced interactive playground for tRPC with tabs, request management, and much more.
- 📋 Intuitive and modern user interface
- 📑 Tab system to organize your queries/mutations
- 💾 Export and import queries to share with your team
- 🔄 Default data loading for new users (Tabs, Headers, etc.)
- 🔧 HTTP headers customization (global & per-tab)
- 🧬 Variables support with type validation (global & per-tab)
- 🎨 Light & dark themes
- ⚙️ Customizable settings (font size, timeout, split)
- ✨ Smart autocomplete & inline linting based on your tRPC schema
- 🪄 Built-in code formatter
- 🏢 Monorepo-friendly (isolate data per project)
- 🔌 Adapters for Fastify
- 🌈 Support for more frameworks (Express, Koa, etc.)
- 🧩 More configuration options to customize your experience
- ...and much more!
Feel free to suggest ideas or contribute on GitHub !
# npm
npm install trpc-playground-plus
# yarn
yarn add trpc-playground-plus
# pnpm
pnpm add trpc-playground-plusWith Fastify
import { createFastifyAdapter } from 'trpc-playground-plus/adapters/fastify';
import { fastify } from 'fastify';
import { appRouter } from './router';
const app = fastify();
// Playground configuration
await createFastifyAdapter({
app,
trpcEndpoint: 'http://localhost:3000/api/trpc',
router: appRouter,
playgroundEndpoint: '/playground'
});
// Start server
await app.listen({ port: 3000 });
console.log('🚀 Server available at http://localhost:3000');
console.log('🚀 Playground available at http://localhost:3000/playground');import { createFastifyAdapter } from 'trpc-playground-plus/adapters/fastify';
const myData = {
tabs: [
{
id: "tab-1",
title: "Get all users",
content: "trpc.user.getAll.query()",
isActive: true
},
],
headers: [
{
key: "Authorization",
value: "Bearer your-token-here",
enabled: true
}
],
};
await createFastifyAdapter({
app: fastify,
trpcEndpoint: '/api/trpc',
playgroundEndpoint: '/playground',
router: appRouter,
defaultData: myData // <- defaultData is optional but recommended for new user
});| Option | Type | Description | Default |
|---|---|---|---|
app |
FastifyInstance |
Fastify instance | (required) |
trpcEndpoint |
string |
tRPC API Endpoint | (required) |
router |
Router |
tRPC Router | (required) |
playgroundEndpoint |
string |
Playground path | /playground |
transformer |
'superjson' |
Data transformer used by your tRPC client | undefined |
defaultData |
ExportData |
Default tabs/headers to bootstrap the playground | undefined |
projectKey |
string |
Prefix for localStorage keys (monorepo isolation) | undefined |
If you use trpc-playground-plus in multiple projects served on the same domain (typical in a monorepo), the localStorage data would normally collide. Set a unique projectKey per project to isolate them:
// App A
await createFastifyAdapter({
app,
trpcEndpoint: '/api/trpc',
router: appRouter,
projectKey: 'app-a',
});
// App B (different project in same monorepo)
await createFastifyAdapter({
app,
trpcEndpoint: '/api/trpc',
router: appRouter,
projectKey: 'app-b',
});localStorage keys are then prefixed (e.g. app-a:trpc-playground-tabs), avoiding collisions. The projectKey is also embedded in exported JSON files so imports can warn when data is brought over from a different project.
Compatible with tRPC v11+ and zod 4.
During a project, we encountered limitations with the trpc-playground solution, which is no longer maintained. This is a proof of concept (POC) created to address the specific needs we had, while providing a modern and maintainable alternative for exploring and testing tRPC APIs easily.
MIT © Rémy 'Raesta' Mulet