whatsapp_chat_sdk 1.0.1 copy "whatsapp_chat_sdk: ^1.0.1" to clipboard
whatsapp_chat_sdk: ^1.0.1 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.

Repository: github.com/deepakyadav-developer/whatsapp_chat_sdk


Install in your Flutter app (3 steps) #

1. Add to pubspec.yaml:

dependencies:
  whatsapp_chat_sdk:
    git:
      url: https://github.com/deepakyadav-developer/whatsapp_chat_sdk.git
      ref: main

After the package is on pub.dev, use this instead (no Git needed):

dependencies:
  whatsapp_chat_sdk: ^1.0.0

2. Install packages:

flutter pub get

3. Import and use:

import 'package:whatsapp_chat_sdk/whatsapp_chat_sdk.dart';

That’s it — embed WhatsAppChatsPage or WhatsAppChatScreen in your app (see Quick start).


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)
  • Voice messages — hold mic to record, release to send; tap play/pause in bubble
  • 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 #

Method When to use
Git Now — install directly from GitHub (see Install in 3 steps)
pub.dev After dart pub publishwhatsapp_chat_sdk: ^1.0.0 (no git: block)
path You cloned the repo and develop SDK + app side by side
dependencies:
  whatsapp_chat_sdk:
    git:
      url: https://github.com/deepakyadav-developer/whatsapp_chat_sdk.git
      ref: main
flutter pub get

From pub.dev (after publish) #

Remove any git: dependency and use:

dependencies:
  whatsapp_chat_sdk: ^1.0.0
flutter pub get

Clone repo (contributors / run example) #

git clone https://github.com/deepakyadav-developer/whatsapp_chat_sdk.git
cd whatsapp_chat_sdk/example
flutter pub get
flutter run

Local path (SDK development) #

dependencies:
  whatsapp_chat_sdk:
    path: ../whatsapp_chat_sdk

Import:

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"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

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>
<key>NSMicrophoneUsageDescription</key>
<string>Used to record voice messages</string>

Voice messages (built into WhatsAppChatScreen) #

  1. Hold the green mic button (when the text field is empty).
  2. Release to send, or use the recording bar to cancel/send.
  3. Playback: tap play on the voice bubble.

Requires onVoiceRecorded (wired automatically on WhatsAppChatScreen when enableAttachments: true).

WhatsAppInputBar(
  onSend: onSendText,
  onVoiceRecorded: (result) {
    final msg = result.toMessage(id: uuid, senderId: myUserId);
    controller.sendChatMessage(chatId: chatId, message: msg);
  },
);

Uses record and audioplayers.
mediaUrl on ChatMessage stores the local .m4a path (upload to your server in production).

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)

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.

Git vs pub.dev — which should I use?

  • Before publish: use the git: URL in your app’s pubspec.yaml.
  • After publish: remove git: and use whatsapp_chat_sdk: ^1.0.0 from pub.dev only.

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


Automated release (maintainers) #

Push to pub.dev + Git tag from GitHub Actions:

  1. Add repo secret PUB_CREDENTIALS (see .github/PUBLISHING.md)
  2. ActionsRelease & PublishRun workflow → choose patch / minor / major

Version in pubspec.yaml and CHANGELOG.md update automatically, then the package publishes to pub.dev.


License #

MIT — see LICENSE.

3
likes
140
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.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

audioplayers, emoji_picker_flutter, file_picker, flutter, image_picker, intl, path_provider, record

More

Packages that depend on whatsapp_chat_sdk