A monorepo containing Angular router state management packages that provide strictly typed, lightweight alternatives to NgRx Router Store (@ngrx/router-store
) and ActivatedRoute
.
This repository contains two main packages:
A Component Store-based solution using observables:
- Package:
@ngworker/router-component-store
- Technology: NgRx Component Store (
@ngrx/component-store
) with RxJS observables - Use Case: When you prefer observable-based reactivity patterns
// Observable-based API
export class HeroService {
#routerStore = inject(RouterStore);
url$ = this.#routerStore.url$; // Observable<string>
searchTerm$ = this.#routerStore.selectQueryParam('q'); // Observable<string | undefined>
}
A Signal Store-based solution using Angular Signals:
- Package:
@ngworker/router-signal-store
- Technology: NgRx Signals (
@ngrx/signals
) with Angular Signals - Use Case: When you prefer signal-based reactivity patterns
// Signal-based API
export class HeroService {
#routerSignalStore = inject(RouterSignalStore);
url = this.#routerSignalStore.url; // Signal<string>
searchTerm = this.#routerSignalStore.selectQueryParam('q'); // Signal<string | undefined>
}
Both packages provide:
✅ Strictly Typed: Full TypeScript support with strict typing
✅ Lightweight: Minimal bundle size impact
✅ Drop-in Replacement: For NgRx Router Store and ActivatedRoute
✅ Global & Local Stores: Application-wide and component-level usage
✅ Immutable State: Router state is immutable and serializable
✅ Memory Safe: Proper subscription management and cleanup
Both packages follow Angular's recommended release pattern for Angular libraries. One major package version for every major Angular release.
Features released in minor versions of Angular and NgRx packages are not used until the following major version package release to ensure compatibility across minor versions.
The packages require the same peer dependencies as their corresponding Angular and NgRx packages.
npm install @ngworker/router-component-store
import { provideGlobalRouterStore } from '@ngworker/router-component-store';
bootstrapApplication(AppComponent, {
providers: [provideGlobalRouterStore()],
});
npm install @ngworker/router-signal-store
import { provideGlobalRouterSignalStore } from '@ngworker/router-signal-store';
bootstrapApplication(AppComponent, {
providers: [provideGlobalRouterSignalStore()],
});
Feature | Router Component Store | Router Signal Store |
---|---|---|
Current Route | currentRoute$: Observable<...> |
currentRoute: Signal<...> |
Query Parameters | queryParams$: Observable<...> |
queryParams: Signal<...> |
Route Parameters | routeParams$: Observable<...> |
routeParams: Signal<...> |
Route Data | routeData$: Observable<...> |
routeData: Signal<...> |
URL | url$: Observable<string> |
url: Signal<string> |
Fragment | fragment$: Observable<...> |
fragment: Signal<...> |
Title | title$: Observable<...> |
title: Signal<...> |
Router events | selectRouterEvents(...): Observable<...> |
Not included to avoid an RxJS dependency |
Both packages support global router stores for application-wide router state access:
// Component Store
@Injectable({ providedIn: 'root' })
export class NavigationService {
#routerStore = inject(RouterStore);
currentPath$ = this.#routerStore.url$;
}
// Signal Store
@Injectable({ providedIn: 'root' })
export class NavigationService {
#routerSignalStore = inject(RouterSignalStore);
currentPath = this.#routerSignalStore.url;
}
Both packages support local router stores for component-specific router state:
// Component Store
@Component({
providers: [provideLocalRouterStore()],
})
export class ProductComponent {
#routerStore = inject(RouterStore);
productId$ = this.#routerStore.selectRouteParam('id');
}
// Signal Store
@Component({
providers: [provideLocalRouterSignalStore()],
})
export class ProductComponent {
#routerStore = inject(RouterSignalStore);
productId = this.#routerStore.selectRouteParam('id');
}
This repository uses:
- Nx for monorepo, task, and CI management
- Angular, RxJS, and NgRx
- TypeScript
- Jest for testing
- Prettier and ESLint for code quality
# Install dependencies
yarn install
# Run tests
yarn test
# Run linting
yarn lint
# Build packages
yarn build
# Perform dead code analysis
yarn knip
# Run all CI checks
yarn ci
# Check formatting
yarn format:check
# Format code
yarn format
Contributions are welcome! Submit pull requests to the main branch.
MIT © ngworkers