Skip to content

add v4 internal realtime docs#1451

Merged
jacobheric merged 15 commits intomainfrom
jacob/v4-realtime
Mar 25, 2026
Merged

add v4 internal realtime docs#1451
jacobheric merged 15 commits intomainfrom
jacob/v4-realtime

Conversation

@jacobheric
Copy link
Copy Markdown
Contributor

@jacobheric jacobheric commented Mar 4, 2026

Built on top of the new v4 docs. Move the v3 docs to the old v3 reference area and marked those a deprecated.

The new default v4 realtime docs also contain a ref to the old v3 docs and vice versa:

Screenshot 2026-03-16 at 1 25 46 PM Screenshot 2026-03-16 at 1 26 02 PM

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment Mar 25, 2026 1:56pm

Request Review

@jacobheric jacobheric changed the base branch from main to v4-is-stable March 16, 2026 17:23
Base automatically changed from v4-is-stable to main March 16, 2026 18:55
jacobheric added a commit to inngest/inngest-js that referenced this pull request Mar 25, 2026
## Summary

Introduces the new **first-class realtime implementation** in
`packages/inngest` with a simpler DX, while keeping `@inngest/realtime`
deprecated during the transition.

- **Spec:**
https://www.notion.so/inngest/Realtime-SDK-DX-Improvements-305b64753bbd80a5a0bfff2000f4a9d7
- **Docs PR:** inngest/website#1451
- **Examples using the new implementation:**
#1367

---

## PR Feedback Update

### 1. Move non-durable publish to the client API

- **Non-durable publish** is now client-level: `inngest.publish(ref,
data)`
- **Durable publish** remains step-level: `step.realtime.publish(id,
ref, data)`

```ts
// Non-durable
await inngest.publish(chat.status, { message: "Streaming..." });

// Durable
await step.realtime.publish("final-status", chat.status, { message: "Done" });
```

### 2. Runtime validation on both sides

- **Publish-time validation**
  - Runs when a topic schema exists.
  - Applies to both `inngest.publish` and `step.realtime.publish`.

- **Subscribe-time validation**
  - Runs client-side when a schema exists.
  - `validate` option is supported (default: `true`).
```ts
const stream = await inngest.realtime.subscribe({
  channel: chat,
  topics: ["status"],
  validate: true,
});
```

**Validation example:**  

https://github.com/inngest/inngest-js/pull/1367/changes#diff-8dbca5b6232bb4bc72c74fe8309bfd4cf5ecfc3b2f04a76f7bad473c151231aa

### 3. Typing model on client subscriptions

- **Fully typed payload inference** requires subscribing with the shared
channel object/instance.
- **String-only channel/topic subscriptions** are still supported, but
payload typing will be generic/untyped.
```ts
const topics = ["status", "tokens"] as const;
const { messages } = useRealtime({
  channel: contentPipeline({ runId }),
  topics,
  token: tokenFactory,
});

// Per-topic typed access
messages.byTopic.status?.data.message; // string

// Union narrowing by topic
for (const msg of messages.delta) {
  if (msg.kind === "run") continue;
  if (msg.topic === "tokens") {
    msg.data.token; // string
  }
}
```

### 4. `useRealtime` naming clarity

Went a bit off script here. Trying to make auto-complete nice while
preserving some convenience stuff for the ui. I can totally flatten this
back out and remove the last/delta stuff if you think that's
distracting.

Replaced ambiguous fields with a **message-first shape**:
```ts
const { messages } = useRealtime(...);

messages.byTopic.status?.data; // core map by topic
messages.all; // core bounded
messages.last; // convenience (single most resent message across all topics)
messages.delta; // convenience (since last flush/render window)
```

**Examples with additional debug/context:**  

https://github.com/inngest/inngest-js/pull/1367/changes#diff-da7df91f25f2f6fdc35936aab88cf18e4a10173b6a86585f198349066cab74b5

---

## Checklist

<!-- Tick these items off as you progress. -->
<!-- If an item isn't applicable, strike it out and explain why. -->
<!-- Example: - [ ] ~~Added tests~~ N/A Only touches docs -->

- [x] Added a [docs PR](https://github.com/inngest/website) that
references this PR
- [x] Added unit/integration tests
- [x] Added changesets if applicable

---

## Related

- EXE-1377

<!-- MENDRAL_SUMMARY -->
---

> [!NOTE]
> Integrates first-class realtime support into the core `inngest`
package, migrating from the separate `@inngest/realtime` package. Adds
typed channels/topics with Standard Schema validation,
`inngest.realtime.publish()` for non-durable publishing,
`step.realtime.publish()` for durable step publishing, server-side
`inngest.realtime.subscribe()` and `inngest.realtime.token()`, and a
`useRealtime` React hook. The `@inngest/realtime` package is kept but
deprecated. Examples are updated to use the new built-in API.
> 
> <sup>Written by [Mendral](https://mendral.com) for commit
84c1217.</sup>
<!-- /MENDRAL_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jack Williams <jack@inngest.com>
* update realtime example to use latest
@jacobheric jacobheric merged commit 1e2febb into main Mar 25, 2026
7 of 8 checks passed
@jacobheric jacobheric deleted the jacob/v4-realtime branch March 25, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants