Pikku builds a full type contract between your backend and frontend. It doesn’t ship a runtime SDK just typed native fetch calls / websockets / queue clients so your frontend gets zero added bundle size and fully inferred request/response types out of the box.
The framework is tree-shaken at the function level, so you can deploy only what’s needed (plus its dependencies) as a binary, Docker image, or serverless functions. Switch cloud providers or queue systems freely, no rewrites, just switch runtimes.
Auth, permissions, and middleware live directly at the function level, giving you a single consistent entrypoint across all transports.
It also supports Next.js-style "use server" patterns — you can call backend functions directly in SSR while keeping them accessible over HTTP for external use.
There’s even a CLI mode where you can run commands on a server and stream live output to a tiny local client — same code, same types.
I'm about to release the next version that allow supports workflows similar to those just released by Vercel or by Cloudflare Workflows.
Would love to hear your thoughts! There's even more on the roadmap :D
The goal is to provide a fully typed nodeJS framework that allows you to write a typescript function once and then decide whether to wire it up to http, websocket, queues, scheduled tasks, mcp server, cli and other interactions.
You can switch between serverless and server deployments without any refactoring / completely agnostic to whatever platform your running it on
It also provides services, permissions, auth, eventhub, advanced tree shaking, middleware, schema generation and validation and more
The way it works is by scanning your project via the typescript compiler and generating a bootstrap file that imports everything you need (hence tree shaking), and allows you to filter down your backend to only the endpoints needed (great to pluck out individual entry points for serverless). It also generates types fetch, rpc, websocket and queue client files. Types is pretty much most of what pikku is about.
Think honoJS and nestJS sort of combined together and also decided to support most server standards / not just http.
Website needs love, currently working on a release to support CLI support and full tree shaking.
I agree framing pikku has been a pretty hard challenge for me.
It supports different runtimes in the sense of deno / bun or custom nodeJS runtimes in the cloud, but ultimately relies purely on typescript / a JavaScript compatible backend.
It’s less of a webserver and more of a lightweight framework though, since it also supports CLIs or Frontend SDKs / isn’t tied to running an actual server.
I agree it’s pretty frustrating, but I do really like the SSR capabilities
I’m divide my frontend and backend via pikku, that way I can continue using normal server side functions but optionally spin up a seperate api service if needed.
Haven’t really tested it on vercel as much, but it ignores middleware on the nextJS side unless it’s for frontend code.
Most backends still treat HTTP as the “first-class citizen,” and everything else (WebSockets, queues, cron, mcp) feels bolted on with custom wiring and their own typings if any.
Pikku aims to take a different approach:
- Define a function once → invoke it from HTTP, WebSockets, queues, cron, or even Postgres.
- Deployment is your choice: single process, containers, serverless, or workers. Pick your own queue library, deploy scheduled tasks via lambda, the choice is endless.
- Fully typed, end-to-end → auto-generated clients are tiny, just thin wrappers over existing libs.
Built-in support for services, middleware, permissions, and auth.
I would recommend looking into being able to recognise ‘thought viruses’
A book that really helped me was ‘Stop overthinking’ by Nick Trenton. I still have those thoughts, Anxiety isn’t the easiest thing to get rid of.
Find what it is that you enjoy, build habits (tiny habits / atomic habits are great references) and you might find that just moving a tiny bit in the direction that makes you happy might compound over time.
Success isn’t always about careers or large paydays. Your health, relationships, hobbies, identity and sanity play a big part of that as well.
I have friends who moved to other countries and restarted their lives at the age of 35/40, and I met people in their 70s who done the same.
SEEKING WORK | Berlin (CET/CEST) | Remote | Senior Full-Stack & Cloud Specialist
I’m a senior developer and infrastructure consultant with 15+ years of experience
— available for part-time work (24h/week). I help teams move fast without breaking things, bringing deep infrastructure expertise alongside strong full-stack execution.
• Delivery-First Mindset: Recently helped a client setup up CI/CD, staging, and production environments via Kubernetes — from scratch to deploy — in just 3 weeks part-time
What I’m Looking For:
Teams with meaningful technical challenges — ideally past the MVP/PoC stage and ready to do things properly. I’m most effective where there’s a need to scale infra, clean up dev workflows, or modernize architecture.
Engagement Style:
• Part-time (24h/week)
• Open to short/middle term high-impact contracts, retainers, or embedded support
SEEKING WORK | Berlin (CET/CEST) | Remote | Senior Full-Stack & Cloud Specialist | Part-Time (24h/week)
I’m a senior developer and infrastructure consultant with 15+ years of experience — available for part-time work (24h/week). I help teams move fast without breaking things, bringing deep infrastructure expertise alongside strong full-stack execution.
• Delivery-First Mindset: Recently helped a client setup up CI/CD, staging, and production environments via Kubernetes and compliant — from scratch to deploy — in just 3 weeks part-time
What I’m Looking For:
Teams with meaningful technical challenges — ideally past the MVP/PoC stage and ready to do things properly. I’m most effective where there’s a need to scale infra, clean up dev workflows, or modernize architecture.
Engagement Style:
• Part-time (24h/week)
• Open to short/middle term high-impact contracts, retainers, or embedded support
It’s a TypeScript web framework that’s runtime agnostic, so it can work on serverless and servers (similar to Hono).
What’s different is that the focus is primarily just on TypeScript. There’s a CLI tool that inspects all the project code and generates loads of metadata. This can include:
• services used
• all the HTTP routes, inputs and outputs
• OpenAPI documentation
• schemas to validate against
• typed fetch client
• typed WebSocket client
(and more)
The design decision was also to make it follow a function-based approach, which means your product code is just functions (that get given all the services required). And you have controllers that wire them up to different transport protocols.
This allows interesting design concepts, like writing WebSocket code via serverless format, while allowing it to be deployed via a single process or distributed/serverless. Or progressive enhancement, allowing backend functions to work as HTTP, but also work via Server-Sent Events if a stream is provided.
It also allows functions to be called directly from Next.js and full-stack development frameworks without needing to run on a separate server or use their API endpoints (not a huge advocate, but it helps a lot with SSR). Gave a talk about that last week at the Node.js meetup in Berlin.
It’s still not 1.0 and there are breaking changes while I include more use cases.
Upcoming changes:
• use Request and Response objects to make it truly runtime agnostic (currently each adapter has its own thin layer, which tbf is still needed by many that don’t adopt the web spec)
• smarter code splitting (this will reduce bundle size by tree-shaking anything not needed on a per-function basis)
SEEKING WORK | Berlin (CET/CEST) | Remote | Part-time | Senior Full-Stack Developer and Cloud Specialist with 14+ years of experience seeking part-time work.
Experience Highlights:
- Fintech: 5 years with banks and hedge funds - Co-founder: deepstreamHub.com
- AI Projects: Tazamun on mindfulness and mental health
Seeking a part-time role with a motivated team. If you need senior expertise in infrastructure optimization or full-stack development without the commitment of a full-time hire, let's connect!
I have been working on an idea/Node.js library called vramework.dev recently, and a big part of it focuses on addressing the main complexities mentioned below.
For a bit of background, in order to tackle scalability, the initial approach was to explore serverless architecture. While there are both advantages and disadvantages to serverless, a notable issue with WebSockets on AWS* is that every time a message is received, it invokes a function. Similarly, sending a message to a WebSocket requires invoking an HTTP call to their gateway with the websocket / channel id.
The upside of this approach is that you get out-of-the-box scalability by dividing your code into functions and building things in a distributed fashion. The downside is latency, due to all the extra network hops.
This is where vramework comes in. It allows you to define a few functions (e.g., onConnect, onDisconnect, onCertainMessage) and provides the flexibility to run them locally using libraries like uws, ws, or socket.io, or deploy them in the cloud via AWS or Cloudflare (currently supported).
When running locally, the event bus operates locally as well, eliminating latency issues. If you apply the same framework to serverless, latency increases, but you gain scalability for free.
Additionally, vramework provides the following features:
- Standard Tooling
Each message is validated against its typescript signature at runtime. Any errors are caught and sent to the client. (Note: The error-handling mechanism has not yet been given much thought into as an API). Rate limiting is also incorporated as part of the permissioning system (each message can have permissions checked, one of them could rate limiting)
- Per-Message Authentication
It guards against abuse by ensuring that each message is valid for the user before processing it.
For example, you can configure the framework to allow unauthenticated messages for certain actions like authentication or ping/pong, while requiring authentication for others.
- User Sessions
Another key feature is the ability to associate each message with a user session. This is essential not only for authentication but also for the actual functionality of the application. This is done by doing a call to a cache (optionally) which returns the user session associated with the websocket. This session can be updated during the websocket lifetime if needed (if your protocol deals with auth as part of it's messages and not on connection)
And one last thing, it also produces a fully typed websocket client, so if using routes (where a property in your message indicates which function to use, the approach AWS uses serverless).
Would love to get thoughts and feedback on this!
edit: *and potentially Cloudflare, though I’m not entirely sure of its internal workings, just the Hibernation server and optimising for cost saving
const onConnect: ChannelConnection<'hello!'> = async (services, channel) => {
// On connection (like onOpen)
channel.send('hello') // This is checked against the input type
}
const onDisconnect: ChannelDisconnection = async (services, channel) => {
// On close
// This can't send anything since channel closed
}
const onMessage: ChannelMessage<'hello!' | { name: string }, 'hey'> = async (services, channel) => {
channel.send('hey')
}
export const subscribeToLikes: ChannelMessage<
{ talkId: string; action: 'subscribeToLikes' },
{ action: string; likes: number }
> = async (services, channel, { action, talkId }) => {
const channelName = services.talks.getChannelName(talkId)
// This is a service that implements a pubsub/eventhub interface
await services.eventHub.subscribe(channelName, channel.channelId)
// we return the action since the frontend can use it to route to specific listeners as well (this could be absorbed by vrameworks runtime in future)
return { action, likes: await services.talks.getLikes(talkId) }
}
addChannel({
name: 'talks',
route: '/',
auth: true,
onConnect,
onDisconnect,
// Default message handler
onMessage,
// This will route the message to the correct function if a property action exists with the value subscribeToLikes (or otherwise)
onMessageRoute: {
action: {
subscribeToLikes: {
func: subscribeToLikes,
permissions: {
isTalkMember: [isTalkMember, isNotPresenter],
isAdmin
},
},
},
},
})
A code example.
Worth noting you can share functions across websockets as well, which allows you to compose logic across different ones if needed
Each function can be wired to whatever transport you want:
Pikku builds a full type contract between your backend and frontend. It doesn’t ship a runtime SDK just typed native fetch calls / websockets / queue clients so your frontend gets zero added bundle size and fully inferred request/response types out of the box.The framework is tree-shaken at the function level, so you can deploy only what’s needed (plus its dependencies) as a binary, Docker image, or serverless functions. Switch cloud providers or queue systems freely, no rewrites, just switch runtimes.
Auth, permissions, and middleware live directly at the function level, giving you a single consistent entrypoint across all transports.
It also supports Next.js-style "use server" patterns — you can call backend functions directly in SSR while keeping them accessible over HTTP for external use.
There’s even a CLI mode where you can run commands on a server and stream live output to a tiny local client — same code, same types.
I'm about to release the next version that allow supports workflows similar to those just released by Vercel or by Cloudflare Workflows.
Would love to hear your thoughts! There's even more on the roadmap :D