Plugins
Plugin System
Extend Spoosh with powerful plugins
Plugins are the heart of Spoosh. They extend the core functionality with features like caching, automatic retries, cache invalidation, and optimistic updates.
Installing Plugins
Each plugin is a separate package:
npm install @spoosh/plugin-cache @spoosh/plugin-invalidation @spoosh/plugin-retryUsing Plugins
Add plugins using the .use() method:
import { Spoosh } from "@spoosh/core";
import { cachePlugin } from "@spoosh/plugin-cache";
import { invalidationPlugin } from "@spoosh/plugin-invalidation";
import { retryPlugin } from "@spoosh/plugin-retry";
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
cachePlugin({ staleTime: 5000 }),
invalidationPlugin(), // Auto-refresh queries after mutations
retryPlugin({ retries: 3 }),
]);Available Plugins
Essential
| Plugin | Package | Description |
|---|---|---|
| Cache | @spoosh/plugin-cache | Response caching with configurable stale time |
| Invalidation | @spoosh/plugin-invalidation | Auto-invalidate queries after mutations |
| Deduplication | @spoosh/plugin-deduplication | Prevent duplicate concurrent requests |
Data Management
| Plugin | Package | Description |
|---|---|---|
| Optimistic | @spoosh/plugin-optimistic | Instant UI updates with automatic rollback |
| Initial Data | @spoosh/plugin-initial-data | Provide initial data for queries |
| Prefetch | @spoosh/plugin-prefetch | Preload data before it's needed |
| GC | @spoosh/plugin-gc | Garbage collection for cache management |
Request Control
| Plugin | Package | Description |
|---|---|---|
| Retry | @spoosh/plugin-retry | Automatic retry on failure |
| Polling | @spoosh/plugin-polling | Automatic periodic refetching |
| Refetch | @spoosh/plugin-refetch | Refetch on window focus/network reconnect |
| Debounce | @spoosh/plugin-debounce | Delay requests until input stops changing |
| Throttle | @spoosh/plugin-throttle | Limit request frequency |
| Progress | @spoosh/plugin-progress | Upload/download progress via XHR |
Data Transformation
| Plugin | Package | Description |
|---|---|---|
| QS | @spoosh/plugin-qs | Nested object serialization for query params |
| Transform | @spoosh/plugin-transform | Transform response data |
Development
| Plugin | Package | Description |
|---|---|---|
| Debug | @spoosh/plugin-debug | Development logging |
Recommended Setup
For most applications, we recommend this plugin combination:
import { Spoosh } from "@spoosh/core";
import { cachePlugin } from "@spoosh/plugin-cache";
import { invalidationPlugin } from "@spoosh/plugin-invalidation";
import { deduplicationPlugin } from "@spoosh/plugin-deduplication";
import { retryPlugin } from "@spoosh/plugin-retry";
import { refetchPlugin } from "@spoosh/plugin-refetch";
const client = new Spoosh<ApiSchema, Error>("/api").use([
cachePlugin({ staleTime: 5000 }),
deduplicationPlugin(),
invalidationPlugin(),
retryPlugin({ retries: 3 }),
refetchPlugin({ refetchOnFocus: true }),
]);This gives you:
- Caching - Avoid redundant network requests
- Deduplication - Prevent duplicate requests when multiple queries invalidate at once
- Auto-invalidation - Queries refresh automatically after mutations
- Retry - Automatic recovery from transient failures
- Refetch - Fresh data when users return to your app
Plugin Order
Most plugins work in any order. The exceptions are:
cachePlugin- should be registered early to check cache before making requeststhrottlePlugin- should be registered last to block all requests including force fetches
const client = new Spoosh<ApiSchema, Error>("/api").use([
cachePlugin({ staleTime: 5000 }), // Early - check cache first
deduplicationPlugin(),
invalidationPlugin(),
retryPlugin(),
throttlePlugin(), // Last - blocks everything
]);Tip: The
deduplicationPluginis especially useful withinvalidationPlugin. When a mutation invalidates multiple queries with overlapping tags, deduplication ensures only one network request is made per unique endpoint.
Per-Request Options
Most plugins support per-request overrides:
// Override cache time for this query
injectRead((api) => api("users").GET(), { staleTime: 60000 });
// Disable retries for this query
injectRead((api) => api("health").GET(), { retries: false });
// Custom polling interval
injectRead((api) => api("notifications").GET(), { pollingInterval: 5000 });