Skip to content

EnesKaraosman/SwiftyChat

Animated preview of the SwiftyChat chat UI

SwiftyChat

A lightweight, cross-platform SwiftUI chat UI framework.
Perfect for AI chatbots, customer support, and messaging apps.

GitHub Stars GitHub Forks Swift 6.0 iOS 17+ macOS 14+ Swift Package Index License

InstallationQuick StartMessage TypesThemesAI & ChatbotCustom Cells


Also available for Flutter.

Why SwiftyChat?

  • 11 built-in message types — text, image, video, location, carousel, quick replies, link previews, contacts, loading indicators, and more
  • 8 pre-built themes with full style customization via SwiftUI environment
  • Cross-platform — iOS 17+ and macOS 14+ from a single codebase
  • High performance — O(n) complexity, cached formatters, async image loading
  • Chatbot-ready — carousels, quick replies, and loading states designed for AI/bot interfaces
  • Lightweight — just 2 dependencies (Kingfisher + SwiftUIEKtensions)
  • Custom message cells for any type you need
  • Landscape orientation support with auto-scaling cells
  • User avatars with configurable positioning
  • Keyboard dismiss on tap and scroll
  • Scroll to bottom or to a specific message
  • Picture-in-Picture video playback
  • Per-corner rounding on text bubbles
  • Multiline input bar (BasicInputView)
  • Attributed string / markdown support

Preview

Light Dark Theme Showcase
Light mode chat demo Dark mode chat demo Theme showcase with carousel and map
More screenshots
Advanced Features Theme (Dark) Chatbot Demo
Advanced features with link preview Theme showcase in dark mode Chatbot demo with quick replies

Installation

Swift Package Manager

Add SwiftyChat in Xcode via File → Add Package Dependencies:

https://github.com/EnesKaraosman/SwiftyChat.git

Or add it to your Package.swift:

dependencies: [
    .package(url: "https://github.com/EnesKaraosman/SwiftyChat.git", from: "4.1.1")
]

Quick Start

import SwiftyChat

struct ContentView: View {
    @State private var messages: [YourMessage] = []
    @State private var message = ""
    @State private var scrollToBottom = false

    var body: some View {
        ChatView(messages: $messages, scrollToBottom: $scrollToBottom) {
            BasicInputView(
                message: $message,
                placeholder: "Type something",
                onCommit: { messageKind in
                    messages.append(/* your message */)
                }
            )
        }
        .environment(\.chatStyle, ChatMessageCellStyle())
    }
}

YourMessage must conform to the ChatMessage protocol (which has an associated ChatUser type). See the SwiftyChatDemo app for a complete implementation.

Message Kinds

public enum ChatMessageKind: CustomStringConvertible {
    case text(String)              // Auto-scales for emoji-only messages
    case image(ImageLoadingKind)   // Local (UIImage/NSImage) or remote (URL)
    case imageText(ImageLoadingKind, String) // Image with caption
    case location(LocationItem)    // MapKit pin
    case contact(ContactItem)      // Shareable contact card
    case quickReply([QuickReplyItem]) // Tappable options, auto-disables after selection
    case carousel([CarouselItem])  // Scrollable cards with buttons
    case video(VideoItem)          // Video with PiP support
    case linkPreview(LinkPreviewItem) // Rich URL preview with Open Graph metadata
    case loading                   // Animated loading indicator
    case custom(Any)               // Your own message type
}

Customization

Input View

A built-in BasicInputView is included. Use it as-is, or build your own — ChatView accepts any view via its inputView closure.

Styling

Every visual aspect is customizable through ChatMessageCellStyle — text styles, edge insets, avatar styles, and cell styles for every message type. Inject via .environment(\.chatStyle, yourStyle). All properties have sensible defaults.

See Styles.md for the full style reference and CustomMessage.md for custom cell types.

Pre-built Themes

Theme Description
Modern Clean blue, minimal design
Classic Traditional green messaging
Dark Neon Cyberpunk with neon pink accents
Minimal Subtle gray tones
Ocean Calming teal, sea-inspired
Sunset Warm orange gradients
Nature Fresh green, eco-friendly
Lavender Soft purple, relaxing

See ThemeShowcaseView in the SwiftyChatDemo app for live demos.

AI & Chatbot Use Case

SwiftyChat is especially well-suited for AI and chatbot interfaces. Built-in support for carousels, quick reply buttons, loading indicators, and link previews means you can build a rich conversational UI without custom cells:

// Show a loading indicator while the AI responds
messages.append(Message(user: bot, messageKind: .loading))

// Replace with the actual response
messages[messages.count - 1] = Message(
    user: bot,
    messageKind: .text("Here's what I found...")
)

// Offer follow-up options as quick replies
messages.append(Message(
    user: bot,
    messageKind: .quickReply([
        QuickReplyItem(title: "Tell me more"),
        QuickReplyItem(title: "Something else"),
    ])
))

Building a ChatGPT-style app, a customer support bot, or an in-app assistant? SwiftyChat gives you the UI layer so you can focus on the AI logic.

Contributing

Contributions are welcome! Whether it's a bug fix, new feature, documentation improvement, or a new theme — we'd love your help.

See CONTRIBUTING.md for guidelines.

Acknowledgments

Inspired by MessageKit (UIKit) and Nio (SwiftUI).

License

SwiftyChat is available under the Apache 2.0 license. See the LICENSE file for details.

Sponsor this project

 

Packages

 
 
 

Contributors

Languages