flutter_ai_elements 0.2.0
flutter_ai_elements: ^0.2.0 copied to clipboard
Composable, themeable Flutter UI for AI chat: conversation view, message bubbles, a streaming-aware composer, and a loader, styled through a mobile-first theme extension.
flutter_ai_elements
The batteries-included AI chat UI kit for Flutter — drop in a polished, streaming chat in one widget, or compose 30+ themeable pieces yourself.
Family: flutter_ai ·
core · client ·
openai · anthropic · gemini ·
tools · mcp · voice
Recipes · Migrating from the Vercel AI SDK
Gallery #
![]() Streaming response AiChat · AiResponse · AiLoader
|
![]() Generative UI AiMessageBubble (custom DataPart renderers)
|
![]() Tool calls AiToolGroup · AiReasoning
|
![]() Citations AiSources · AiInlineCitation
|
![]() Theming AiThemeExtension tokens
|
![]() Dark mode One theme extension, light & dark |
Composable, themeable Flutter UI for AI chat — the UI layer of the
flutter_ai family.
It adopts the Vercel AI Elements component vocabulary but renders through a
mobile-first AiThemeExtension, built from base Flutter widgets. No
shadcn_flutter / forui dependency, no hardcoded Material or Cupertino look —
restyle everything via theme tokens.
Widgets #
Presentational (plain data + callbacks; reusable, testable):
AiMessageBubble— renders one message's parts (text, reasoning, tool calls, results, files, sources, data), role-aware, with streaming-safe semantics.AiConversationView— a scrolling list of bubbles, optional thinking loader.AiComposer— the presentational input: a leading attach (+) button and a main button that is Live while empty, Send once you type, and Stop while streaming; emits haptics. Use this only if you're wiring callbacks yourself.AiLoader— a pulsing three-dot thinking indicator.
Controller-bound (wire to a UseChatController — what you usually want):
AiChatView— the batteries-included one-widget chat: transcript + composer + layout. The fastest way to drop in a full chat.AiChat— live transcript with auto-scroll and a thinking loader.AiPromptInput— the drop-in composer: wrapsAiComposerand wires it tosendText/stop. Prefer this overAiComposer.
Quick start #
import 'package:flutter/material.dart';
import 'package:flutter_ai_elements/flutter_ai_elements.dart';
class ChatScreen extends StatelessWidget {
const ChatScreen({super.key, required this.controller});
final UseChatController controller; // from flutter_ai_client
@override
Widget build(BuildContext context) => Scaffold(
// Batteries-included: transcript + composer + layout in one widget.
body: AiChatView(controller: controller),
);
}
Need a custom layout between the transcript and composer? Compose the pieces yourself instead:
Scaffold(
body: Column(
children: [
Expanded(child: AiChat(controller: controller)),
AiPromptInput(controller: controller),
],
),
);
Theming #
Register an AiThemeExtension (or override the default) on your ThemeData:
MaterialApp(
theme: ThemeData(
extensions: [
AiThemeExtension.fallback().copyWith(
userBubbleColor: const Color(0xFF7C3AED),
bubbleRadius: const BorderRadius.all(Radius.circular(28)),
enableHaptics: true,
),
],
),
home: const ChatScreen(...),
);
Widgets read tokens via AiThemeExtension.of(context), falling back to the
mobile-first default when none is registered. All visual constants live behind
this one extension, so a future flutter_ai_design_system can extract them
without breaking the API.
Rich text #
Markdown renders by default — headings, lists, bold/italic, links, and fenced
code blocks — via MarkdownTextRenderer, so streamed answers format themselves
out of the box. Text flows through an injectable AiTextRenderer
(TextRenderer<Widget>), so you can swap in PlainTextRenderer for raw text, or
your own renderer for LaTeX or custom syntax highlighting:
// Markdown is the default — this line is optional.
AiChat(controller: controller, textRenderer: const MarkdownTextRenderer());
// Opt out to plain text, or bring your own.
AiChat(controller: controller, textRenderer: const PlainTextRenderer());
Status #
Published on pub.dev (see the CHANGELOG); depends on the sibling flutter_ai
packages.
See example/ for a full app.
If flutter_ai saves you time, you can buy me a coffee ☕.






