Cette page est affichée en anglais. Une traduction française est en cours.
WorkflowsMay 7, 2026·3 min de lecture

Inngest Realtime — Stream Job Progress to UI in Browser

Inngest Realtime streams job logs, metadata, and step results from background functions to the browser via SSE. React hooks make progress UIs trivial.

Inngest
Inngest · Community
Prêt pour agents

Installation agent prête

Cet actif peut être installé après choix du runtime, vérification du plan et exécution de la commande adaptée.

Native · 98/100Policy : autoriser
Surface agent
Tout agent MCP/CLI
Type
Skill
Installation
Single
Confiance
Confiance : Community
Point d'entrée
Asset
Commande d'installation directe
npx -y tokrepo@latest install 175edc4b-d637-4779-86ae-6e3a296a0465 --target codex

À exécuter après confirmation du plan en dry-run.

Introduction

Inngest Realtime ships logs and intermediate results from a running job to the browser via Server-Sent Events. Combined with the React hooks, you get progress bars and live status without polling. Best for: long AI generation tasks, batch processing, anything where users wait and need to see progress. Works with: Inngest Cloud + any frontend that supports EventSource. Setup time: 5 minutes.


Publish from a job

import { inngest } from "./client";

export const generateReport = inngest.createFunction(
  { id: "generate-report" },
  { event: "report.requested" },
  async ({ event, step, publish }) => {
    await publish({ channel: `run.${event.data.runId}`, topic: "status",
      data: { stage: "fetching", percent: 10 }});

    const data = await step.run("fetch", () => fetchReportData(event.data));

    await publish({ channel: `run.${event.data.runId}`, topic: "status",
      data: { stage: "processing", percent: 50 }});

    const report = await step.run("generate", () => generateReportPDF(data));

    await publish({ channel: `run.${event.data.runId}`, topic: "status",
      data: { stage: "done", percent: 100, url: report.url }});

    return report;
  },
);

Subscribe from React

import { useInngestSubscription } from "@inngest/realtime/hooks";

function ReportProgress({ runId }: { runId: string }) {
  const { latest } = useInngestSubscription({
    channel: `run.${runId}`,
    topics: ["status"],
  });

  if (!latest) return <div>Starting…</div>;

  return (
    <div>
      <p>{latest.data.stage}</p>
      <Progress value={latest.data.percent} />
      {latest.data.url && <a href={latest.data.url}>Download report</a>}
    </div>
  );
}

Subscribe to all messages (history)

const { messages } = useInngestSubscription({ channel, topics });

// messages is a chronological array — render as a log
return (
  <ol>
    {messages.map((m, i) => (
      <li key={i}>{m.data.stage} ({m.data.percent}%)</li>
    ))}
  </ol>
);

Auth tokens (no client secrets)

The frontend uses a short-lived subscription token issued from your server. The Inngest signing key never reaches the browser.


FAQ

Q: How is Realtime different from polling? A: SSE pushes the next message the moment it's published. Polling adds latency (the polling interval) and load (request per poll). Realtime is one persistent connection with sub-second updates.

Q: Does Realtime work outside the browser? A: Yes — any HTTP client that supports SSE works. The React hooks are optional convenience; you can subscribe from Vue / Svelte / vanilla JS / a server-side EventSource.

Q: Is it included in the free tier? A: Yes — Realtime is included in all Inngest Cloud tiers, including free. Self-hosted Inngest also supports Realtime via the same API.


Quick Use

  1. npm install inngest @inngest/realtime
  2. In your function, call await publish({ channel, topic, data }) from the step context
  3. In React, useInngestSubscription({ channel, topics }) to read the stream

Intro

Inngest Realtime ships logs and intermediate results from a running job to the browser via Server-Sent Events. Combined with the React hooks, you get progress bars and live status without polling. Best for: long AI generation tasks, batch processing, anything where users wait and need to see progress. Works with: Inngest Cloud + any frontend that supports EventSource. Setup time: 5 minutes.


Publish from a job

import { inngest } from "./client";

export const generateReport = inngest.createFunction(
  { id: "generate-report" },
  { event: "report.requested" },
  async ({ event, step, publish }) => {
    await publish({ channel: `run.${event.data.runId}`, topic: "status",
      data: { stage: "fetching", percent: 10 }});

    const data = await step.run("fetch", () => fetchReportData(event.data));

    await publish({ channel: `run.${event.data.runId}`, topic: "status",
      data: { stage: "processing", percent: 50 }});

    const report = await step.run("generate", () => generateReportPDF(data));

    await publish({ channel: `run.${event.data.runId}`, topic: "status",
      data: { stage: "done", percent: 100, url: report.url }});

    return report;
  },
);

Subscribe from React

import { useInngestSubscription } from "@inngest/realtime/hooks";

function ReportProgress({ runId }: { runId: string }) {
  const { latest } = useInngestSubscription({
    channel: `run.${runId}`,
    topics: ["status"],
  });

  if (!latest) return <div>Starting…</div>;

  return (
    <div>
      <p>{latest.data.stage}</p>
      <Progress value={latest.data.percent} />
      {latest.data.url && <a href={latest.data.url}>Download report</a>}
    </div>
  );
}

Subscribe to all messages (history)

const { messages } = useInngestSubscription({ channel, topics });

// messages is a chronological array — render as a log
return (
  <ol>
    {messages.map((m, i) => (
      <li key={i}>{m.data.stage} ({m.data.percent}%)</li>
    ))}
  </ol>
);

Auth tokens (no client secrets)

The frontend uses a short-lived subscription token issued from your server. The Inngest signing key never reaches the browser.


FAQ

Q: How is Realtime different from polling? A: SSE pushes the next message the moment it's published. Polling adds latency (the polling interval) and load (request per poll). Realtime is one persistent connection with sub-second updates.

Q: Does Realtime work outside the browser? A: Yes — any HTTP client that supports SSE works. The React hooks are optional convenience; you can subscribe from Vue / Svelte / vanilla JS / a server-side EventSource.

Q: Is it included in the free tier? A: Yes — Realtime is included in all Inngest Cloud tiers, including free. Self-hosted Inngest also supports Realtime via the same API.


Source & Thanks

Built by Inngest. Licensed under Apache-2.0.

Inngest Realtime docs — Active

🙏

Source et remerciements

Built by Inngest. Licensed under Apache-2.0.

Inngest Realtime docs — Active

Fil de discussion

Connectez-vous pour rejoindre la discussion.
Aucun commentaire pour l'instant. Soyez le premier à partager votre avis.

Actifs similaires