flowchart LR
app[Your app] --> ui[UI widgets]
app -. custom UI .-> core
ui --> core[Core]
core --> client[Client]
persist[Persistence] -. caches for .-> client
client <--> api[Stream API]Flutter Introduction
The Flutter SDK enables you to build any type of chat or messaging experience for Android, iOS, Web and Desktop.
Start here
This SDK is the client half of your integration. App settings, permissions, webhooks, push templates and data retention are configured from your backend with a server-side SDK or the REST API, and the token your app connects with has to be signed there too. See the server-side overview for what belongs there.
How the SDK is structured
The SDK consists of 4 packages:
-
stream_chat: A pure Dart package that can be used on any Dart project. It provides a low-level client to access the Stream Chat service.
-
stream_chat_flutter_core: Provides business logic to fetch common things required for integrating Stream Chat into your application. The
corepackage allows more customization and hence provides business logic but no UI components. -
stream_chat_flutter: This library includes both a low-level chat SDK and a set of reusable and customisable UI components. The full documentation for this package is available here.
-
stream_chat_persistence: Provides a persistence client for fetching and saving chat data locally.
Build prototypes with the full UI package: stream_chat_flutter ships widgets already integrated with Stream's API, and it is the fastest way to get chat running in your app.
If you're building a very custom UI, the core package is the lean option. It exposes the SDK's logic for users, messages and channels through providers and builders, with no UI widgets.
The online API tour shows how the API works; it runs JavaScript in the browser, but the ideas are the same in Dart.
Build with Stream CLI and Agent Skills
The Stream CLI and Agent Skills provide AI coding agents, such as Claude Code, Cursor, and Codex, with the tools and knowledge necessary to build apps with Stream.
Install the CLI and add the skills to your project:
curl -fsSL https://getstream.io/cli.sh | bash
getstream skills stream-flutterOnce installed, invoke it from your agent:
/stream Add Stream Chat to my Flutter app.The /stream skill acts as a router, reading your request and dispatching it to the specialist skill. You can also invoke the /stream-flutter skill directly.
Stream Agent Skills can also be installed from skills.sh.
Getting started
This guide will quickly help you get up to speed on Stream’s Chat API. The API is flexible and allows you to build any type of chat or messaging application.
Add one of the 3 packages to your app dependencies, to do that just open pubspec.yaml and add it inside the dependencies section.
dependencies:
# client + UX
stream_chat_flutter: ^1.0.1-beta
# core business logic widgets
stream_chat_flutter_core: ^1.0.1-beta
# client only
stream_chat: ^1.0.2-betaChat client
final apiKey = "{{ api_key }}";
final userToken = "{{ chat_user_token }}";
/// Create a new instance of [StreamChatClient] passing the apikey obtained from
/// your project dashboard.
final client = StreamChatClient(
's2dxdhpxd94g',
logLevel: Level.INFO,
);
/// Set the current user and connect the websocket.
/// In a production scenario, this should be done using a backend to generate
/// a user token using our server SDK.
/// Please see the following for more information:
/// https://getstream.io/chat/docs/ios_user_setup_and_tokens/
await client.connectUser(
User(id: 'super-band-9'),
userToken,
);The user token is typically provided by your backend when you login or register in the app. If authentication is disabled for your app you can also use a client.devToken(userId) to generate an insecure token for development. You should never launch into production with authentication disabled.
For more complex token generation and expiration examples have a look at the token provider documentation.
Channels
Let’s continue by watching your first channel. A channel contains messages and a list of members who are permanently associated with the channel and a list of watchers currently watching the channel. The example below shows how to set up a channel:
final channel = client.channel(
'messaging',
id: 'flutterdevs',
extraData: {
'name': 'Flutter devs',
},
);
await channel.watch();The first two arguments are the Channel Type and the Channel ID ( messaging and flutterdevs in this case). The Channel ID is optional; if you leave it out, the ID is determined based on the list of members. The channel type controls the settings we’re using for this channel.
There are 5 default types of channels:
-
livestream
-
messaging
-
team
-
gaming
-
commerce
These five options above provide you with the most suitable defaults for those use cases. You can also define custom channel types if the 5 defaults don’t work for your use-case.
The third argument is an object containing the channel data. You can add as many custom fields as you would like as long as the total size of the object is less than 5KB.
Messages
Now that we have the channel set up, let's send our first chat message:
final message = Message(
text:
'I told them I was pesca-pescatarian. Which is one who eats solely fish who eat other fish.',
extraData: {
'customField': '123',
},
);
await channel.sendMessage(message);Similar to users and channels, the sendMessage method allows you to add custom fields. When you send a message to a channel, Stream Chat automatically broadcasts to all the people that are watching this channel and updates in real-time.
Querying channels
The client.queryChannels method enables you to retrieve a list of channels. You can specify a filter and sort order. The client keeps the channels list updates as new messages, reactions and new channels arrive.
final filter = Filter.and([
Filter.equal('type', 'messaging'),
Filter.in_('members', ['john']),
]);
final sort = [SortOption<ChannelState>.desc('last_message_at')];
final channels = await client.queryChannels(
filter: filter,
channelStateSort: sort,
);To learn more about which fields you can query and sort on have a look at the query channels documentation.
What's next
Now that you understand the building blocks of a fully functional chat integration, these are good places to go deeper. The sample chat application is a fully-fledged messaging app built from our widgets.