whatsapp_chat_sdk 1.0.0 copy "whatsapp_chat_sdk: ^1.0.0" to clipboard
whatsapp_chat_sdk: ^1.0.0 copied to clipboard

Flutter UI SDK for WhatsApp-style chat — embed chat list, threads, bubbles, emoji & attachments in your app. UI only, no backend.

whatsapp_chat_sdk #

pub package License: MIT

A Flutter UI SDK for building WhatsApp-style chat experiences inside your own app.
It provides ready-made widgets (chat list, thread screen, bubbles, emoji picker, attachments) and optional local state — not a standalone chat app and not a backend.


Table of contents #


What this package is #

Included Not included
Chat list UI User authentication
Chat thread UI (messages + input) REST / Firebase / WebSocket server
Message bubbles (text, media, contact, etc.) Push notifications
Emoji picker & attachment sheet UI Message encryption
Light / dark themes Account / contact sync from device
Optional WhatsAppChatController for local/demo state A full clone WhatsApp app shell

Recommended usage: embed WhatsAppChatsPage and WhatsAppChatScreen in your Scaffold, tabs, or routes.
Optional: WhatsAppChatApp is a pre-built demo shell for prototypes only.

flowchart LR
  subgraph your_app [Your Flutter App]
    A[Your AppBar / Nav / Auth]
    B[WhatsAppChatsPage]
    C[WhatsAppChatScreen]
  end
  subgraph sdk [whatsapp_chat_sdk]
    B --> D[WhatsAppChatList]
    C --> E[WhatsAppMessageBubble]
    C --> F[WhatsAppInputBar]
    C --> G[WhatsAppEmojiPicker]
  end
  subgraph backend [You implement]
    H[API / Firebase / Socket]
  end
  B --> H
  C --> H

Features #

  • Conversation list — avatars, unread count, last message preview, typing indicator on list
  • Chat screen — wallpaper, date dividers, auto-scroll, group sender names
  • Message types — text, image, video, audio, document, location, contact, sticker, system
  • Read receipts — sending, sent ✓, delivered ✓✓, read (blue ✓✓), failed
  • Input bar — emoji picker, attach menu, camera shortcut, send / mic button
  • Attachments — document, camera, gallery (photo/video), contact (from chat participants), location (demo picker)
  • Reply preview — quoted message in composer (wire replyTo on send)
  • Forwarded label on bubbles
  • ThemesWhatsAppTheme.light() / .dark() or fully custom colors
  • ControllerChangeNotifier for conversations + messages (swap with your state management later)

Requirements #

  • Flutter 3.3+
  • Dart 3.11+ (see pubspec.yaml environment.sdk)
  • Your app must declare platform permissions for camera/gallery/files (see Attachments)

Installation #

From pub.dev #

dependencies:
  whatsapp_chat_sdk: ^1.0.0
flutter pub get

From path (local development) #

dependencies:
  whatsapp_chat_sdk:
    path: ../whatsapp_chat_sdk

From Git #

dependencies:
  whatsapp_chat_sdk:
    git:
      url: https://github.com/YOUR_USERNAME/whatsapp_chat_sdk.git
      ref: main

Import everything from the public library:

import 'package:whatsapp_chat_sdk/whatsapp_chat_sdk.dart';

Quick start #

Minimal integration: your MaterialApp, your AppBar, SDK only for the messages body.

import 'package:flutter/material.dart';
import 'package:whatsapp_chat_sdk/whatsapp_chat_sdk.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late final WhatsAppChatController _controller;

  @override
  void initState() {
    super.initState();
    _controller = WhatsAppChatController(
      currentUserId: 'me',
      conversations: [], // load from your API
      messagesByChatId: {},
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Messages')),
        body: WhatsAppChatsPage(
          controller: _controller,
          currentUserId: 'me',
          theme: WhatsAppTheme.light(),
        ),
      ),
    );
  }
}

Run the bundled example:

cd example
flutter run

How to use in your app #

Use WhatsAppChatsPage inside any parent widget (Scaffold, TabBarView, Drawer, etc.).

WhatsAppChatsPage(
  controller: controller,
  currentUserId: currentUserId,
  theme: WhatsAppTheme.dark(),
  header: MyPromoBanner(),           // optional widget above list
  emptyWidget: MyEmptyChatsWidget(), // optional
  onChatTap: (chat) {                // optional — default opens chat screen
    WhatsAppChatOpener.open(
      context,
      conversation: chat,
      controller: controller,
      currentUserId: currentUserId,
    );
  },
)

Pattern 2 — Open a chat from a button / notification #

WhatsAppChatOpener.open(
  context,
  conversation: conversation,
  controller: controller,
  currentUserId: 'me',
  onSend: (text) => myApi.sendText(conversation.id, text),
  onSendMessage: (msg) => myApi.sendMessage(conversation.id, msg),
);

Pattern 3 — Chat screen only (you own the list) #

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => WhatsAppChatScreen(
      conversation: conversation,
      messages: messages,
      currentUserId: 'me',
      onSend: (text) => sendText(text),
      onSendMessage: (msg) => sendFullMessage(msg),
      isTyping: remoteUserIsTyping,
      typingLabel: 'Alice is typing...',
      enableAttachments: true,
    ),
  ),
);

Pattern 4 — List widget only (full control) #

WhatsAppChatList(
  conversations: chats,
  currentUserId: 'me',
  theme: theme,
  onChatTap: (chat) => /* your navigation */,
)

Pattern 5 — Single bubble (custom layout) #

WhatsAppMessageBubble(
  message: message,
  isMe: message.senderId == myUserId,
  theme: theme,
  showSenderName: isGroup,
  senderName: 'Alice',
  onLongPress: () => showMessageActions(message),
)

Pattern 6 — Demo shell (prototypes only) #

// Includes WhatsApp-style app bar + FAB — not for production branding
WhatsAppChatApp(
  currentUserId: 'me',
  controller: controller,
  title: 'Chats',
)

Widget reference #

Widget Purpose
WhatsAppChatsPage Main entry — list + listens to controller + opens chat
WhatsAppChatScreen Full thread: app bar, messages, typing, input, attachments
WhatsAppChatList Conversation list only
WhatsAppChatOpener Static helper to Navigator.push chat screen
WhatsAppInputBar Composer with emoji / attach / send
WhatsAppEmojiPicker Standalone emoji panel
WhatsAppMessageBubble Single message bubble
WhatsAppChatAppBar Thread header (avatar, name, actions)
WhatsAppAvatar Circle avatar with optional online dot
WhatsAppTypingIndicator Animated typing dots
WhatsAppDateDivider “Today”, “Yesterday”, date labels
WhatsAppWallpaper Chat background pattern
WhatsAppAttachmentSheet Attach menu bottom sheet
WhatsAppContactPickerSheet Share contact bottom sheet
WhatsAppAttachmentHandler Pick gallery / camera / file / location
WhatsAppChatApp All-in-one demo shell (optional)

Models #

ChatUser #

ChatUser(
  id: 'user_1',
  name: 'Alice',
  avatarUrl: 'https://...', // optional
  phone: '+1 555-0100',     // used when sharing contact
  isOnline: true,
)

ChatConversation #

ChatConversation(
  id: 'chat_1',
  title: 'Alice',
  participants: [me, alice],
  isGroup: false,
  unreadCount: 2,
  lastMessage: lastMsg,
  isTyping: false,
  typingUserName: null,
)

ChatMessage #

ChatMessage(
  id: 'm1',
  senderId: 'me',
  createdAt: DateTime.now(),
  type: MessageType.text, // see MessageType enum
  text: 'Hello',
  status: MessageStatus.sent,
  replyTo: quotedMessage,
  mediaUrl: '/path/or/https/url', // image, video, local or network
  fileName: 'report.pdf',
  contactName: 'Bob',
  contactPhone: '+1...',
  latitude: 37.77,
  longitude: -122.42,
)

MessageType #

text · image · video · audio · document · location · contact · sticker · system

MessageStatus #

sending · sent · delivered · read · failed

ChatAttachmentResult #

Returned by pickers; convert to message:

final result = await WhatsAppAttachmentHandler.pickFromGallery();
if (result != null) {
  final message = result.toMessage(
    id: uuid,
    senderId: myUserId,
  );
  controller.sendChatMessage(chatId: chatId, message: message);
}

Controller #

WhatsAppChatController extends ChangeNotifier. Use with ListenableBuilder, AnimatedBuilder, or your state library.

Method Description
conversations Read-only list of chats
messagesFor(chatId) Messages in a thread
sendMessage(chatId:, text:) Send text (demo delivery simulation)
sendChatMessage(chatId:, message:) Send any MessageType
setConversations(list) Replace all chats (e.g. after API fetch)
setMessages(chatId, list) Replace thread messages
addConversation(chat) Add new chat
updateConversation(chat) Update metadata
markAsRead(chatId) Clear unread badge
setTyping(chatId:, isTyping:, userName:) Typing state for list + screen

Important: sendMessage / sendChatMessage simulate delivery with delays. In production, call setMessages or update status after your API responds.

// Listen to updates
controller.addListener(() => setState(() {}));

// Or
ListenableBuilder(
  listenable: controller,
  builder: (_, __) => WhatsAppChatsPage(controller: controller, ...),
);

Themes #

// Presets
final light = WhatsAppTheme.light();
final dark = WhatsAppTheme.dark();

// Custom
final brand = WhatsAppTheme(
  primaryColor: Color(0xFF075E54),
  accentColor: Color(0xFF25D366),
  sentBubbleColor: Color(0xFFDCF8C6),
  receivedBubbleColor: Colors.white,
  isDark: false,
);

Pass theme: to WhatsAppChatsPage, WhatsAppChatScreen, WhatsAppChatList, and bubbles.

Color constants: WhatsAppColors.


Attachments & permissions #

The SDK uses image_picker and file_picker.
Permissions must be added in your app, not in the package.

Android (android/app/src/main/AndroidManifest.xml) #

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32"/>

iOS (ios/Runner/Info.plist) #

<key>NSCameraUsageDescription</key>
<string>Used to take photos for chat messages</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to pick photos for chat messages</string>

Attachment flow (built into WhatsAppChatScreen) #

  1. User taps attachWhatsAppAttachmentSheet (document, camera, gallery, contact, location).
  2. Handler returns ChatAttachmentResult.
  3. Screen calls onSendMessage with a ChatMessage.

Override handlers on the screen or use WhatsAppAttachmentHandler directly for custom UX.

Contact picker uses ChatConversation.participants (excluding current user). Add phone on ChatUser for display.


Connect your backend #

The SDK is UI-only. Typical flow:

  1. Load chats → map API JSON to List<ChatConversation>controller.setConversations(...).
  2. Open chat → fetch messages → controller.setMessages(chatId, list).
  3. Send text → optimistic UI → API → update MessageStatus on success/failure.
  4. Send media → upload file → set mediaUrl to CDN URL → sendChatMessage.
  5. Realtime → on socket event, setMessages or patch a single message.

Example (pseudo-code):

Future<void> onSendText(String chatId, String text) async {
  final tempId = const Uuid().v4();
  final optimistic = ChatMessage(
    id: tempId,
    senderId: myUserId,
    text: text,
    createdAt: DateTime.now(),
    status: MessageStatus.sending,
    type: MessageType.text,
  );
  controller.sendChatMessage(chatId: chatId, message: optimistic);

  try {
    final saved = await api.postMessage(chatId, text);
    final list = controller.messagesFor(chatId).map((m) {
      return m.id == tempId
          ? m.copyWith(id: saved.id, status: MessageStatus.sent)
          : m;
    }).toList();
    controller.setMessages(chatId, list);
  } catch (_) {
    // mark failed
  }
}

Works with Provider, Riverpod, Bloc, GetX, etc. — use the controller as a starting point or bind widgets to your own streams.


Demo data #

For prototyping and the example app:

WhatsAppChatController(
  currentUserId: WhatsAppDemoData.currentUserId,
  conversations: WhatsAppDemoData.conversations(),
  messagesByChatId: WhatsAppDemoData.messagesByChat(),
);

Do not ship demo data in production.


Example project #

Location: example/

Shows embedding the SDK in a host app with:

  • Custom AppBar (“My App — Messages”)
  • Bottom navigation (Messages / Settings)
  • WhatsAppChatsPage on the Messages tab
  • Chat light/dark toggle (SDK theme only)
git clone <your-repo>
cd whatsapp_chat_sdk/example
flutter pub get
flutter run

Platform support #

Platform UI Emoji picker Gallery / camera File picker
Android ✅ (with permissions)
iOS ✅ (with permissions)
Web Limited
Windows
macOS
Linux Varies

Local image paths in bubbles use Image.file on IO platforms and network URLs everywhere.


FAQ #

Is this a full WhatsApp app?
No. It is a UI kit you place inside your application.

Can I use only the chat screen?
Yes. Use WhatsAppChatScreen + your own list/navigation.

Does it store messages permanently?
Only in memory via WhatsAppChatController. Persist with your database.

Can I change colors and fonts?
Yes, via WhatsAppTheme (fontFamily, bubble colors, app bar, etc.).

How do I disable attachments?
Set enableAttachments: false on WhatsAppChatScreen / WhatsAppChatsPage.

Package name / trademark
This is an unofficial UI toolkit. Ensure your app name and branding comply with store policies and trademarks.


License #

MIT — see LICENSE.

3
likes
110
points
10
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter UI SDK for WhatsApp-style chat — embed chat list, threads, bubbles, emoji & attachments in your app. UI only, no backend.

Homepage

License

MIT (license)

Dependencies

emoji_picker_flutter, file_picker, flutter, image_picker, intl

More

Packages that depend on whatsapp_chat_sdk