Skip to content
Agentmart
Submit a tool

stream-flutter

Build and integrate Stream Chat, Video, and Feeds in Flutter apps.

Skill by GetStream

IndexedApache-2.0★ 20
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/getstream-stream-flutter

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Build and integrate Stream Chat, Video, and Feeds in Flutter apps. Use for Flutter/Dart project work with Stream package setup, auth wiring, and widget blueprints. Supports stream_chat_flutter (pre-built Chat UI), stream_chat_flutter_core (custom Chat UI), stream_video_flutter (Video calling and livestreaming), and stream_feed / stream_feed_flutter_core (Activity Feeds, no pre-built UI). Also migrates Flutter apps from the Sendbird Chat SDK (sendbird_chat_sdk / sendbird_uikit) to Stream Chat.

Use cases: design, security

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/stream-flutter

Tools it pre-approves 30

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Read,
  • Write,
  • Edit,
  • Glob,
  • Grep,
  • Bash(ls
  • *),
  • Bash(grep
  • Bash(find
  • .
  • Bash(cat
  • pubspec.yaml),
Show 18 more
  • pubspec.lock),
  • Bash(flutter
  • pub
  • create
  • run
  • analyze
  • analyze),
  • build
  • devices),
  • emulators
  • emulators),
  • Bash(getstream
  • token
  • env
  • api
  • login
  • init
  • *)

What's inside

Skill name
stream-flutter
Description
Build and integrate Stream Chat, Video, and Feeds in Flutter apps. Use for Flutter/Dart project work with Stream package setup, auth wiring, and widget blueprints. Supports stream_chat_flutter (pre-built Chat UI), stream_chat_flutter_core (custom Chat UI), stream_video_flutter (Video calling and livestreaming), and stream_feed / stream_feed_flutter_core (Activity Feeds, no pre-built UI). Also migrates Flutter apps from the Sendbird Chat SDK (sendbird_chat_sdk / sendbird_uikit) to Stream Chat.
License
Apache-2.0
Compatibility
Works in an existing Flutter project, or scaffolds a new one. No Stream CLI required.
Allowed tools
Read,, Write,, Edit,, Glob,, Grep,, Bash(ls, *),, Bash(grep, *),, Bash(find, ., *),, Bash(cat, pubspec.yaml),, Bash(cat, pubspec.lock),, Bash(flutter, pub, *),, Bash(flutter, create, *),, Bash(flutter, run, *),, Bash(flutter, analyze, *),, Bash(flutter, analyze),, Bash(flutter, build, *),, Bash(flutter, devices),, Bash(flutter, emulators, *),, Bash(flutter, emulators),, Bash(getstream, token, *),, Bash(getstream, env, *),, Bash(getstream, api, *),, Bash(getstream, login, *),, Bash(getstream, init, *)
Metadata
author: GetStream
Instructions
412 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves some shell commands

Files (23)

  • RULES.md
  • SKILL.md
  • builder.md
  • custom-ui.md
  • design-matching.md
  • CHAT-ADVANCED-FLUTTER-blueprints.md · references/
  • CHAT-ADVANCED-FLUTTER.md · references/
  • CHAT-CORE-blueprints.md · references/
  • CHAT-CORE.md · references/
  • CHAT-FLUTTER-blueprints.md · references/
  • CHAT-FLUTTER.md · references/
  • FEEDS-FLUTTER-blueprints.md · references/
  • FEEDS-FLUTTER.md · references/
  • LIVESTREAM-FLUTTER-blueprints.md · references/
  • LIVESTREAM-FLUTTER.md · references/
  • RINGING-FLUTTER-blueprints.md · references/
  • RINGING-FLUTTER.md · references/
  • VIDEO-ADVANCED-FLUTTER-blueprints.md · references/
  • VIDEO-ADVANCED-FLUTTER.md · references/
  • VIDEO-FLUTTER-blueprints.md · references/
  • VIDEO-FLUTTER.md · references/
  • sdk.md
  • sendbird-migration.md

SKILL.md (first lines)

# Stream Flutter - skill router + execution flow

**Rules:** Read **[`RULES.md`](RULES.md)** once per session - every non-negotiable rule is stated there, nowhere else.

This file is the **single entrypoint**: intent classification, local project detection, and module pointers for Stream work in Flutter apps.

---

## Step 0: Intent classifier (mandatory first - never skip)

Before any tool call, decide the **track** from the user's input alone - no probes first.

### Signals -> track

| Signal in user input                                                                                                                                          | Track                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Explicit package/widget token: `stream_chat_flutter`, `StreamChannelListView`, `StreamMessageListView`, `StreamChatClient`, etc.                              | **C - Reference lookup**                                                                                                                            |
| Explicit video token: `stream_video_flutter`, `StreamCallContainer`, `StreamVideo`, `StreamVideoRenderer`, `goLive`, `stopLive`, `livestream` call type       | **C - Reference lookup**                                                                                                                            |
| Explicit feeds token: `stream_feed`, `stream_feed_flutter_core`, `StreamFeedClient`, `FlatFeedCore`, `FlatFeed`, `FeedBloc`, `activity feed`, `feeds flutter` | **C - Reference lookup**                                                                                                                            |
| Words "docs" or "documentation" around Stream Flutter work                                                                                                    | **C - Reference lookup**                                                                                                                            |
| "How do I {X} in Flutter?", "What does {widget/method} do?"                                                                                                   | **C - Reference lookup**                                                                                                                            |
| "Build me a new Flutter app", "create a Flutter chat app" + Stream                                                                                            | **A - New app**                                                                                                                                     |
| "Build a Flutter video call app", "create a livestream app in Flutter"                                                                                        | **A - New app** (load `VIDEO-FLUTTER.md` + `VIDEO-FLUTTER-blueprints.md` or `LIVESTREAM-FLUTTER.md` + `LIVESTREAM-FLUTTER-blueprints.md`)           |
| "Build an audio room / Twitter Spaces clone", "TikTok-style live feed", "call while livestreaming", "chat with video calls", "two calls at once"              | **A or B** (load `VIDEO-ADVANCED-FLUTTER.md` + `VIDEO-ADVANCED-FLUTTER-blueprints.md` on top of the Video/Livestream pair)                          |
| "Add ringing / incoming calls", "video call with push notifications", "CallKit", "VoIP push", "FCM ringing", "missed call notification"                       | **A or B** (load `RINGING-FLUTTER.md` + `RINGING-FLUTTER-blueprints.md` on top of the Video pair)                                                   |
| "Build a Flutter feeds app", "create an activity feed app", "build a social feed in Flutter", "create a Twitter/Instagram clone"                              | **A - New app** (load `FEEDS-FLUTTER.md` + `FEEDS-FLUTTER-blueprints.md`; use Twitter-style UI unless the user explicitly specifies otherwise)      |
| "Add/integrate Stream into this app", "wire Chat into my Flutter project"                                                                                     | **B - Existing app**                                                                                                                                |
| "Add video calling to my Flutter app", "integrate Stream Video into my existing app"                                                                          | **B - Existing app** (load `VIDEO-FLUTTER.md` + `VIDEO-FLUTTER-blueprints.md`)                                                                      |
| "Add a feed to my Flutter app", "integrate Stream Feeds into my existing app", "add activity feed"                                                            | **B - Existing app** (load `FEEDS-FLUTTER.md` + `FEEDS-FLUTTER-blueprints.md`; use Twitter-style UI unless the user explicitly specifies otherwise) |
| "Install Stream packages", "set up Stream in Flutter", "wire auth/token" with no broader feature request                                                      | **D - Bootstrap / setup**                                                                                                                           |
| "Migrate my Flutter app from Sendbird", "replace `sendbird_chat_sdk` / `sendbird_uikit` with Stream", "switch off Sendbird / SendbirdUIKit"                    | **M - Migrate from Sendbird** ([`sendbird-migration.md`](sendbird-migration.md))                                                                    |
| Bare `/stream-flutter` with no args                                                                                                                           | List the tracks briefly and wait                                                                                                                    |

### Styling-depth flag (orthogonal to Tracks A/B/C/D)

If the request carries a **target appearance** — an attached screenshot, a Figma frame, or "make it look like WhatsApp / iMessage / Telegram / Slack / <app>" — then **before** feature work (Track A or B), **first run the strategy decision below** (components vs custom):

- **Components** → run [`design-matching.md`](design-matching.md): read its **procedure half in full** — everything above the `# Reference` divider (Steps 1–5; it may span two Reads, so page past a mid-procedure truncation) — then Grep its Reference half per region while implementing.
- **Custom** (livestream / overlay / bespoke) → run [`custom-ui.md`](custom-ui.md) instead — same region-by-region rigor, different mechanism.

The rest of this section is the **components** case (the common one). A reference design is a checklist of regions (header, composer buttons, where the timestamp + read receipts sit, bubble shape/tail, date separators, attachments...), and most of them differ from Stream's defaults **structurally**, not just by color. Do **not** stop at the wallpaper and bubble color — that is the known failure mode. Decompose every region first (capturing its **dimensions**, not just colors), then route each to one of **two axes**:

1. **Theming** — `StreamTheme` (a `ThemeExtension` on `MaterialApp.theme.extensions`) owns design foundations (spacing / radius / typography / colors) **and** all fine-grained/leaf styling including the whole message row (`messageItemTheme` bubble/text/attachment/metadata, `reactionsTheme`, `reactionPickerTheme`, `avatarTheme`, `textInputTheme`, `mediaViewerTheme`, …), while `StreamChatThemeData` (passed to `StreamChat(themeData:)`) owns only the chat composite-widget slots (the three headers, message-list background/wallpaper, channel-list item, quoted message, thread tile, poll themes).
2. **Widget replacement** — the component factory, populated via **core named slots** on `StreamComponentBuilders(...)` (~48 leaf slots: `messageBubble`, `messageText`, `reactions`, `reactionPicker`, `mediaViewer`, `jumpToUnreadButton`, `textInput`, `avatar`, …) **and** **chat slots** via `streamChatComponentBuilders(...) → extensions:` (~30 composite slots: `messageItem`, `messageComposer` + sub-slots, `channelListItem`, per-attachment builders, …), passed to `StreamChat(componentBuilders: StreamComponentBuilders(...))` (global) or `StreamComponentFactory(builders: …, child: …)` (scoped); plus per-widget builders (`messageBuilder`, `itemBuilder`) for a single instance.

Recurring traps the doc guards against:

- **(a)** overriding a **composite widget** (`messageItem` builder, `messageComposer` builder, `messageBuilder` on `StreamMessageListView`) silently drops the sub-features the default rendered — the incoming-message avatar, grouping, reactions, replies, status, or the send/voice/edit/slow-mode button — unless you read the default's `build()` and reproduce them (grouping state is available inside a custom `messageItem` via `StreamMessageLayout.of(context)`);
- **(b)** **model-driven title logic** must live in one shared helper used by both the channel list `itemBuilder` and the header, so the two surfaces cannot diverge;
- **(c)** route deliberately — bubble padding / color / shape live on **`StreamTheme`** (`StreamTheme.messageItemTheme.bubble`); structural changes (send button outside the field, metadata inside the bubble, a bubble tail, a Slack-style flat row) need **widget replacement** (component factory or a per-widget builder).

The match is **not done until you run, seed data that triggers every region, compare region-by-region against the reference on the real navigation path, and iterate** ([`design-matching.md`](design-matching.md) Step 5), deleting any throwaway verification scaffold — the UI must be as close to the reference as possible, not approximately like it. **Implement every region, the composer included** — never deliver a partial match with the rest labelled "known cosmetic gaps"; a region left at the SDK default is a FAIL, not a footnote. And **work in batches**: ground the pinned SDK version + local checkout once, read the source you need in one pass, implement all regions, then verify once on hot reload — don't rebuild-and-screenshot after every small edit.

### Chat only: pick the UI strategy first (before any code)

Stream Chat ships **two layers**, and choosing between them is an **architecture decision that dwarfs any styling choice** — getting it wrong wastes a day either way. So decide deliberately, and **default to the pre-built components**:

| Strategy | Use when the design is... | Mechanism | Runbook |
|---|---|---|---|
| **Pre-built UI components** (`stream_chat_flutter`) — **the default** | A messenger: bubbles, or a channel list → conversation, or per-message avatar/timestamp/receipts/reactions/attachments. Social, marketplace, workplace, support, DMs. "Make it look like WhatsApp / iMessage / Telegram / Slack." | Customize via the two axes — theming (`StreamTheme` for foundations + the message row/leaf widgets, `StreamChatThemeData` for the chat composite widgets) + widget replacement (the component factory `StreamComponentBuilders` / `streamChatComponentBuilders` / `StreamComponentFactory`, plus per-widget builders) | [`design-matching.md`](design-matching.md) |
| **Custom UI on `stream_chat_flutter_core`** — the exception | Not a messenger: a flat bubble-less author-inline feed, an overlay/ticker on video, high-volume ephemeral livestream chat (Twitch / YouTube / Kalshi), live shopping, or anonymous/guest read-only viewers vastly outnumbering posters (→ `livestream` channel type). Every message rendered identically; bespoke app chrome around it. | Build your own widgets on the headless `stream_chat_flutter_core` controllers (+ the low-level client); **no** `stream_chat_flutter` widgets | [`custom-ui.md`](custom-ui.md) |

**Lean hard toward components.** They're built to be *customized*, and the litmus test is: *if the two axes — theming (`StreamTheme` + `StreamChatThemeData`) + a few component-builder slots — could get there, it's a components job* — even strong messenger reskins. Pick **custom only** when matching the design would mean replacing the message row, composer, header, AND list all at once — i.e. you'd be using the SDK purely as a data source, not for any of its widgets. Over-choosing custom (rebuilding a worse messenger by hand, losing avatars/grouping/reactions/threads/attachments/typing/receipts/pickers) is the common, expensive mistake; over-choosing components costs a few hours of fighting layout. **When unsure, build the components version first** — it's faster to confirm-or-reject. And treat **"livestream" / "live-shopping" as signals, not labels**: they point to custom only when the *shape* matches (flat identical rows, overlay/ticker, high volume, read-only viewers) — a livestream app that wants a normal bubble/channel-list chat panel stays on **components**. This is the full decision rubric; [`custom-ui.md`](custom-ui.md) is the build runbook you follow *after* the decision lands on custom, not a doc you open to decide.

**Workplace / Slack-style hybrid is a components job too.** A Slack/Teams/Discord surface is a channel list + message list + composer, so it stays on the pre-built components — but two things differ from a messenger and must be matched, not punted: (1) the **message row** is flat and left-aligned (avatar-top rounded-square, an author·custom-status·timestamp header line, body, **bottom reaction pills**, and a **thread-reply summary**), with **no incoming/outgoing bubble split** — reproduce it by overriding the `messageItem` component builder (a composite slot — reproduce its sub-features); (2) the **header** and chrome are custom. The full workplace archetype is in [`design-matching.md`](design-matching.md). Workplace apps are also **thread-first**, so wire the thread-reply summary and thread screen.

The strategy also picks the **channel type and permission model** (e.g. `messaging` membership-gated for social/marketplace vs `livestream` public + anonymous viewers) — see [`RULES.md`](RULES.md) → "Surface permission prerequisites proactively", and Step 0.5 → "Permissions awareness". Decide both axes together.

If it's genuinely unclear, ask one question:

> Does this chat look like a standard messenger (channel list + bubbles), or a bespoke surface like livestream/overlay chat? It decides whether we customize the pre-built components or build custom UI on `stream_chat_flutter_core`.

### Disambiguation flow

If the request is ambiguous between **build/integrate** and **reference lookup**, ask one short question and wait:

> Do you want me to wire this into the project, or just map the Flutter SDK pattern and widgets?

### After classification

- **Tracks A, B, D** -> run **Project signals** once per session, then continue in [`builder.md`](builder.md) and [`sdk.md`](sdk.md). If the styling-depth flag was raised, run the design-match phase alongside per the UI-strategy decision — [`design-matching.md`](design-matching.md) for the pre-built components (the common case; read its procedure half in full — everything above the `# Reference` divider, which may span two Reads — then Grep its Reference half per region) or [`custom-ui.md`](custom-ui.md) for a bespoke `stream_chat_flutter_core` surface (design-match rigor is a mandatory phase, not an optional add-on).
- **Track C** -> skip the probe if the product + package are explicit. Only run it on demand if the SDK layer is ambiguous.
- **Track M** -> run [`sendbird-migration.md`](sendbird-migration.md): detect the existing Sendbird integration shape, swap packages/init/views/channels/messages, re-apply theming via the two axes, and verify design + functional fidelity per screen against the Sendbird original. Reuses Step 0.5 credentials and [`design-matching.md`](design-matching.md)/[`custom-ui.md`](custom-ui.md) rigor; hands off to the shared data-migration runbook when the code migration is done.

---

## Step 0.5: Credentials, token, and seed data (tracks A, B, D — and Track M at phase M2)

Run this once per session, right after intent classification, before the Project signals probe.

### Goal

Collect the Stream **API key**, a **user token**, and optionally seed channels or calls - all before touching code - so the app has real data to show from the first run.

### Single upfront question (ask exactly once, then act immediately)

Post **one message** asking all relevant things together. Do not split into multiple rounds.

**For Chat projects:**

> To wire everything up with real data, I need a few quick answers:
>
> 1. **Credentials** - Should I fetch your API key from the dashboard and generate a token via the Stream CLI, or will you paste them yourself?
> 2. **Token expiry** - If I'm generating the token: should it expire? (e.g. `1h`, `1d`, `30m`) or never expire?
> 3. **Seed channels** - Should I pre-create a few channels with random usernames so the app has something to show immediately?
>
> If you want to handle everything yourself, just paste your API key and token and tell me whether to seed channels.

**For Video projects** (calls are ephemeral - no seeding needed):

> To wire everything up, I need a couple of quick answers:
>
> 1. **Credentials** - Should I fetch your API key from the dashboard and generate a token via the Stream CLI, or will you paste them yourself?
> 2. **Token expiry** - If I'm generating the token: should it expire? (e.g. `1h`, `1d`, `30m`) or never expire?
>
> If you want to handle everything yourself, just paste your API key and token.

> **Guest-viewer requirement — surface this BEFORE building any app that signs viewers in as guests**. A guest connects with the `guest` role, which by default has minimal capabilities. On the `livestream` call type guests **cannot even read or join a call** until the integrator grants those capabilities to the `guest` role. When a guest-based viewer flow is in scope, tell the integrator it is a **prerequisite** to grant the `guest` role `read-call` and `join-call` (plus `create-call` if a viewer may open the call before the host) on the relevant call type via Stream Dashboard → Video & Audio → Call Types → <type> → Roles & Permissions (or the API), or to use authenticated `User.regular` viewers instead. Details: [`references/VIDEO-FLUTTER.md`](references/VIDEO-FLUTTER.md) → Guest users, and [`references/LIVESTREAM-FLUTTER.md`](references/LIVESTREAM-FLUTTER.md) → Roles, permissions, and backstage security.

From GetStream/agent-skills, Apache-2.0.

More from GetStream/agent-skills

Signals

Stars
20
Forks
4
Open issues
0
Last commit (this folder)
Aug 13, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
Apache-2.0
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from GetStream

Cite this page

stream-flutter skill. Agent Mart. https://agentmart.dev/skills/getstream-stream-flutter (last updated 2026-10-24)