@talosjs/service component is the service layer foundation for Talos applications. A service is an injectable unit of business logic, such as order processing, payment handling, or email dispatch, that you register with a decorator and resolve from the container. Each service implements the IService interface, exposing a single execute(data?) entry point, and is wired into @talosjs/container so dependencies resolve on their own.
What a service is for
Services hold the domain operations that you’d otherwise scatter through controllers and routes, which keeps controllers thin and delegating. Register one with@decorator.service() and resolve it anywhere with container.get(), with no manual wiring. Because every service implements IService, they share the same execute(data?) shape and compose predictably, with one service resolving and calling another to build a larger operation from smaller units. Each service picks its own scope, singleton, transient, or request, to match its lifecycle.
How it works
A service is a plain class decorated with@decorator.service(). The decorator calls container.add(target, scope), registering the class with @talosjs/container. From then on, container.get(MyService) returns an instance with its scope honored: the container constructs it, caches it (for singletons), and resolves any container-backed dependencies it pulls in.
The IService contract is intentionally minimal:
EContainerScope:
Decorator and usage
@decorator.service(scope?)
Registers a service class with the container. It takes an optional scope (defaults to EContainerScope.Singleton) and returns a class decorator that adds the target to the container.
Designing services
Give each service a single business operation, and compose services rather than letting one grow into a god class. Keepexecute() as the public entry point: put the orchestration there and break the steps into private methods. Replace the default Record<string, unknown> data shape with a precise interface for the service’s input, and since data is optional, guard for undefined before you use it.
Get services from the container with container.get() so scopes and dependencies are honored, and avoid new. Default to singleton scope for stateless logic, reaching for transient or request scope only when per-call or per-request state actually matters. Keep routing and HTTP concerns in controllers and let the services do the work.
CLI command
Scaffold a service class and its test file with the generator. It writes the class undermodules/<module>/src/services/<Name>Service.ts, adds a matching test, and installs @talosjs/service if it is missing.
The generated class is a ready-to-fill
IService stub:
Use with Claude and Codex
The generator ships a matchingservice:create skill. It runs the scaffold, then guides your AI agent through completing the service: defining a real ServiceDataType, implementing execute() with the business logic, and injecting dependencies. Initialize the skills once for your agent.
- Claude
- Codex
Prompt
service:create --name=Invoice, then implements execute() to compute the totals.