Mid term (3-9 months)
By this point the experimental packages have been promoted to beta and the obvious gaps from short-term are filled. Mid-term is a focused list - three pillars - chosen because each unblocks a class of production apps that today need workarounds: realtime, observability, and read-heavy caching.
WebSocket support
plannedFirst-class WebSocket support that composes with existing decorators and DI. Two integration paths reflect the existing HTTP adapter split:
@miiajs/node-serverexposes WebSocket viawspackage@miiajs/uws-serveruses uWebSockets.js' native WebSocket upgrade (significantly faster)
API in @miiajs/core stays adapter-agnostic - decorators like @WebSocket('/chat') and @OnMessage('event-name'), with the same @UseGuard/@Use middleware composition as HTTP routes.
Why mid-term: WebSocket is a Web Standard, fits the framework's architecture, but needs careful design around connection lifecycle, broadcasting, and how the two adapters expose roughly the same primitives without leaking adapter-specific APIs.
OpenTelemetry integration (@miiajs/otel)
plannedAuto-instrument HTTP requests, DI providers, transport publish/dispatch, and database calls. Picks up the W3C trace context already plumbed through MessageEnvelope.meta.traceparent.
Module shape:
OtelModule.configure({
serviceName: 'orders-svc',
exporter: 'otlp', // or 'console' for dev
// automatically instrument:
instrumentations: ['http', 'messaging', 'drizzle', 'mongoose'],
})
Why mid-term: distributed tracing is a non-negotiable for multi-service production. The traceparent field is already there - this package wires it to spans on both ends.
Cache abstraction (@miiajs/cache + @miiajs/cache-redis + @miiajs/cache-unstorage)
plannedCacheStore interface mirroring IdempotencyStore shape: get/set/delete/has with optional TTL. Decorator @Cache({ ttl, key? }) for memoizing handler results. Three packages ship together:
@miiajs/cache- core: interface, decorator, middleware, in-memory store (the dev default).@miiajs/cache-redis- ioredis-backedCacheStorefor typical Node/Bun/Deno deployments.@miiajs/cache-unstorage- thin adapter (~30 lines) that wraps any unstorage driver as aCacheStore. The escape hatch for serverless/edge: Cloudflare KV, Vercel KV, Netlify Blob, S3, and ~30 more drivers come for free.
@Get('/user/:id')
@Cache({ ttl: 60, key: (ctx) => `user:${ctx.params.id}` })
async getUser(ctx) { ... }
Serverless story. app.fetch already runs MiiaJS on Cloudflare Workers, Vercel Edge, Netlify, and AWS Lambda. Forcing Redis on an edge runtime burns money on outbound network and adds latency. The unstorage adapter plugs the runtime's native KV directly into our CacheStore interface:
import cloudflareKV from 'unstorage/drivers/cloudflare-kv-binding'
import { unstorageStore } from '@miiajs/cache-unstorage'
CacheModule.configure({
store: unstorageStore(cloudflareKV({ binding: env.MY_KV }))
})
Because CacheStore is our interface, not unstorage's, native first-party drivers can land later (@miiajs/cache-cloudflare, @miiajs/cache-vercel-kv) without breaking users. They swap the store instance, nothing else changes.
Why mid-term: caching is the second most-requested cross-cutting concern after auth. Reusing the transport-store separation pattern from messaging keeps it consistent across the framework.
Examples expansion
examples/realtime-chat- WebSocket end-to-end with rooms, presence.examples/observability- OpenTelemetry + structured logging + metrics endpoint.examples/cached-api- cache decorator + Redis adapter + invalidation patterns.
Out of scope (deferred to long-term)
- NATS transport
- GraphQL
- Request-Reply for messaging
- Type-safe RPC client generation
- Job scheduling