Documentation/titan/Module map
In this section

Module map

A bird's-eye view of every module in the Titan ecosystem — who depends on whom, who can substitute for whom, and which combinations show up in real backends.

Dependency graph

flowchart TB
  subgraph Builtin["Built-in (ship with @omnitron-dev/titan)"]
    Config[config]
    Logger[logger]
  end

  subgraph Foundations["Foundation modules"]
    Redis[titan-redis]
    Events[titan-events]
    Database[titan-database]
  end

  subgraph Observability["Observability"]
    Health[titan-health]
    Metrics[titan-metrics]
    Telemetry[titan-telemetry-relay]
  end

  subgraph Coordination["Coordination & runtime"]
    Lock[titan-lock]
    Scheduler[titan-scheduler]
    PM[titan-pm]
    Discovery[titan-discovery]
  end

  subgraph Surface["Surface modules"]
    Auth[titan-auth]
    Cache[titan-cache]
    RateLimit[titan-ratelimit]
    Notifications[titan-notifications]
  end

  Lock --> Redis
  Discovery --> Redis
  Cache -. L2 tier .-> Redis
  RateLimit -. redis storage .-> Redis
  Notifications --> Redis
  Scheduler -. redis persistence .-> Redis

  Health -. db indicator .-> Database
  Health -. redis indicator .-> Redis

  Notifications -. preference store .-> Database
  Telemetry -. ships .-> Metrics

  Auth -. token cache .-> Cache

  classDef builtin    fill:#e8f5e9,stroke:#43a047,color:#1b5e20
  classDef found      fill:#e3f2fd,stroke:#1976d2,color:#0d47a1
  classDef obs        fill:#fff8e1,stroke:#fb8c00,color:#e65100
  classDef coord      fill:#f3e5f5,stroke:#8e24aa,color:#4a148c
  classDef surf       fill:#fce4ec,stroke:#d81b60,color:#880e4f

  class Config,Logger          builtin
  class Redis,Events,Database  found
  class Health,Metrics,Telemetry obs
  class Lock,Scheduler,PM,Discovery coord
  class Auth,Cache,RateLimit,Notifications surf

Solid arrows are hard dependencies — you can't run the dependent module without the foundation. Dotted arrows are soft / optional — feature flagged at config time (storageType: 'redis', multiTier: true, enableDatabaseIndicator: true).

Install footprint

The numbers below count peer modules a typical adoption pulls in (transitive Redis client, postgres driver, etc. are omitted):

You installWhat else lights up
titan-eventsStandalone
titan-redisStandalone
titan-databaseStandalone (+ db driver)
titan-cacheStandalone (+ titan-redis if multiTier: true)
titan-lock+ titan-redis
titan-discovery+ titan-redis
titan-ratelimitStandalone (+ titan-redis if storageType: 'redis')
titan-notifications+ titan-redis (+ titan-database for preference store)
titan-schedulerStandalone (+ titan-redis for distributed persistence)
titan-authStandalone (+ titan-cache for token cache)
titan-healthStandalone (indicators light up per enableXxxIndicator)
titan-metricsStandalone (+ storage driver if persisting)
titan-telemetry-relayStandalone (paired with titan-metrics at remote end)
titan-pmStandalone

The framework deliberately keeps modules independently versionable — you only pull in what you actually use.

Common stacks

Web API service

built-in · @omnitron-dev/titan · config + logger official · titan-redis + titan-database + titan-cache + titan-auth + titan-health + titan-metrics

flowchart LR
  C[config + logger] --> R[titan-redis]
  R --> Ca[titan-cache]
  R --> A[titan-auth]
  D[titan-database] --> H[titan-health]
  R --> H
  C --> M[titan-metrics]

Common starting set for any REST / RPC backend.

Worker fleet

built-in · @omnitron-dev/titan · config + logger official · titan-redis + titan-database + titan-lock + titan-scheduler + titan-metrics + titan-health

flowchart LR
  C[config + logger] --> R[titan-redis]
  R --> L[titan-lock]
  R --> S[titan-scheduler]
  D[titan-database] --> H[titan-health]
  C --> M[titan-metrics]

titan-lock is what stops two workers running the same job.

Notification gateway

built-in · @omnitron-dev/titan · config + logger official · titan-redis + titan-notifications + titan-ratelimit + titan-metrics

flowchart LR
  C[config + logger] --> R[titan-redis]
  R --> N[titan-notifications]
  R --> RL[titan-ratelimit]
  C --> M[titan-metrics]

titan-ratelimit shields the upstream provider; titan-metrics records throughput / failures by channel.

Multi-instance app

Add titan-discovery to any of the above when you have more than one pod and want to address services without hard-coded URLs.

Edge / offline node

official · titan-telemetry-relay · stable

Add titan-telemetry-relay when the node may be disconnected from the central metrics endpoint — it buffers samples to SQLite and flushes when connectivity returns.

Similar modules — when which?

NeedReach forWhy
Sync in-process pub/subtitan-eventsFire-and-forget, intra-process, typed channels
Reliable cross-pod queuetitan-notificationsBuilt on rotif; survives crashes, has DLQ + retry
Periodic work (cron / interval)titan-schedulerPer-job persistence + missed-fire handling
Memoize a function calltitan-cache@Cacheable(...) decorator; multi-tier (L1+L2)
Talk to Redis directlytitan-redisJust a typed client; no service abstraction
Throttle callstitan-ratelimitToken-bucket / sliding-window / fixed-window
Coordinate across instancestitan-lockRedis-backed mutex with UUID ownership
Spawn / supervise child processestitan-pmWorker pools, IPC, crash supervision
Find sibling servicestitan-discoveryHeartbeat-based service registry
Count / measuretitan-metricsCounters, gauges, histograms; Prom exposition
Ship metrics off-hosttitan-telemetry-relayStore-and-forward; survives offline windows
Check it's alivetitan-healthk8s probes + custom indicators
Authenticate RPC callerstitan-authJWT (HS256/RS256/ES256), JWKS, token cache
Query a databasetitan-databaseKysely + migrations + RLS
Validated configconfig (built-in)Layered, validated, hot-reloadable
Structured logginglogger (built-in)pino under the hood; transports + processors

Replacement / overlap matrix

ModuleClosest overlapWhen to prefer
titan-eventstitan-notificationsIn-process / no persistence / lowest latency
titan-notificationstitan-events + titan-schedulerCross-process, retry, DLQ, channel templating
titan-cachebare titan-redisCaching semantics (@Cacheable, TTL, multi-tier)
titan-schedulersetInterval / node-cronPersistence, missed-fire, observability
titan-lockbare SETNX on RedisSafe ownership (UUID) + Lua-script atomicity
titan-discoveryenv-var URL configDynamic topology, autoscaling, rolling deploys
titan-metricsprom-clientNative persistence + cross-pod aggregation
titan-telemetry-relaydirect Prom scrapeEdge / offline / store-and-forward
titan-healthrolling-your-own /healthzStandard k8s probe shapes + indicator registry
titan-authmanual JWT verificationJWKS rotation, token cache, RBAC primitives

Where Redis sits

Five official modules use Redis as their primary backend. They share the same Redis client provided by titan-redis:

flowchart LR
  R[(Redis)]
  R --- L[titan-lock]
  R --- D[titan-discovery]
  R --- Ca[titan-cache L2]
  R --- RL[titan-ratelimit]
  R --- N[titan-notifications]

Register TitanRedisModule.forRoot(...) once at app boot; all five pick up the connection automatically.

@Module({
  imports: [
    TitanRedisModule.forRoot({ config: { url: env.REDIS_URL } }),
    TitanLockModule.forRoot(),
    DiscoveryModule.forRoot(),
    TitanCacheModule.forRoot({ multiTier: true, l2: { /* picked up */ } }),
    TitanRateLimitModule.forRoot({ storageType: 'redis' }),
    NotificationsModule.forRoot({ /* … */ }),
  ],
})
class AppModule {}

Recommended Redis-DB split (avoid keyspace collisions):

DBPurpose
0App data (cache, sessions, business state)
1Queues / pub-sub (notifications, events)
2Rate limits
3Locks (titan-lock)
4Discovery registry

Configure per-module by passing a different db: index in the options, or by registering multiple named Redis clients via TitanRedisModule.forFeature(['cache', 'queue', …]) (or the clients: [...] option on forRoot).

Lifecycle order — first to last

The container resolves lifecycle in dependency order:

flowchart TB
  Start([App start])
  Start --> Config[ConfigModule]
  Config --> Logger[LoggerModule]
  Logger --> Redis[TitanRedisModule]
  Logger --> Database[TitanDatabaseModule]
  Redis --> Lock[TitanLockModule]
  Redis --> Discovery[DiscoveryModule]
  Redis --> Cache[TitanCacheModule]
  Redis --> RateLimit[TitanRateLimitModule]
  Redis --> Notif[NotificationsModule]
  Database --> Health[TitanHealthModule]
  Redis --> Health
  Database --> Scheduler[TitanSchedulerModule]
  Cache --> Auth[TitanAuthModule]
  Logger --> Metrics[TitanMetricsModule]
  Metrics --> Telemetry[TelemetryRelay]
  Metrics --> User[Your services]
  Auth --> User
  Health --> Ready([App ready])
  User --> Ready

On shutdown, the reverse order is followed — user services drain first, then surface modules, then foundations, then logger / config last. The exact reverse ensures dependants always stop before their dependencies.

Picking the right tier

QuestionTier
Always available, smallest install?Built-in
Battle-tested, official, individually versioned?Official
Niche need, no official equivalent yet?Community (audit first)
Want to publish your own?Authoring a module

See also