Skip to content

RecachedCache locally. Sync everywhere.

A local-first cache and real-time sync engine, powered by Rust. Keep shared cache data in your application, read it from local memory, and sync updates across browser, mobile, and Rust clients.

Connected R and synchronized server, browser, mobile, and Rust clients

Keep shared cache data close to your application ​

Recached runs one Rust cache engine on the server, in browsers as WebAssembly, inside native Android and Apple apps, and in embedded Rust services. Your backend writes through the RESP command subset with the Redis client it already uses. Clients hold the keys they watch in local memory and receive changes over WebSocket, so a UI can render cached data without a request per read and update when the backend changes it.

Recached is a cache and synchronization engine, not a system of record. Keep MySQL or PostgreSQL as the source of truth and publish committed state into Recached. What Recached is — and isn't draws the line.

Architecture ​

Backend RESP clients connect to the Recached server on port 6379. Browser, native Android and Apple apps, and embedded Rust services sync over WebSocket on port 6380 and read local memory.Backend RESP clients connect to the Recached server on port 6379. Browser, native Android and Apple apps, and embedded Rust services sync over WebSocket on port 6380 and read local memory.
  • Browser: recached-edge runs the engine as WebAssembly, with optional IndexedDB persistence and React and Vue adapters.
  • Android and Apple: Kotlin and Swift SDKs run the engine natively through UniFFI and persist data and queued writes to SQLite.
  • Rust services: recached-embed holds a watched slice of the cache in your process's memory.
  • Recached server: executes RESP commands from your backend, persists snapshots and an optional AOF, and fans changes out to permitted clients.
  • Your database (optional): stays the source of truth. Your backend or an outbox worker publishes committed state to Recached. There is no built-in SQL connector; see database integration.

How it works covers hydration, reconnect replay, and each client's storage contract.

Hydrate, then read locally ​

Register a live query to receive initial server state and later changes:

typescript
import { createCache } from 'recached-edge'

const cache = await createCache({
  connect: { url: 'ws://localhost:6380' },
})
cache.liveQuery('inventory:*')
cache.onKeyChange('inventory:item:99', () => {
  console.log(cache.get('inventory:item:99'))
})

Reads can return a miss before the initial snapshot arrives. On mobile, call watch(pattern) to subscribe, then use Kotlin Flow or Swift AsyncStream to observe local values. How it works covers hydration and reconnect recovery.

Use cases ​

Real-time interfaces. A backend INCR on metrics:orders:today reaches every subscribed dashboard without a polling loop or a separate push endpoint. The same path carries shared carts, presence, typing indicators, and reactive UI state.

Offline-capable apps. An Android or iOS field app reopens without a network and still reads the reference data and configuration it last synced from SQLite. Writes queue locally and replay when the connection returns. Browser persistence saves local writes but not every server update; see browser persistence.

Backend services. A Rust service reads feature flags or tenant configuration from local memory on every request. A change made through the server reaches each instance, and a reconnect re-hydrates whatever the instance missed.

Use cases explains each pattern, and where Redis, Memcached, or a database is the better tool.

Choose your runtime ​

RuntimePackageStatus
Browser, React, Vuerecached-edge, @recached/react, @recached/vue on npmSync layer beta
Androiddev.recached:recached-android on Maven Central0.1.0 preview
iOS and macOSRecached via SwiftPM0.1.0 preview
Rust servicerecached-embed as a Git dependencyUnpublished
ServerDocker image, Homebrew, or cargo install --gitRelease candidate for cache workloads

Client support and limits explains API, persistence, and delivery differences. The quick start runs a server and connects a backend and a browser client.

Use a local cache without a server ​

Omit connect in the browser, or omit the URL in a mobile RecachedConfig, to keep data on the client. Browser persistence uses IndexedDB; native SDKs save to SQLite. Cross-device sync needs a server. See local-only use cases and the outbox limits.

Released under the Apache License 2.0.