Long term (9-12+ months)

Ecosystem expansion - new transports, integrations, and patterns that broaden where MiiaJS fits.

By the time these land, mid-term essentials are in production use and the framework has a couple of release versions behind it. Long-term items are bigger ecosystem bets - new transports, foreign protocol integrations, advanced patterns - and each will get a dedicated design discussion before implementation.

Items here are in planned or idea status. The line between them comes from real demand: items move up when at least two independent users ask for them.

NATS transport (@miiajs/messaging-nats)

planned

Native transport for NATS Core + JetStream. Big draws: native request-reply (nc.request()), built-in deduplication via Nats-Msg-Id (no extra IdempotencyStore needed for short windows), kv store for state, hierarchical subjects.

Builds on the existing MessageTransport interface - all decorators (@On, @OnRequest, @Idempotent) work unchanged.

Kafka and RabbitMQ transports are explicitly not on the roadmap until real demand surfaces. NATS covers the core use-cases (event bus + request-reply + KV); other transports get added when a production user asks.

Request-Reply for messaging

planned

RPC over the existing event bus. bus.request<TRes>(topic, payload, { timeout }) + @OnRequest(topic) decorator. Replies correlated through a per-client shared reply topic to avoid subscription churn. Per-transport implementation: NATS native, Redis manual, in-memory trivial.

Why long-term: RPC over messaging is niche-r than fire-and-forget events. Lands cleanly once NATS transport exists, since NATS provides this primitive natively and we can validate the abstraction against a real implementation.

GraphQL integration (@miiajs/graphql)

planned

@Query, @Mutation, @Subscription decorators that share DI/middleware/guards with HTTP controllers. Schema-first or code-first (probably both via Pothos). Subscription transport uses the existing messaging package + WebSocket adapter from mid-term.

Why long-term: GraphQL is a substantial integration - schema generation, federation, subscriptions, complexity analysis. Wants careful design, not a shim.

Type-safe RPC client generation

idea

Generate a fully-typed RPC client from controller signatures (tRPC-style), without giving up REST routes. Consumer side gets client.users.create(dto) typed end-to-end; server side stays plain HTTP controllers with their normal decorators.

Three approaches to compare in design:

  • Build-time codegen (miia generate client) - simple, no runtime overhead.
  • Inferred types via typeof appRouter - zero codegen but ties consumer build to server source.
  • Hybrid: types via typeof, runtime client via tiny dispatcher.

Why long-term: strongest unique angle for a decorator-driven framework on Web Standards, but worthless without first having stable controller decorators (we have them) and a real consumer story (don't yet).

Job scheduling

idea

Cron-like decorator: @Cron('0 */5 * * *') on a method runs it on a schedule. Pluggable store (memory or Redis-backed for distributed deduplication). Backed by the same DI lifecycle so jobs see onInit providers.

Demoted from mid-term to idea because scheduling has solid out-of-process answers (k8s CronJob, systemd timer, BullMQ) and embedding it in the framework adds complexity that not every app needs. We'll wait for the second user request.

Testing utilities expansion

idea

TestApp covers the basics. Likely additions once we feel the gaps in real test suites:

  • Transport mocks: MockMessageBus with assertion helpers (expect(bus).toHaveDispatched('order.created')).
  • Time control: app.useFakeTimers() for retry/idempotency expiration tests.
  • Database fixtures: per-test transaction rollback, snapshot helpers.
  • Request fluent builder: await app.get('/users').auth(token).expect(200).

Not urgent - waiting until specific patterns repeat across enough test files to justify the abstraction.

Performance work

idea

Continuous, not project-managed:

  • More benchmarks in the miiajs/benchmarks repo - extend coverage to messaging and DB scenarios.
  • HMR for miia dev (currently restarts the whole process).
  • Profile-guided optimization for hot paths once 1.0 is out.

Things explicitly NOT on the roadmap

Worth being explicit about what we are not going to build, so users plan accordingly.

  • Custom request/response abstractions. Web Standards Request/Response are the only types. No MiiaRequest, no Reply object.
  • Module scoping by default. Per-app DI container, flat. If a user case requires sub-scopes, we'd add it - but the default stays flat.
  • A bundled UI / admin panel. Out of scope - users compose their own.
  • A bundled ORM. Drizzle/Mongoose/Papr exist; we integrate, we don't build.
  • reflect-metadata polyfills. TC39 native decorators only.
  • CommonJS dual-package outputs. ESM-only forever.
  • Compression middleware. gzip/brotli is the proxy's job (nginx, Caddy, CDN). Embedding it in the runtime burns CPU on every node and complicates streaming responses.
  • Migration CLI wrapper. drizzle-kit already does this well for Drizzle. Mongoose and Papr have no official migration CLI - schema migrations are mostly a non-concern (schemaless storage); data migrations are app-specific scripts that don't fit a generic wrapper. A miia db:migrate umbrella would add a layer that breaks in subtle ways without giving anything new.
  • Decorator-based transactions. A @Transactional() decorator was considered and rejected. Implementation requires AsyncLocalStorage indirection so inject(db) returns the in-flight transaction instead of the connection - the clarity cost (silent context-dependent behaviour) is bigger than the ergonomic win (saving one closure level). Use the ORM's native callback API directly: db.transaction(async (tx) => { ... }). Recipes in docs cover Drizzle/Mongoose/Papr patterns.
  • Separate auth-strategy packages. OAuth2, API keys, session-based - all stay as recipes in docs. ~50 lines of glue each, no maintenance benefit from shipping them as packages.
  • Health checks package. A recipe + small core helper covers the same ground. Each module exposes a healthCheck() function from its module file; the user composes them in a controller.
  • DI graph visualization. Useful but not framework-level. If demand appears, lands as an external community tool.
  • Kafka and RabbitMQ messaging transports. NATS covers the same surface for our target deployments. We'll add them when a production user asks.
  • Realtime helpers (rooms, presence, typing indicators). Considered, dropped. Mid-term WebSocket support + the existing messaging package + the SSE helper in core compose into rooms/presence/broadcast in ~150 lines of app-specific code, which is exactly the right place for opinionated decisions (delivery guarantees, replay-on-reconnect, presence timeouts). Specialized solutions (Socket.IO, Centrifugo, Liveblocks, PartyKit, Pusher, Ably) cover the rest. We ship recipes and an examples/realtime-chat example, not a @miiajs/realtime package.

Want to suggest something?

Open an issue describing the problem (not the solution). The strongest signal is a use case from production where MiiaJS doesn't fit. The roadmap moves on real demand.