A real-time live streaming service that combines Amazon IVS for video (both Low-Latency and Real-Time modes) with Stream Chat React for interactive messaging, reactions, and comments. Viewers can toggle between IVS Low-Latency playback and IVS Real-Time stage participation without leaving the page.
- Overview
- Architecture
- Prerequisites
- Step 1 — Set Up Amazon IVS
- Step 2 — Set Up Stream Chat
- Step 3 — Configure & Run the Project
- Project Structure
- How It Works
- Customization
- Troubleshooting
- Where To Go From Here
This demo app shows how to build a Twitch-style live streaming experience where:
- Video is delivered through Amazon Interactive Video Service (IVS) with two modes:
- Low-Latency — Traditional HLS playback with sub-second latency, ideal for large audiences watching a broadcast.
- Real-Time — WebRTC-based stage participation using the IVS Real-Time Broadcast SDK, enabling multi-party interactive video with ultra-low latency (~300 ms).
- Messaging is powered by Stream Chat React, providing real-time chatting with typing indicators, message status indicators (sending, received), user role configuration, emoji support (opt-in), message read indicators, threading, message replies, reactions, URL previews (send a YouTube link to see this in action), file uploads and previews, and video playback.
- A Streaming Mode Toggle in the title bar lets users switch between Low-Latency and Real-Time modes.
- A Messages UI places the chat next to the live player, with a toggle button to show/hide the chat panel.
┌──────────────────────────────────────────────────────────────────┐
│ React App (Vite) │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ IVS Player SDK │ │ IVS Real-Time │ │ Stream Chat │ │
│ │ (CDN script) │ │ Broadcast SDK │ │ React SDK │ │
│ │ │ │ (npm package) │ │ (npm package) │ │
│ │ HLS playback │ │ WebRTC stage │ │ WebSocket chat │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │ │
└───────────┼────────────────────┼─────────────────────┼────────────┘
│ │ │
▼ ▼ ▼
Amazon IVS Channel Amazon IVS Stage Stream Chat Backend
(video ingest + (real-time WebRTC (message storage,
low-latency HLS) multi-party video) real-time delivery)
Low-Latency mode — You stream to an IVS ingest endpoint (with OBS, FFmpeg, etc.) and viewers receive near-real-time HLS playback through the IVS Player SDK loaded from CDN.
Real-Time mode — Participants connect to an IVS Stage via WebRTC using the IVS Real-Time Broadcast SDK (amazon-ivs-web-broadcast npm package). Each participant shares their camera and microphone and receives streams from other participants with ultra-low latency.
Stream Chat handles the messaging pipeline — users connect via WebSocket, send messages, and receive updates in real time. The React SDK provides hooks and components for building custom chat UIs.
Before you begin, make sure you have:
| Requirement | Details |
|---|---|
| Node.js | v18 or later (download) |
| npm or Yarn | Comes with Node.js |
| AWS account | Sign up — IVS is available in the free tier |
| Stream account | Sign up — free Maker plan available |
| A streaming tool | OBS Studio, FFmpeg, or any RTMP-capable software (for Low-Latency mode) |
| HTTPS | Required for Real-Time mode (camera/microphone access). localhost works for development. |
Amazon IVS provides managed, low-latency live streaming infrastructure. Follow these steps to create a channel and get a playback URL.
- Sign in to the AWS Management Console.
- Navigate to Amazon IVS (search for "IVS" in the services search bar).
- In the left sidebar, select Channels under the Low-latency streaming section.
- Click Create channel.
- Configure the channel:
- Channel name:
live-event-demo(or any name you prefer) - Latency mode: Low-latency (recommended for interactive use cases)
- Type: Standard (sufficient for most demos)
- Recording: Leave off unless you want VOD replays
- Channel name:
- Click Create channel.
After creating the channel:
- Open the channel details page.
- Under Playback configuration, find the Playback URL — it looks like:
https://abc123def456.us-west-2.playback.live-video.net/api/video/v1/us-west-2.123456789012.channel.AbCdEfGhIjKl.m3u8 - Copy this URL — you will add it to your
.envfile in Step 3.
To start streaming, you also need:
- Ingest server:
rtmps://abc123def456.global-contribute.live-video.net:443/app/ - Stream key: Shown on the channel details page (click Show to reveal it)
Use these in OBS Studio or your preferred streaming tool.
To see the video player working without setting up OBS:
- AWS provides a test stream you can use as the playback URL:
This is a publicly available IVS demo stream. The app uses this URL by default if you don't provide one.
https://fcc3ddae59ed.us-west-2.playback.live-video.net/api/video/v1/us-west-2.893648527354.channel.DmumNckWFTqz.m3u8
Learn more: Getting Started with Amazon IVS
IVS Real-Time lets multiple participants share audio and video with ultra-low latency (~300 ms). Follow these steps to create a stage and generate a participant token.
- In the AWS Console, navigate to Amazon IVS.
- In the left sidebar, select Stages under the Real-time streaming section.
- Click Create stage.
- Give the stage a name (e.g.,
live-event-stage). - Click Create stage.
Each participant needs a token to join the stage. You can create tokens via the AWS Console or the CreateParticipantToken API.
Via the Console:
- Open your stage's detail page.
- Under Participant tokens, click Create a participant token.
- Set a User ID (e.g.,
host-user) and optional attributes. - Copy the generated token — you will add it to your
.envfile asVITE_IVS_STAGE_TOKEN.
Via the AWS CLI:
aws ivs-realtime create-participant-token \
--stage-arn arn:aws:ivs:us-west-2:123456789012:stage/AbCdEfGhIjKl \
--user-id host-user \
--capabilities '["PUBLISH","SUBSCRIBE"]'Note: Participant tokens are short-lived. For production, generate them on a backend server using the AWS SDK.
Learn more: Getting Started with IVS Real-Time Streaming | IVS Real-Time Broadcast SDK — Web
Stream Chat provides the real-time messaging backend. You need an API key, a user, and a token.
- Go to the Stream Dashboard.
- Click Create App.
- Fill in:
- App name:
live-event-chat(or any name) - Environment: Development
- App name:
- Click Create App.
- Open your newly created app from the dashboard.
- In App Settings → General, find:
- API Key (public — safe for the frontend)
- API Secret (private — keep this on the server side only; used to generate tokens)
- Copy the API Key — you will add it to your
.envfile.
Stream Chat uses JWT tokens for authentication. For development, you can generate a token using the Stream CLI or the dashboard.
- In your app dashboard, navigate to Explorer → Users.
- Click Create User.
- Set a User ID (e.g.,
demo-user) and an optional Name. - After creating the user, use the Token Generator tool in the dashboard (or the Dev Token option below).
For development, you can enable Disable Auth Checks in the dashboard:
- Go to App Settings → General.
- Toggle Disable Auth Checks to ON.
- Use the user ID as the token value (no JWT needed).
Warning: Only use this for local development. Always use proper JWT tokens in production.
Create a small script to generate a token:
// generate-token.js
const { StreamChat } = require('stream-chat');
const apiKey = 'YOUR_API_KEY';
const apiSecret = 'YOUR_API_SECRET';
const serverClient = StreamChat.getInstance(apiKey, apiSecret);
const token = serverClient.createToken('demo-user');
console.log('User Token:', token);Run it:
node generate-token.jsThe app automatically creates a livestream channel when it connects. If you want to pre-create it:
- In the dashboard, go to Explorer → Channels.
- Click Create Channel.
- Set:
- Type:
livestream - Channel ID:
livestream-chat - Add your user as a member.
- Type:
Learn more: Stream Chat React Tutorial | React SDK Docs
cd aws-ivs-stream-chat
npm installCopy the example file and fill in your credentials:
cp .env.example .envEdit .env with your values:
# Stream Chat credentials (required)
VITE_STREAM_API_KEY=your_stream_api_key
VITE_STREAM_USER_TOKEN=your_user_jwt_token
VITE_STREAM_USER_ID=demo-user
VITE_STREAM_USER_NAME=Demo User
# Stream Chat channel (optional — defaults to 'livestream-chat')
VITE_STREAM_CHANNEL_ID=livestream-chat
# AWS IVS playback URL — Low-Latency mode (optional — defaults to AWS test stream)
VITE_IVS_PLAYBACK_URL=https://your-channel.playback.live-video.net/api/video/v1/your-channel.m3u8
# AWS IVS Real-Time stage participant token — Real-Time mode (optional)
VITE_IVS_STAGE_TOKEN=your_stage_participant_tokennpm run devOpen http://localhost:5173 in your browser. You should see:
- The video player on the left (showing the IVS stream or a loading/error state).
- A streaming mode toggle in the title bar to switch between Low-Latency and Real-Time.
- The chat sidebar on the right (connected to Stream Chat).
- A Hide Chat button overlaid on the player to toggle the sidebar.
npm run build
npm run previewaws-ivs-stream-chat/
├── index.html # HTML shell — loads IVS Player SDK from CDN
├── .env.example # Template for environment variables
├── package.json # Dependencies and scripts
├── vite.config.ts # Vite configuration
├── tsconfig.json # TypeScript project references
├── tsconfig.app.json # App TypeScript config
├── public/
│ └── vite.svg # Favicon
└── src/
├── main.tsx # React entry point
├── App.tsx # Main layout — mode toggle + player/stage + chat
├── App.css # All application styles
├── index.css # Global reset and font config
├── vite-env.d.ts # Typed environment variables
├── types/
│ └── ivs.d.ts # TypeScript declarations for IVS Player CDN API
└── components/
├── IVSPlayer.tsx # Amazon IVS Low-Latency video player wrapper
├── IVSRealTime.tsx # Amazon IVS Real-Time stage (WebRTC)
└── ChatSidebar.tsx # Stream Chat message list + input (custom UI)
The title bar contains a toggle with two modes:
- Low-Latency — Renders the
IVSPlayercomponent for HLS playback. Best for large audiences watching a single broadcaster. - Real-Time — Renders the
IVSRealTimecomponent for WebRTC stage participation. Best for interactive multi-party sessions.
Switching modes swaps the video component in real time; the chat sidebar remains connected throughout.
The component loads the Amazon IVS Player from a CDN script (included in index.html). On mount it:
- Checks
window.IVSPlayerfor SDK availability and browser support. - Creates a player instance and attaches it to a
<video>element. - Loads the HLS playback URL from your IVS channel.
- Listens for
STATE_CHANGEDandERRORevents to show loading/error UI.
The component uses the amazon-ivs-web-broadcast npm package to connect participants to an IVS stage. It:
- Requests camera and microphone permissions via
getUserMedia. - Wraps local tracks in
LocalStageStreamobjects for publishing. - Creates a
Stagewith aStageStrategythat publishes local streams and subscribes to all remote participants withAUDIO_VIDEO. - Listens for stage events (
STAGE_PARTICIPANT_STREAMS_ADDED,STAGE_PARTICIPANT_LEFT, etc.) to build a participant grid. - Renders each participant's video in a responsive grid layout. Local audio is excluded from playback to prevent echo.
- Provides Join Stage and Leave Stage controls with a connection status indicator.
The app uses Stream Chat React's built-in <MessageList> and <MessageInput> components, wrapped in <Chat> and <Channel> context providers. This provides:
- Real-time message delivery via WebSocket
- Typing indicators and read receipts
- Message reactions and threading
- File uploads and URL previews
On mount, the App component:
- Creates a Stream Chat client via
new StreamChat(apiKey). - Connects the user with
chatClient.connectUser(). - Creates and watches a
livestream-type channel. - Passes the client and channel to
<Chat>and<Channel>providers. - Renders the active video component (IVSPlayer or IVSRealTime) and the chat sidebar in a flex layout.
The magenta accent (#d946ef) is used throughout the CSS for the mode toggle, buttons, and the loading spinner. To change it, update these values in src/App.css:
.mode-toggle-btn.active { background: #your-color; }
.rt-join-btn { background: #your-color; }
.loading-spinner { border-top-color: #your-color; }The app uses Stream Chat's livestream channel type by default. You can switch to messaging (which enables all members to send messages by default) by updating the channel creation in App.tsx:
const ch = chatClient.channel('messaging', CHANNEL_ID, {
name: 'Live Stream Chat',
});Stream Chat supports reactions out of the box. You can extend ChatSidebar.tsx to show reaction buttons per message using the channel.sendReaction() method.
Open the app in multiple browser tabs or windows, each with different VITE_STREAM_USER_ID and VITE_STREAM_USER_TOKEN values, to see real-time chat between users.
To test multi-party Real-Time mode:
- Create multiple participant tokens (each with a different
userId). - Open the app in separate browser tabs, each with a different
VITE_IVS_STAGE_TOKEN. - Switch to Real-Time mode and click Join Stage in each tab.
| Problem | Solution |
|---|---|
| "IVS Player SDK not loaded" | Check your internet connection — the SDK loads from player.live-video.net. Make sure ad blockers aren't blocking it. |
| "Stream unavailable" | The IVS channel is likely offline. Start streaming with OBS or use the default test stream URL. |
| "Missing Stream Chat credentials" | Create a .env file from .env.example and add your Stream API key and user token. |
| "Failed to connect to chat" | Verify your API key and user token are correct. Check the browser console for detailed errors. |
| Chat messages not appearing | Ensure the user has permission to read/write in the livestream channel. In the Stream Dashboard, check channel type permissions. |
| "Camera/microphone access denied" | Real-Time mode needs camera and mic permissions. Click the browser's permission prompt or update site settings. |
| "No stage participant token provided" | Add a valid VITE_IVS_STAGE_TOKEN to your .env file. Generate one from the AWS Console or the CreateParticipantToken API. |
| Real-Time stage not connecting | Participant tokens are short-lived. Generate a fresh one. Ensure the stage is active in the AWS Console. |
| Build warnings about chunk size | Expected — the Stream Chat SDK and IVS Real-Time SDK are large. For production, consider code splitting with dynamic imports. |
- What is Amazon IVS?
- What is IVS Real-Time Streaming?
- Getting Started with IVS Real-Time
- IVS Real-Time Broadcast SDK — Web
- IVS Player SDK — Web
- Amazon IVS Real-Time Web Demo (React)
- Amazon IVS Player Web Sample
- Built with React 19 + TypeScript + Vite
- Low-Latency Video: amazon-ivs-player v1.49.0 (CDN)
- Real-Time Video: amazon-ivs-web-broadcast v1.33.0 (npm)
- Chat: stream-chat-react v13 + stream-chat v9 (npm)
