NgxPersist is a type-safe, signal-based persistent state primitive for Angular 19+.
It syncs your state with localStorage, sessionStorage, IndexedDB, or any custom backend, providing a seamless developer experience.
- 🚀 Signal-based: Built for Angular Signals.
- 🔄 Cross-Tab Sync: Automatically syncs state across tabs using
BroadcastChannel. - 📦 Pluggable Adapters:
localStorage,sessionStorage,memory, and custom adapters. - 🔗 Linked Signals: Persist state that depends on other signals.
- 🌐 Resource API: Offline-first data fetching with
persistResource. - 🏪 NGRX Integration: Seamless
SignalStorepersistence.
npm install ngx-persistAdd provideNgxPersist to your app.config.ts.
import { provideNgxPersist } from 'ngx-persist';
export const appConfig = {
providers: [
provideNgxPersist({
namespace: 'my-app' // Prefixes all keys to avoid collisions
})
]
};Create a signal that automatically saves to localStorage.
import { storageSignal } from 'ngx-persist';
@Component({ ... })
export class SettingsComponent {
// Stored as 'my-app:theme'
theme = storageSignal({
key: 'theme',
initial: 'light'
});
toggle() {
this.theme.update(t => t === 'light' ? 'dark' : 'light');
}
}Use IndexedDB or other async storage. The loaded signal tells you when data is ready.
const largeData = storageSignal({
key: 'large-dataset',
initial: [],
adapter: indexedDbAdapter // or any custom StorageAdapter
});
// Check if hydrated
if (largeData.loaded()) {
console.log(largeData());
}Persist state that resets when a dependency changes (e.g., form drafts per user).
const userId = input.required<string>();
const draft = storageLinkedSignal({
key: (id) => `draft_${id}`, // Unique key per user
source: userId,
computation: () => '' // Reset value when user changes
});Add offline-first caching to Angular's resource API.
const userResource = resource({
loader: persistResource(fetchUser, {
key: (params) => `user_${params.id}`,
adapter: localStorageAdapter
})
});Persist your SignalStore state with a single line.
export const UserStore = signalStore(
withState({ name: 'Guest' }),
withPersist({ key: 'user-store' })
);MIT
