Realtime

Quickstart

Upstash Realtime is the easiest way to add realtime features to any Next.js project.

Upstash Realtime

Why Upstash Realtime?

  • 🧨 Clean APIs & first-class TypeScript support
  • ⚑ Extremely fast, zero dependencies, 2.6kB gzipped
  • πŸ’» Deploy anywhere: Vercel, Netlify, etc.
  • πŸ’Ž 100% type-safe with zod 4 or zod mini
  • ⏱️ Built-in message histories
  • πŸ”Œ Automatic connection management w/ delivery guarantee
  • πŸ”‹ Built-in middleware and authentication helpers
  • πŸ“Ά 100% HTTP-based: Redis streams & SSE

Quickstart

1. Installation

npm
npm install @upstash/realtime @upstash/redis zod
yarn
yarn add @upstash/realtime @upstash/redis zod
pnpm
pnpm add @upstash/realtime @upstash/redis zod
bun
bun install @upstash/realtime @upstash/redis zod

2. Configure Upstash Redis

Upstash Realtime is powered by Redis Streams. Grab your credentials from the Upstash Console.

Add them to your environment variables:

.env
UPSTASH_REDIS_REST_URL=https://striking-osprey-20681.upstash.ioUPSTASH_REDIS_REST_TOKEN=AVDJAAIjcDEyZ...

And lastly, create a Redis instance:

lib/redis.ts
import { Redis } from "@upstash/redis"export const redis = new Redis({  url: process.env.UPSTASH_REDIS_REST_URL,  token: process.env.UPSTASH_REDIS_REST_TOKEN,})

3. Define Event Schema

Define the structure of realtime events in your app:

lib/realtime.ts
import { Realtime, InferRealtimeEvents } from "@upstash/realtime"import { redis } from "./redis"import z from "zod/v4"const schema = {  notification: {    alert: z.string(),  },}export const realtime = new Realtime({ schema, redis })export type RealtimeEvents = InferRealtimeEvents<typeof realtime>

4. Create Realtime Route Handler

Create a route handler at api/realtime/route.ts:

app/api/realtime/route.ts
import { handle } from "@upstash/realtime"import { realtime } from "@/lib/realtime"export const GET = handle({ realtime })

5. Add the Provider

Wrap your application in RealtimeProvider:

app/providers.tsx
"use client"import { RealtimeProvider } from "@upstash/realtime/client"export function Providers({ children }: { children: React.ReactNode }) {  return <RealtimeProvider>{children}</RealtimeProvider>}
app/layout.tsx
import { Providers } from "./providers"export default function RootLayout({ children }: { children: React.ReactNode }) {  return (    <html>      <body>        <Providers>{children}</Providers>      </body>    </html>  )}

6. Create Typed Client Hook

Create a typed useRealtime hook for your client components:

lib/realtime-client.ts
"use client"import { createRealtime } from "@upstash/realtime/client"import type { RealtimeEvents } from "./realtime"export const { useRealtime } = createRealtime<RealtimeEvents>()

7. Emit Events

From any server component, server action, or API route:

app/api/notify/route.ts
import { realtime } from "@/lib/realtime"export const POST = async () => {  await realtime.emit("notification.alert", "hello world!")  return new Response("OK")}

8. Subscribe to Events

In any client component:

app/components/notifications.tsx
"use client"import { useRealtime } from "@/lib/realtime-client"export default function Notifications() {  useRealtime({    events: ["notification.alert"],    onData({ event, data, channel }) {      console.log(`Received ${event}:`, data)    },  })  return <p>Listening for events...</p>}

That's it! Your app is now listening for realtime events with full type safety. πŸŽ‰

9. Realtime Dashboard

For debugging or monitoring purposes, you can use Realtime Dashboard in console.

Next Steps

Loading search…