Skip to Content
HeronJS v4 is now available.
4.0.0Services

Services

Services execute initialization tasks, recurring jobs, and long-running subscriptions outside HTTP request handlers. They run on the main thread and participate in the application lifecycle.

Lifecycle hooks

A service is started by the framework when the application boots. You define its behavior with the @Service() decorator and lifecycle hooks such as @OnStart() and @PreDestroy().

The service mode determines how the framework invokes each hook:

  • @OnStart() runs when the service starts.
  • @PreDestroy() runs before the service shuts down.
  • mode controls when and how the service executes.

Create an interval service

Use mode: 'Interval' when the service should run repeatedly on a fixed schedule.

import {Service, OnStart, PreDestroy} from '@heronjs/common'; @Service({ mode: 'Interval', options: { interval: 1000 } }) export class HeartbeatService { @OnStart() async start() { // Perform periodic work. } @PreDestroy() async destroy() { // Release owned resources. } }

This mode is useful for polling, scheduled synchronization, metrics collection, or periodic cleanup tasks.

Create a daemon service

Use mode: 'Daemon' when the service should start with the application and continue running in the background.

import {Service, OnStart, PreDestroy} from '@heronjs/common'; @Service({ mode: 'Daemon' }) export class AuditService { @OnStart() async start() { // Start the subscription or listener. } @PreDestroy() async destroy() { // Release owned resources. } }

Use this mode for listeners and subscriptions that remain active for the lifetime of the application. Use a dedicated worker service when execution must run in a separate thread.

Create an initialize service

Use mode: 'Initialize' when the service should run once during application startup.

import {Service, OnStart, OnComplete} from '@heronjs/common'; @Service({ mode: 'Initialize' }) export class BootstrapService { @OnStart() async start() { // Initialize application state. } @OnComplete() async complete() { // Finalize initialization after start() completes. } }

This is useful for tasks such as warming caches, loading configuration, seeding application state, or verifying external dependencies before the server starts accepting traffic.

Initialize services require both @OnStart() and @OnComplete(); the latter runs after initialization work completes. Daemon services require @OnStart() and @PreDestroy().

Register services

To enable services, register them in the module services array.

@Module({ services: [HeartbeatService, AuditService, BootstrapService], }) export class AppModule {}

Once registered, HeronJS will initialize the services according to their configured mode when the application starts.

Execution and cleanup

Services execute on the main thread. Finite hooks are awaited, daemon subscriptions are tracked, and interval services skip a tick while the previous invocation is active. Register services explicitly; decorators do not install global runtime instances. Await app.close() for owned cleanup.

Use Thread for dedicated worker services and CPU-bound jobs. See reactive execution for completion and cancellation rules.

Last updated on