Skip to content

services & inject

A service is a cross-cutting dependency — an API client, an analytics tracker, a logger. Services are acquired with inject service.

inject service analytics

The inject keyword always takes a kind qualifierinject store or inject service. A bare inject X is an error (SVC015): the qualifier names what you’re acquiring.

export service AnalyticsService {
action track(event: string, props?: Record<string, unknown>) {
// …send the event
}
}
Compiled React 19 — this is the file in your repo
import { ServiceRegistry, createServiceInstance } from "@reactra/service"
export const AnalyticsService = {
name: "AnalyticsService",
factory: () => createServiceInstance(() => {
const track = (event: string, props?: Record<string, unknown>) => { // …send the event
}
return { track }
}),
}
if (import.meta.hot) {
import.meta.hot.accept((newMod) => {
if (!newMod) return
ServiceRegistry.replace(newMod.AnalyticsService)
})
}

Services are registered at boot via configureServices (the generated manifest wires this up). Unlike stores, services don’t auto-register — you provide their implementation explicitly, which makes them straightforward to swap in tests.

Because the implementation is injected, you can provide a fake in a test without touching the component:

inject service analytics // real in the app, a stub in tests
action save() { analytics.track("saved") }

This keeps components testable and side-effects explicit.

Next: routing.