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 |
Framework
| Plugin | Package | Description |
|---|---|---|
| Next.js | @spoosh/plugin-nextjs | Server-side cache revalidation |
Development
| Plugin | Package | Description |
|---|---|---|
| Devtool | @spoosh/devtool | Visual debugging panel with tracing |
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";
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
cachePlugin({ staleTime: 5000 }),
deduplicationPlugin(),
invalidationPlugin(),
]);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
Plugin Execution Order
Plugins are executed based on their priority value, not their registration order. This means you can register plugins in any order you like.
- Lower priority runs first (e.g.,
cachePluginwith priority -10) - Higher priority runs last (e.g.,
throttlePluginwith priority 100) - Default priority is 0 (most plugins)
Key plugins with non-default priorities:
cachePlugin(priority: -10) - Runs early to check cache before other pluginsthrottlePlugin(priority: 100) - Runs last to block all requests including force fetches
// These produce the same execution order:
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
throttlePlugin(), // priority: 100 (runs last)
retryPlugin(), // priority: 0 (default)
cachePlugin({ staleTime: 5000 }), // priority: -10 (runs first)
]);
// Same as:
const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
cachePlugin({ staleTime: 5000 }), // priority: -10 (runs first)
retryPlugin(), // priority: 0 (default)
throttlePlugin(), // priority: 100 (runs last)
]);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
useRead((api) => api("users").GET(), { staleTime: 60000 });
// Disable retries for this query
useRead((api) => api("health").GET(), {
retry: { retries: false },
});
// Custom polling interval
useRead((api) => api("notifications").GET(), { pollingInterval: 5000 });