Skip to content

Multijet

A framework for TypeScript microservice monorepos, where the OpenAPI contract generates the types and the compiler guarantees nobody breaks it.

Open source · TypeScriptGo to the repository

Multijet is an opinionated framework for building microservice monorepos in TypeScript. The structure is simple and deliberately rigid: each microservice is an independent Node.js project based on Fastify, and each shared package lives in libs/ as a project in its own right, importable from a microservice or from another lib.

The central point of the project, though, is not the structure. It is the fact that type safety runs through the whole system, without interruption and without having to be maintained by hand.

The problem of contracts between services

In a microservice architecture the boundary between two components is the most fragile point in the system. Service A calls service B: somewhere there is a shared idea of what that request and response look like, but the language does not know it. It exists in a document, in a type file copied by hand, or in the head of whoever wrote both sides.

When that contract changes (a renamed field, a type that becomes optional, an enum with one more value) nothing notices the break. The code compiles, the tests pass if they do not cover that path, and the error arrives at runtime, in an environment different from that of the person who made the change. The more services there are, the more frequent this scenario becomes and the more expensive it is to diagnose.

OpenAPI as the single source of truth

In Multijet the contract is not documentation: it is the source from which everything else is generated.

Each microservice starts from its own OpenAPI specification. From there come the request and response types, the handler signatures and the clients the other services will use to call it. The result is an unbroken chain of types: from schema to route, from route to handler, from handler to client, from client to caller.

The practical consequence is that breaking a contract silently becomes impossible. If a response changes shape, the service that consumes it stops compiling: immediately, on the machine of whoever made the change, not in staging three days later. The error that used to be the hardest to find becomes the easiest: the editor flags it as you type.

It also follows that the API documentation cannot diverge from the code, because the code derives from it. And that adding an endpoint means describing it once, instead of writing it, typing it, documenting it and replicating it in the client.

Fast builds

A monorepo with many services quickly becomes slow to build, and at that point the modular structure starts to cost instead of paying off. Multijet uses turborepo for caching and task orchestration and esbuild for bundling: each microservice is compiled into a single file, dependencies included, in the order of milliseconds.

The single bundle also simplifies deployment, which supports both AWS Lambda and Docker by default, with no changes to the application code.

What it includes

A CLI to generate and manage services and libraries, optional modules that can be enabled per service, centralised configuration, and Jenkins pipelines and SonarCloud integration available as an option.