I cut 40% of my NgRx Signal Store boilerplate — here’s the 5 utilities I extracted
Every Signal Store in our monorepo started the same way. Fifty-plus lines of ceremony before a single line of business logic. Loading…
I cut 40% of my NgRx Signal Store boilerplate — here’s the 5 utilities I extracted

Every Signal Store in our monorepo started the same way. Fifty-plus lines of ceremony before a single line of business logic. Loading flags, error messages, pagination math, search pipes, entity sync — all copy-pasted from the last store with minor tweaks. Twenty stores later, I had twenty copies of the same patterns drifting apart.
So I extracted them. Five composable signalStoreFeature utilities, each replacing a chunk of repetitive code with a single function call. The result is signalstore-toolkit.
The problem: stores that are 60% scaffolding
Here is a stripped-down version of what a typical store looked like before. This handles one entity with loading state, error handling, and pagination:
That is around 35 lines of infrastructure and maybe 0 lines of actual domain logic. Every new store repeated this. Every one was slightly different in the ways that cause bugs.
The fix: five composable features
withRequestStatus — the hero cut
This was the biggest win. Every store had its own isLoading, isError, errorMessage triple, its own setPending/ setFulfilled/ setError methods. withRequestStatus() replaces all of it:
// Before: 15 lines of state + methods per store // After: withRequestStatus ()
One line. You get requestStatus, isPending, isFulfilled, error, setPending, setFulfilled, setError, and resetStatus - all typed, all consistent across every store.
withEntitySync — real-time entity reconciliation
If you work with live data — WebSocket updates, polling, server-sent events — you need to reconcile incoming entities with what is already in the store. withEntitySync() gives you syncAll, upsertOne, liveUpdate (parses JSON and upserts), and removeOne:
The liveUpdate method is particularly useful. Point it at a WebSocket message and it handles JSON parsing and entity upsert in one call.
withPagination — no more page math
Page offset calculations, hasNextPage guards, total page derivation - all computed, all reactive:
withPagination () // Gives you: currentPage, pageSize, total, totalPages, // hasNextPage, hasPreviousPage, pageOffset, // setPage, nextPage, previousPage, setPageSize, setPageResult
createApiMethod — factory for rxMethod + loading state
This is not a store feature but a factory function. It wires up rxMethod with tapResponse, manages loading/error state on the store, and validates the API response shape. You configure the operator ( switchMap for reads, concatMap for writes):
That replaces roughly 30 lines of rxMethod + pipe + tapResponse + manual setPending/ setFulfilled/ setError wiring per API call.
withSearchFilter — declarative search + sort
Composes after withEntities(). You declare which fields to search and how to sort:
The composed store
Here is the same product store from above, rebuilt with all five utilities:
All the infrastructure is handled. What remains is the domain-specific wiring: which API to call, what to do with the response. That is it.
How it compares to @angular-architects/ngrx-toolkit
The two libraries are complementary, not competing. @angular-architects/ngrx-toolkit focuses on DevTools integration, undo/redo, Redux connector, and data service patterns. signalstore-toolkit focuses on per-operation status tracking, entity live-update reconciliation, the API method factory with app-level response checking, and search/filter pipelines. There is no overlap - you can use both in the same store.
Install
npm install signalstore-toolkit
Peer deps: Angular 17+, @ngrx/signals 17+, RxJS 7+. The @ngrx/operators package is optional and only needed if you use createApiMethod.
These patterns were extracted from a production Angular monorepo running 20+ Signal Stores with gRPC-web as the transport layer. They have been stable in production for months.
npm: signalstore-toolkit GitHub: harsh04/signalstore-toolkit
Feedback welcome.
Originally published at https://dev.to on April 12, 2026.
메타데이터
- post_id
- 7d00545ec982
- slug
- i-cut-40-of-my-ngrx-signal-store-boilerplate-heres-the-5-utilities-i-extracted-7d00545ec982
- url
- https://medium.com/@harshmathur.04/i-cut-40-of-my-ngrx-signal-store-boilerplate-heres-the-5-utilities-i-extracted-7d00545ec982
- canonical_url
- https://medium.com/@harshmathur.04/i-cut-40-of-my-ngrx-signal-store-boilerplate-heres-the-5-utilities-i-extracted-7d00545ec982
- author_url
- https://medium.com/@harshmathur.04
- status
- ok
- fetched_at
- 2026-06-20 20:29:01