fluo is a TypeScript backend framework built on TC39 standard decorators and explicit dependency injection. Organize applications into controllers, services, and modules, then connect the database, authentication, and messaging packages you need.
Quick Start · Book · Documentation · Examples
- Standard decorators: No dependency on
experimentalDecorators,emitDecoratorMetadata, orreflect-metadata. fluo uses framework-owned metadata stores and standard decorator metadata integration. - Explicit dependencies: Declare constructor tokens with class-level
@Inject(...)and register providers and controllers with@Module(...). - Testable features: Compose HTTP routing, request validation, and response serialization, then verify DI wiring and request handling with the testing tools.
- A choice of hosts: Connect runtime-specific adapters to a shared module and DI model. Host lifecycle and package coverage follow each adapter's contract.
- Scaffolding through diagnostics: Use the CLI to generate projects and features and manage development, builds, and startup.
fluo inspectand Studio provide paths to application structure and diagnostics.
This minimal example puts an HTTP route, service injection, module registration, and Fastify startup in one file. The CLI starter below supplies the decorator transform and build configuration.
import { FluoFactory } from '@fluojs/runtime';
import { createConsoleApplicationLogger, createNodeShutdownSignalRegistration } from '@fluojs/platform-nodejs';
import { Inject, Module } from '@fluojs/core';
import { Controller, Get } from '@fluojs/http';
import { FastifyHttpApplicationAdapter } from '@fluojs/platform-fastify';
class GreetingService {
greet() {
return { message: 'Hello from fluo' };
}
}
@Inject(GreetingService)
@Controller('/greeting')
class GreetingController {
constructor(private readonly service: GreetingService) { }
@Get('/')
getGreeting() {
return this.service.greet();
}
}
@Module({
controllers: [GreetingController],
providers: [GreetingService],
})
class AppModule { }
const app = await FluoFactory.create(AppModule, {
adapter: FastifyHttpApplicationAdapter.create({
port: 3000,
}),
logger: createConsoleApplicationLogger(),
shutdownRegistration: createNodeShutdownSignalRegistration(),
});
await app.listen();Here, GET /greeting returns {"message":"Hello from fluo"}. Generated projects split this structure into separate files and add a repository, health checks, and tests. To run this example separately, replace the generated project's src/main.ts with the code above. The quick start below uses the unmodified starter.
Prerequisites: Install Node.js 24.x and pnpm 10. The CLI and Node.js path support >=24.0.0 <27. The CLI itself runs on Node.js even when generating a project for another runtime.
Start with the CLI published on npm; no repository clone is needed.
pnpm --allow-build=esbuild dlx @fluojs/cli new my-backend --package-manager pnpm
cd my-backend
pnpm dev--allow-build=esbuild is a pnpm option that approves the CLI dependency's install script. If prompted, keep the default standard / HTTP application / Node.js / Fastify choices and install dependencies. A global CLI installation is not required.
Once the server starts, send a request from another terminal. The default port is 3000; change it through PORT in the generated .env file.
curl http://localhost:3000/greeting{"message":"Hello from fluo","framework":"fluo","project":"my-backend"}GET /health also returns 200 and {"status":"ok"}. To change your first response, edit src/greeting/greeting.repo.ts. Follow request handling and dependency wiring in greeting.controller.ts, greeting.service.ts, and greeting.module.ts in the same directory.
Run the tests and build from the generated project directory:
pnpm test
pnpm buildThe starter includes a Fastify app, /greeting, /health, /ready, tests, and build configuration. Add authentication, persistent storage, and deployment configuration in your application. See the CLI guide for other starters and runner options, and the toolchain contract for supported transforms.
Upgrading an existing project? Follow the Node, packages, then imports order in the Node 24 migration guide. Upgrading the CLI does not automatically rewrite an existing app's configuration. Also check the Node.js support policy and HTTP dependency security update.
Connect the capabilities you need. These are representative packages; the package chooser provides the full catalog and selection guidance.
| Category | Packages |
|---|---|
| Foundations | Core, DI, Runtime, Config, I18n |
| HTTP/API | HTTP, Validation, Serialization, OpenAPI, GraphQL |
| Host adapters | Fastify, Express, Node.js, Next.js, Bun, Deno, Workers |
| Authentication | JWT, Passport |
| Data and caching | Prisma, Drizzle, Mongoose, Redis, Cache Manager |
| Messaging and jobs | Microservices, CQRS, Event Bus, Queue, Cron |
| Realtime and notifications | WebSockets, Socket.IO, Notifications, Email, Slack, Discord |
| Operations | Health (Terminus), Metrics, Throttler |
| React and developer tools | React, CLI, Testing, Vite, Studio |
Runtime support is package-specific. Having an adapter does not make every package portable to that host. For example, the Drizzle integration is Node.js-only, while the Socket.IO adapter supports Node.js and Bun but not Deno or Workers. The Next.js integration targets Node.js hosts, not the Edge Runtime. Before changing hosts, check startup, shutdown, and dependency requirements in the Canonical Runtime Package Matrix and the owning package README.
| Your goal | Start here |
|---|---|
| Learn backend design by building a product | Three-volume Book: FluoBlog → FluoShop → Fluo internals. Start with the volume 1 contents. |
| Try a short first HTTP feature | FluoBlog exercise: Learn routes, DI, request validation, and tests through repository checkpoints. |
| Add a capability to an existing app | Task guides and the package chooser. |
| Check APIs, defaults, and support | Use the documentation map to find the owning contract and package README. |
| Implement or review with AI | Read AI Context, then the documentation map/package chooser, the owning contract, and implementation, test, and execution evidence. |
| Compare runnable code | Check each app's environment and verification scope in the examples catalog. |
The Book is the primary learning path; the short HTTP exercise is a companion. The exercise starts from separate repository checkpoints rather than continuing directly in a CLI-generated app. It does not provide completed applications for every Book chapter.
- Discussions: Questions, ideas, RFCs, and use cases.
- Issues: Bug reports, documentation gaps, and feature requests.
- Contributing: Local setup, verification steps, and the PR process.
- Support: Choose the right support channel.
- Security: Report vulnerabilities privately.
- MIT license.
Explicit composition needs explicit boundaries. Package defaults, failure behavior, resource ownership, and support limits follow the behavioral contracts and the owning package README. Installing packages does not complete an application's authentication policies, data consistency, or external delivery guarantees.
This README is an entry point. The documentation authority policy defines ownership of detailed contracts; release governance defines how versions and changelogs are managed.
