Skip to main content
Developer Experience

Your backend has never
reloaded this fast.

Frontend devs got instant feedback years ago. Backend devs are still restarting servers. Pikku changes that — edit, save, it's live. Across every protocol.

The Status Quo

Backend development is restart-driven.

You know the loop. Every backend developer does. Edit. Save. Wait for the server to restart. Lose your WebSocket connections. Re-authenticate. Test again. Hundreds of times per day.

Restart loop

100+ times / day

1Edit code
2Save file
3Server restarts
4Wait 2-5 seconds
5Re-test manually

Death by a thousand restarts

Each restart takes 2-5 seconds. At 100+ restarts per day, that's 5-10 minutes of pure waiting. But the real cost is the context switch — every restart breaks your flow.

Connections drop

WebSocket clients disconnect. Queue consumers stop. Cron timers reset. Every restart tears down your entire runtime state. Then you rebuild it manually to test again.

Multiple protocols, multiple restarts

If you're running HTTP, WebSocket, and a queue consumer, a single code change means restarting all of them. Different processes, different startup times, different headaches.

Why Frontend Has HMR and Backend Doesn't

Backend code is stateful.
That's the whole problem.

React components are pure functions of props and state — that's why React Fast Refresh works. Backend handlers? They're tangled with everything.

Route tables

Routes are registered at startup. Swapping a handler means re-registering routes, which means restarting the server.

Middleware chains

Middleware is composed at boot time. Each handler is wrapped in a closure chain that can't be unwound without a full restart.

Connection state

Database pools, WebSocket connections, in-memory caches — they all live in the process. Swapping code means losing state.

Framework coupling

Your handler is tangled with Express req/res, or Fastify's schema compiler, or Hono's context. The handler and the framework are inseparable.

This is why nodemon exists. It doesn't hot-reload your code. It kills the process and starts a new one. That's the best backend developers have had — until now.

Pikku functions are
stateless.

No route registration. No middleware closures. No framework coupling. Just a pure function: services in, data in, result out. That makes them hot-swappable by nature.

Traditional handler

// Coupled to Express
app.post('/api/greet',
  authMiddleware,      // ← framework state
  validate(schema),    // ← framework state
  async (req, res) => {
    const user = req.user  // ← coupled to req
    const { name } = req.body
    res.json({ message: `Hi ${name}` })
  }
)

Pikku function

// Pure function — no framework, no state
const greet = async (
  services: Services,
  data: { name: string }
) => {
  return { message: `Hi ${data.name}` }
}

// Auth, validation, routing — all metadata
// Swapping this file = instant reload

The function is just logic. Auth, validation, permissions, and routing are declared as metadata — not wired into the handler. When the file changes, Pikku swaps the function and reloads the metadata. No restart. No state lost. No connections dropped.

How It Works

Save. That's it.

Run pikku watch once. From then on, every file save is a live reload — across every protocol your function is wired to.

Step 1

You save a file

You edit a function — change the logic, add a field, update a return type. Just save.

No restart command. No waiting.

Step 2

Pikku reloads the metadata

The CLI detects the change, regenerates route metadata, types, and validation schemas. The function module is swapped in-place.

Sub-second. No process restart.

Step 3

It's live. Everywhere.

The updated function is immediately available on every protocol — HTTP, WebSocket, queue, cron, RPC, MCP, CLI. All at once. All in the same process.

One save. Every protocol. Instantly.

terminal
$ npx pikku watch
[pikku] Watching for changes...
[pikku]  greet.ts changed — reloaded in 47ms
[pikku]  Types regenerated
[pikku]  Live on: HTTP, WebSocket, RPC, Cron

Every Protocol

One save. Eight protocols.
Zero restarts.

Because Pikku functions are protocol-agnostic, a single file save updates the function everywhere it's wired. No per-protocol restart. No process juggling. One save and every consumer sees the new code.

HTTP

REST endpoints update instantly

WebSocket

No disconnection, no reconnection

Queue

Consumer keeps running, new logic applies

Cron

Next tick uses updated function

CLI

Command reflects changes immediately

RPC

Type-safe client stays in sync

MCP

AI tools update without restart

SSE

Streams continue uninterrupted

Compare this to traditional setups: HTTP on Express (restart), WebSocket on Socket.io (restart + reconnect), queue consumer on BullMQ (restart + re-subscribe), cron on node-cron (restart + re-schedule). Four processes. Four restarts. Four broken states. Pikku: one save.

The Dev Loop

Traditional vs. Pikku
side by side.

nodemon / ts-node
pikku watch
What happensKill process, restart from scratchSwap function module, reload metadata
Reload time2-5 seconds (compile + boot)< 50ms
ConnectionsAll dropped — WS, DB, queuesAll preserved
Type generationManual / separate watcherAutomatic on every save
Multi-protocolRestart each process separatelyOne save updates all protocols
Daily cost (100 edits)~8 min waiting + context switches~5 sec total, zero context switches

< 50ms

Reload time

Function swap + metadata reload

0

Dropped connections

WebSockets, queues, everything stays

~40 hrs

Saved per year

At 100 edits/day, 250 working days

Type Safety

Types regenerate
on every save.

When you change a function's input or output shape, pikku watch regenerates the TypeScript types, validation schemas, and client types — automatically. Your editor catches errors before you even switch to the browser.

Route metadata

HTTP paths, methods, permissions, and middleware — all regenerated from your function decorators. No manual route files to keep in sync.

Validation schemas

Input/output schemas are derived from your TypeScript types. Change the type, the schema follows. Runtime validation matches compile-time checks.

Client types

Auto-generated type-safe client types stay in sync with your functions. Your frontend knows the exact shape of every API response — always.

Stop restarting.
Start building.

The fastest backend feedback loop you've ever had. Edit, save, it's live — across every protocol, with full type safety, in under 50 milliseconds.

$ npm create pikku@latest

MIT Licensed · Works with Express, Fastify, uWS, Bun & more