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

Cet actif peut être lu et installé directement par les agents

TokRepo expose une commande CLI universelle, un contrat d'installation, le metadata JSON, un plan selon l'adaptateur et le contenu raw pour aider les agents à juger l'adaptation, le risque et les prochaines actions.

Native · 98/100Policy : autoriser
Surface agent
Tout agent MCP/CLI
Type
Skill
Installation
Single
Confiance
Confiance : New
Point d'entrée
Asset
Commande CLI universelle
npx tokrepo install 175edc4b-d637-4779-86ae-6e3a296a0465
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