# Durable Streams Yjs

Yjs CRDT sync over durable streams with @durable-streams/y-durable-streams.

- Repository: https://github.com/humanlayer/humanlayer (12740 stars)
- Category: Engineering
- License: Apache-2.0
- Last updated: 2026-10-31
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add humanlayer/humanlayer --skill durable-streams-yjs -g -a claude-code -y`
Codex: `npx skills add humanlayer/humanlayer --skill durable-streams-yjs -g -a codex -y`
Cursor: `npx skills add humanlayer/humanlayer --skill durable-streams-yjs -g -a cursor -y`
Gemini CLI: `npx skills add humanlayer/humanlayer --skill durable-streams-yjs -g -a gemini-cli -y`

## Description

Yjs CRDT sync over durable streams with @durable-streams/y-durable-streams. DurableStreamsProvider setup, document stream and awareness stream config, transport modes (SSE vs long-poll), provider lifecycle (connect, disconnect, destroy), synced/status/error events, lib0 VarUint8Array framing, awareness heartbeat. Requires yjs, y-protocols, lib0 peer dependencies. Load when integrating Yjs collaborative editing with durable streams.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Durable Streams, Yjs Sync

Sync Yjs documents over HTTP durable streams. No WebSocket infrastructure
needed, uses standard HTTP with SSE or long-poll transport. Built-in
persistence through stream history, presence support via awareness streams.

## Setup

```typescript
import { DurableStreamsProvider } from "@durable-streams/y-durable-streams"
import * as Y from "yjs"
import { Awareness } from "y-protocols/awareness"

const doc = new Y.Doc()
const awareness = new Awareness(doc)

const provider = new DurableStreamsProvider({
  doc,
  documentStream: {
    url: "https://your-server.com/v1/stream/doc-updates",
    transport: "sse",
  },
  awarenessStream: {
    url: "https://your-server.com/v1/stream/doc-awareness",
    protocol: awareness,
    transport: "sse",
  },
})

provider.on("synced", (synced) => {
  console.log("Synced:", synced)
})

provider.on("status", (status) => {
  console.log("Status:", status) // "disconnected" | "connecting" | "connected"
})
```

## Core Patterns

### Document-only sync (no presence)

```typescript
import { DurableStreamsProvider } from "@durable-streams/y-durable-streams"
import * as Y from "yjs"

const doc = new Y.Doc()

const provider = new DurableStreamsProvider({
  doc,
  documentStream: {
    url: "https://your-server.com/v1/stream/my-doc",
    transport: "sse",
  },
})
```

### Manual connect/disconnect

```typescript
const provider = new DurableStreamsProvider({
  doc,
  documentStream: { url, transport: "sse" },
  connect: false, // Don't auto-connect
})

// Connect when ready
provider.connect()

// Temporarily disconnect (can reconnect later)
provider.disconnect()

// Permanently destroy (cleanup all listeners and timers)
provider.destroy()
```

### Dynamic auth headers

The rest: https://github.com/humanlayer/humanlayer/blob/HEAD/.claude/skills/sync/durable-streams-yjs/SKILL.md
