Event Sourcing first-class
Aggregate roots, domain events, and projections with built-in replay. Your event log is the source of truth.
Object-oriented and domain-driven by design. Built for teams shipping complex, multi-tenant SaaS on microservices — not just landing pages.
$ sf init
✔ Monorepo created
$ sf generate microservice crm
✔ crm microservice created
$ sf run
✔ crm microservice started → http://localhost:3000/
✔ admin panel companion started → http://localhost:3001/ Most frameworks stop at routing and auth. SaaSFormation goes further.
Aggregate roots, domain events, and projections with built-in replay. Your event log is the source of truth.
Shared TypeScript contracts across service boundaries. No runtime surprises when services talk to each other.
HTTP requests, commands, queries, and domain events all follow the message bus pattern. Every bus accepts middleware — add logging, auth, or tracing once and it applies everywhere.
Reflect-metadata DI container with constructor injection. Repositories, services, and handlers wire themselves.
OpenTelemetry traces and Grafana dashboards pre-configured. Know exactly what your services are doing in production.
Standards-compliant JSON:API with built-in Swagger documentation. Versioned, consistent endpoints your consumers can explore and test from day one.
No spaghetti. Clean, typed, testable command handlers with the dependencies they need — and nothing else.
@Inject — no service locators CommandHandler<T> enforces the contract import { Inject } from "@saasformation/di";
import { CommandHandler } from "@saasformation/message-bus";
@CommandHandler(RegisterUser)
export class RegisterUserHandler
implements CommandHandler<RegisterUser>
{
constructor(
@Inject(UserRepository)
private readonly users: UserRepository,
) {}
async handle(cmd: RegisterUser): Promise<void> {
const user = User.register(
cmd.email,
await Password.hash(cmd.password),
);
await this.users.save(user);
}
} We're opening access progressively. Leave your email and we'll reach out when it's your turn.