Local reads without a network hop
The browser WASM module holds a live copy of the cache in local memory. Reads never leave the browser — no network hop, no round-trip.
A Redis-compatible server. WebAssembly in the browser. Local reads without a network hop.

Every caching solution forces a choice: server-side caches like Redis mean every frontend read is a network round-trip; client-side state like Zustand or SWR means two caches — one on the server and one in every client, with manual staleness code gluing them together. Recached removes the choice.
The same Rust cache engine runs natively on your server (RESP on port 6379) and as WebAssembly inside the browser. Common Redis clients work with the commands Recached implements. Browser reads come from local WASM memory; the WebSocket is a sync path, not a read path.
import { createCache } from 'recached-edge'
const cache = await createCache({
persistence: true, // survives page refresh via IndexedDB
connect: { url: 'ws://localhost:6380' }, // syncs with the server
})
cache.get('inventory:item:99') // "42" — local WASM memory, no network request
// React to any store mutation — local writes, server push, or cross-tab sync
cache.onMutation(() => {
document.body.dataset.theme = cache.get('user:theme') ?? 'light'
})No polling. No extra state management library. No round-trips for reads. The server is your backend's cache; the WASM module is your frontend's cache; the WebSocket is the invisible sync layer between them.
The sync layer is optional. Omit connect and no socket is opened: recached-edge becomes a standalone client cache — TTLs, counters, JSON documents, glob queries, IndexedDB persistence and cross-tab sync — with no Recached server anywhere and no changes to your backend.
const cache = await createCache({ persistence: true, broadcastChannel: 'my-app' })
cache.setJSON('user:42', user, 60) // expires on its own, survives a refreshPub/sub, live queries and cross-device sync are the parts that need a server. See no server at all.