Skip to main content

Omnitron

One TypeScript stack. Backend, RPC, UI, supervision.
No bridges. No codegen. No drift.

Titan is the backend framework — DI, lifecycle, modules, decorators. Netron is the RPC plane — HTTP, WebSocket, TCP, Unix sockets, one service contract. Prism renders the frontend. Omnitron the daemon supervises the fleet. Same types from the database row to the React hook. Zero generated code.

The stack

Six layers, one toolchain. Each one shipped, documented, and used in production. Nothing aspirational, nothing roadmap.

Titan — backend in a decorator

Decorator-driven services, container-based DI (Nexus), structured lifecycle (onInit / onStart / onStop / onDestroy), zod-validated configuration, typed error classes that travel across the wire. No ambient state, no thread-locals, no surprises.

@Module({
imports: [
ConfigModule.forRoot({ schema: AppConfigSchema }),
LoggerModule.forRoot({ level: 'info' }),
TitanDatabaseModule.forRoot({ dialect: 'postgres' }),
TitanAuthModule.forRootAsync({
useFactory: (cfg: ConfigService) => ({ jwtSecret: cfg.get('jwt.secret') }),
inject: [CONFIG_SERVICE_TOKEN],
}),
],
providers: [UsersService],
})
export class AppModule {}

Netron — one service, four transports

The same @Service is reachable over HTTP, WebSocket, TCP, and Unix sockets. Auth, middleware, rate limits, and tracing layer once and apply uniformly. Subscriptions stream over WS; everything else takes the cheapest path that fits.

@Service('orders@1.0.0')
export class OrdersService {
@Public() @Auth({ roles: ['user'] })
async create(input: CreateOrder) { /* ... */ }

@Public()
async *watch(filter: OrderFilter): AsyncIterable<OrderEvent> {
for await (const event of this.bus.subscribe(filter)) yield event;
}
}

// Client picks the transport; the contract is identical.
const ws = new NetronClient({ url: 'wss://api', transport: 'websocket' });
for await (const evt of (await ws.queryInterface<OrdersService>('orders@1.0.0'))
.watch({ tier: 'pro' })) handle(evt);

End-to-end types — no codegen

The service interface IS the hook contract. Refactor a method signature on the server, TypeScript fails the build on every client caller in the same `tsc` pass. No OpenAPI, no protobuf, no .d.ts sync step. The compiler is the source of truth.

// Backend signature changes —
@Public() async findById(id: string, opts?: GetOpts): Promise<User | null>

// Frontend breaks loudly until you migrate:
const users = useService<UsersService>('users');
const { data } = users.findById.useQuery([id]);
// ^? User | null | undefined ✓ traced through

// Forget the new opts arg? Type error. No drift. No runtime surprise.

Prism — 50+ components, three layers

MUI v7 foundation; schema-aware forms (react-hook-form + zod); three pre-built layouts; three full-page blocks; 25+ React hooks. Tree-shaken per subpath. Dark mode without flicker. Accessibility built in, never bolted on.

<DataGridBlock
title="Users"
columns={[
{ field: 'email', header: 'Email', sortable: true },
{ field: 'role', header: 'Role', filterable: { type: 'select', options: ROLES } },
{ field: 'status', header: 'Status', render: (r) => <StatusChip status={r.status} /> },
]}
query={({ page, sort, filter }) =>
users.list.useQuery([{ page, sort, filter }])
}
rowActions={[{ id: 'remove', label: 'Remove', danger: true,
confirm: { title: 'Remove user?' }, onClick: onRemove }]}
/>

16+ modules. Pick what you need.

Auth, cache, database, discovery, events, health, lock, metrics, notifications, process-manager, rate-limit, redis, scheduler, telemetry — plus built-in config + logger. Each independently versioned, each opt-in. No invisible runtime tax.

// Compose the modules you need. Skip the rest.
@Module({
imports: [
TitanRedisModule.forRoot({ config: { url: env.REDIS_URL } }),
TitanCacheModule.forRoot({ multiTier: true }),
TitanRateLimitModule.forRoot({ strategy: 'sliding-window', defaultLimit: 100 }),
TitanLockModule.forRoot(),
SchedulerModule.forRoot({ persistence: { provider: 'redis' } }),
TitanHealthModule.forRoot({ enableMemoryIndicator: true }),
],
})

Omnitron — supervisor + console + CLI

One daemon supervises N apps × M projects × K stacks. 20+ RPC services on the management plane. Web console (React + Vite + Prism). 75+ CLI subcommands. Declarative infrastructure (Postgres, Redis, MinIO, custom) via Docker or bare-metal. MCP server for AI agents.

# Boot the daemon + provision infra + start all apps.
$ omnitron up

# Stream logs across the fleet with filters.
$ omnitron logs api -f -l warn -g 'payment'

# Inspect the live DI graph of any running app.
$ omnitron inspect api --graph --format mermaid

# Drive everything from MCP — agents speak the same surface.
$ omnitron kb mcp

Four steps. One language. Zero glue.

Declare. Compose. Boot. Call. From a Postgres row to a React hook — one type system end-to-end. No OpenAPI, no protobuf, no client-server drift. This is the entire wire format.

// 1. Declare a service. The decorator is the contract.
@Service('users@1.0.0')
export class UsersService {
constructor(private readonly repo: UserRepo) {}

@Public()
@Validate(IdSchema)
async findById(id: string): Promise<User> {
return this.repo.findById(id);
}
}

// 2. Compose modules. DI, lifecycle, RPC exposure — wired by the container.
@Module({ imports: [DatabaseModule], providers: [UserRepo, UsersService] })
export class AppModule {}

// 3. Boot. One module, multiple transports.
const app = await Application.create(AppModule);
await app.start();

// 4. Call from React. The interface IS the hook.
const users = useService<UsersService>('users');
const { data, isLoading } = users.findById.useQuery(['u_42']);

// → No codegen. No schema sync. No drift. Pure TypeScript.
16+
modules
20+
daemon RPC services
75+
CLI subcommands
50+
Prism components
4
transports
3
RBAC roles
0
codegen steps

Capabilities

What the platform delivers, by layer. Every primitive verified against shipping source — no roadmap, no "coming soon".

Backend

Decorators (@Service, @Module, @Injectable, @Public, @Validate, @Auth, @Cron, @Cached, @WithDistributedLock, @Metrics, @CircuitBreaker). Container DI with scopes + contextual injection. Lifecycle hooks. Typed errors travel the wire intact.

RPC

Four transports, one service contract. Middleware pipeline (auth, rate-limit, validation, instrumentation). Token cache + JWKS rotation. AsyncIterable streaming over WS. Multi-backend client routing. Cross-tab auth sync via BroadcastChannel.

Frontend

Prism: 50+ MUI v7 components, 3 layouts, 3 blocks, schema-aware forms, 25+ hooks, dark mode without flicker. netron-react: useQuery / useMutation / useSubscription / useInfiniteQuery / useService — all typed from the backend interface.

Observability

pino logs with rotation. titan-metrics with Prometheus exposition + pluggable storage (memory / SQLite / Postgres). titan-health with k8s probes. titan-telemetry-relay store-and-forward over WAL. Per-app distributed traces. All aggregated by the daemon.

Supervision

Process pools with P2C balancing. Crash-restart with exponential backoff. Graceful shutdown in dependency order. File-watch hot reload in dev. Multi-app, multi-process, multi-instance topology. Persistent state across daemon restart.

Infrastructure

Declarative app requirements: database / redis / s3 / custom daemons. Docker provider for dev/test; bare-metal hooks for prod. Reconcile loop. Env-var templating with secrets (${host}, ${port:name}, ${secret:name}). One declaration, every environment.

Cluster + Fleet

Multi-node cluster with simplified Raft leader election (5–15 s timeouts, 2 s heartbeat). Master-slave state sync via batch replication. Per-node uptime bars with 90-day retention. Remote daemons addressed by alias. Cross-region patterns.

🜂

Agent-ready

omnitron-kb MCP server exposes ~9 KB tools + ~30 management tools to AI agents. Semantic + full-text hybrid search over the codebase. Agents read/write the same RPC surface as the CLI. Authoring + invocation through one protocol.

One stack. Ship.

pnpm add @omnitron-dev/titan. Write a decorated class. Boot. Add Netron when a client wants in. Add Prism when you render. Add Omnitron when you scale. Each step is the next import — never the next framework.