Skip to main content
TypeScript Function Framework

One function.
Every wiring.

Write your backend once. Pikku wires it to HTTP, WebSocket, queues, cron, AI agents, workflows, and more — same auth, same validation, zero rewrites.

$ npm create pikku@latest  ·  MIT Licensed  ·  Open Source

Built with Pikku

AgreeWeHeyGermanymartaBambooRoseCalligraphy Cut

Sound Familiar?

You've written this function more times than you'd admit.

Every time you add a protocol, you copy-paste, re-wire auth, and pray the handlers don't drift. It's not lazy engineering — it's a missing abstraction.

"So many places in my code base have like three entry points: CLI, public HTTP API and internally from within the API. Would be so nice having everything just an invoke away."— Alex Harley, CTO @ Bamboo Rose

Same logic, five handlers

Your getCard function lives in your HTTP handler, your WebSocket handler, your queue worker, and your CLI. They started as copies. Now they've drifted apart.

New protocol, new framework

Want AI agents? That's Vercel AI SDK. Workflows? Inngest or Temporal. MCP? Another adapter. Each one brings its own auth layer, schema format, and deploy pipeline.

Switching runtimes means rewriting

Moving from Express to Lambda touches every handler. Your business logic is tangled with framework APIs you never wanted to think about.

The Fix

One function that doesn't drift.
Fix a bug once, it's fixed everywhere.

Without Pikku5 copies that drift
// HTTP
app.get('/cards/:id', auth, validate, async (req, res) => {
const card = await db.getCard(req.params.id)
res.json(card)
})
// WebSocket
ws.on('getCard', auth, validate, async (msg, socket) => {
const card = await db.getCard(msg.cardId)
socket.send(JSON.stringify(card))
})
// Queue worker — same logic, third copy
// CLI command — same logic, fourth copy
// AI agent tool — new SDK, new auth, fifth copy
With Pikku1 function + wirings
// Write it once
const getCard = pikkuFunc({
func: async ({ db }, { cardId }) => db.getCard(cardId),
permissions: { user: isAuthenticated }
})

// Wire it to everything — same auth, same validation
wireHTTP({ method: 'get', route: '/cards/:cardId', func: getCard })
wireChannel({ name: 'cards', onMessage: { getCard } })
wireQueueWorker({ queue: 'fetch-card', func: getCard })
wireCLI({ program: 'cards', commands: { get: getCard } })
+ SSE+ RPC+ MCP+ AI Agent+ Workflow+ Trigger+ Gateway

12 protocols total — all with the same pattern. See every wiring in action

More Than a Router

AI agents, durable workflows,and drop-in billing — built in.

tRPC stops at HTTP. Hono gives you a fast router. NestJS buries you in decorators. Pikku gives you agents, workflows, and installable backend features — all using the same functions you've already written.

AI AgentsAlpha

Your functions are already agent tools

Most frameworks need adapters, schema re-definitions, and a separate auth layer for AI agents. With Pikku, pass your existing functions directly. Types, permissions, and middleware carry over.

Zero glue code — functions become tools automatically
Auth and permissions follow the agent
Any LLM provider — just swap the model name
Learn about AI Agents
const support = pikkuAgent({
instructions: 'You are a support agent...',
tools: [getCustomer, getOrders, createTicket],
model: 'claude-sonnet-4-5'
})
Workflows

Multi-step processes that survive restarts

No separate workflow engine. Write sequential steps like normal code. Pikku persists each step, retries on failure, and resumes exactly where it left off — even after deploys.

Deterministic replay from the exact failure point
Sleep for minutes, hours, or weeks
State persists to PostgreSQL or Redis
Learn about Workflows
await workflow.do('Create profile', 'createProfile', { userId })
await workflow.sleep('Wait', '5min')
await workflow.do('Send welcome', 'sendEmail', { to: email })
Addons

Install Stripe billing in one line

Addons are drop-in backend features. One wireAddon() call adds Stripe, SendGrid, or any package — fully typed, namespaced, sharing your existing database and services.

Drop-in packages, not bolt-on frameworks
Fully typed across package boundaries
Secrets you control via secretOverrides
Learn about Addons
wireAddon({ name: 'stripe', package: '@pikku/addon-stripe' })
// Then call it from anywhere:
await rpc.invoke('stripe:checkoutCreate', { plan: 'pro' })
GatewayNew

One handler for WhatsApp, Slack, and Telegram

Most messaging integrations mean a new SDK, a new webhook handler, and a new auth layer per platform. With Pikku, write one handler — the adapter normalizes every platform into the same message format.

Normalized messages — same interface across all platforms
Auto webhook verification for WhatsApp, Slack, Telegram
Webhook, WebSocket, or listener — same handler function
Learn about Gateways
wireGateway({
name: 'whatsapp',
type: 'webhook',
route: '/webhooks/whatsapp',
adapter: whatsAppAdapter,
func: handleMessage,
})

Built for the problems developers actually have

From the teams who switched

"So many places in my code base have like three entry points: CLI, public (sometimes protected) HTTP API and internally from within the API. Would be so nice having everything just an invoke away. With Nest it's a pain because you basically have to start the whole API up just to run CLI command."

Alex Harley

Co-founder @ Superbridge

"Ever been annoyed at having to write your code different in a Lambda than in an express handler? Pikku fixes that."

Christoph Sitter

CTO @ spot

Deploy Anywhere

Change your runtime.
Keep your functions.

Same code runs on Express, Fastify, AWS Lambda, Cloudflare Workers, Next.js, and more. Switching runtimes never requires touching your functions.

Plus any custom runtime via the adapter interface. Build your own →

Built For Production

Production-grade out of the box

Auth, validation, type-safe clients, middleware — all built in. No bolting on third-party packages for every new protocol.

MIT licensed. Standard TypeScript. No VC-backed lock-in.

Type-Safe Clients

Auto-generated HTTP, WebSocket, and RPC clients with full IntelliSense.

Auth & Permissions

Cookie, bearer, API key auth with fine-grained permissions — built in.

Services

Singleton and per-request dependency injection, type-safe and testable.

Middleware

Before/after hooks for logging, metrics, tracing — work across all protocols.

Schema Validation

Runtime validation against TypeScript input schemas. Supports Zod.

Zero Lock-In

Standard TypeScript, tiny runtime, MIT licensed. Bring your own everything.

Visual Control PlaneAlpha

Every function, every wire,
every secret — one screen

Browse functions, run agents, manage secrets, and trigger workflows — without writing tooling code.

Pikku Console — browse and inspect all functions, wirings, and services
Browse all functions & wiringsAgent playgroundRun & visualize workflowsManage secrets & variablesPer-environment control

Stop copying functions across protocols.

Write it once. Pikku wires it everywhere.

$ npm create pikku@latest

5-minute setup  ·  MIT Licensed  ·  Open Source