Realtime sync for any backend stack

 

Replicache makes it easy to add realtime collaboration, lag-free UI, and offline support to web apps. It works with any backend stack.

 

Benefits

Realtime Multiplayer Collaboration. Popularized by Google Docs, Figma, and Notion — realtime collaboration is awesome, but famously hard to build. Replicache provides a programming model that makes it much easier.

Bring Your Own Backend. Replicache is entirely client-side technology, and works with any standard web service backend. Your data stays on your servers.

Lag-Free UI. By executing all reads and writes against a local cache, apps built with Replicache respond instantly, without waiting for the server. It even works if the app is…

Offline. Replicache persists its cache to client-side storage, so apps boot and render instantly. Online, offline, or anything in between.

Transactional Conflict Resolution. Conflicts are a fact of life when syncing, but they don't have to be exceptionally painful. Replicache rewinds and replays your transactions during sync, sort of like git rebase for application state. It's the easiest way to deal with conflicts that is…

Correct. Replicache was designed in consultation with indepedent distributed systems expert Kyle Kingsbury of Jepsen. When properly integrated with your backend, Replicache provides Causal+ Consistency — one of the strongest consistency models possible in a synchronizing system. See the Replicache Design Document or Jepsen's summary for more information.

How it Works

Overview

Replicache provides fast key/value storage to web apps, along with a protocol to synchronize that storage with your web service and resolve conflicts.

Render your UI directly from Replicache, and write changes right back to it — as if your app only had local storage. Replicache uses a Git-inspired protocol to sync continuously in the background.

①  Pull

POST /replicache-client-view HTTP/2
Host: myservice.com
Authorization: Bearer 51857000befac83d338df7661d00d81011d7fb10

{
  "clientID": "d1570b3a",
  "cookie": "",
}
HTTP/2 200
Content-Type: application/json

{
  "lastMutationID": 6,
  "cookie": "eae66b62",
  "patch": [
    {
      "op": "add",
      "path": "/todo/39B224C1-1DBE-48D2-B89D-1DC4BA9821AA",
      "value": {
        "text": "Take out the garbage",
        "complete": false
      }
    },
    {
      "op": "add",
      "path": "/todo/77173E44-C620-429C-9CD1-16548D58A94A",
      "value": {
        "text": "Walk the dog",
        "complete": true
      }
    }
  }
}

The set of key/value pairs stored in Replicache is called the Client View.

Replicache pulls updates to the Client View from the /replicache-client-state endpoint on your server. Return a delta from the previous returned version in JSON Patch format.

You can control the extent of pulled data by parameterizing the client view URL, or even prioritize by sending multiple pull requests.

②  Subscribe

const todos = useSubscribe(
    replicache,
    tx => tx.scanAll({prefix: '/todo/'}));

return <ul>{
  todos.map(t => <li>{t.title}</li>)
}</ul>;
replicache.subscribe(
  async (tx) => await tx.scanAll({prefix: '/todo/'}),
  {
    onData: (todos) => {
      this.setState({ todos });
    },
  }
);

Easily build realtime applications using subscribe(). Whenever the data in Replicache changes — either due to remote or local changes — the affected views refresh automatically and consistently.

③  Optimistic Mutate

const createTodo = replicache.register(
  "create-todo",
  async (tx, {id, text, complete}) => {
    await tx.put(`/todo/${id}`, { text, complete });
  }
);
await createTodo(
  id: uuid(),
  text: this.state.todoText,
  complete: false,
});

To make changes on the client, register a mutator.

Replicache executes the mutator immediately against the local cache. Subscriptions re-fire, and views are instantly updated with the pending change.

It doesn't matter if the mutator computes the same result as server later will — Replicache guarantees the local mutation will be undone once the server result is known.

④  Push

POST /replicache-batch HTTP/2
Host: myservice.com

{
  "clientID": "CB94867E-94B7-48F3-A3C1-287871E1F7FD",
  "mutations": [
    {
      "id": 7,
      "name": "createTodo",
      "args": {
        "id": "AE2E880D-C4BD-473A-B5E0-29A4A9965EE9",
        "title": "Fix the car",
        "complete": false
      }
    },
    {
      "id": 8,
      "name": "toggleComplete",
      "args": {
        "id": "5C2F21E8-A9CC-4DA8-91D6-97D2D1F7CECF",
        "done": true
      }
    }
  ]
}
HTTP/2 200 

Batches of pending write transactions are sent to the /replicache-batch endpoint on your service as connectivity allows. These requests are delayed, but otherwise normal. Your service defensively checks for conflicts, and ignores, modifies, or rejects the request.

⑤, ⑥  Poke, Incremental Pull

After processing a mutation on your server, send a WebSocket "poke" (a message with no payload) telling affected users' devices to sync again.

⑦  Rebase

Replicache rewinds the cache to the point before sync started, applies the incremental pull, and then replays any remaining unacknowledged changes on top.

The final state is revealed to the UI atomically, subscriptions re-fire, and the UI refreshes.

Price

Replicache is free for any amount of non-commercial use. For commercial use:

🛹🚴🏽‍♀️🏎🚀
MAC< 500< 10k< 100k100k - ∞
PriceFree$500/mo$2,500/mo$5,000/mo
SupportSharedDedicatedDedicatedDedicated

Fine Print

  • A MAC is a Monthly Active Client. For example, if a user runs your application on their phone, tablet, and on Firefox and Chrome on their computer, that would be four clients.

Get Started Now

Start with Replicache right now for free. Only pay once you have over 500 clients.

What People are Saying