# KakaoTalk Chat UI Clone in SwiftUI

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-07. 6 min read.
> Source: https://vp0.com/blogs/kakao-talk-chat-ui-clone-swiftui

Any Korean user spots a vague KakaoTalk clone instantly. The signatures are specific, and the read count is the one that gives it away.

**TL;DR.** A KakaoTalk chat clone in SwiftUI reproduces a specific grammar Korean users recognize instantly: the warm yellow-brown palette, friend bubbles on the left with name and avatar, your bubbles on the right without, grouped timestamps, and the defining detail, a small unread count beside each message that decrements as group members read it. Build the list inverted, paged, and grouped (consecutive bubbles tucked, avatar on the first only), back it with an honest message-state model (sending/sent/delivered/read-by-N, never a faked count), and make the sticker tray first-class. Respect Dynamic Type, VoiceOver, and dark mode under the Korean look. A free VP0 design supplies the chat screens; bring your own backend and branding.

## What makes KakaoTalk's chat UI distinct enough to clone?

A specific visual and interaction grammar that any Korean user recognizes instantly, and getting it slightly wrong reads as a knockoff. [KakaoTalk](https://en.wikipedia.org/wiki/KakaoTalk) (used by 93% of South Korea's population at its peak) has a few signatures: the warm yellow-and-brown palette, friend bubbles on the left with the friend's name and avatar shown, your bubbles on the right with no avatar, the **unread count as a small number beside a message** (how many group members have not yet read it, not a generic badge), and timestamps that group rather than stamp every line. Reproducing those exactly is what makes a clone read as KakaoTalk rather than "a chat app with yellow in it."

The honest scope: this is a UI clone, the layout, the bubbles, the list, not KakaoTalk's backend, identity system, or brand assets. Build the recognizable interface as a learning piece or a starting point for your own messenger, with your own branding and a real-time backend you provide.

## How is the message list built so it scrolls right?

Inverted, lazy, and grouped, the three decisions every chat list lives or dies on. Messages render newest-at-bottom with the scroll pinned there, which in SwiftUI means a `ScrollView` with [`ScrollViewReader`](https://developer.apple.com/documentation/swiftui/scrollviewreader) (or a `List` with the rotation trick) so a new message slides in at the bottom and the view stays anchored. Load history in pages as the user scrolls up, never all at once, because a long conversation is thousands of bubbles.

Grouping is what makes it feel like KakaoTalk specifically:

| Element | KakaoTalk behavior | Why it matters |
| --- | --- | --- |
| Consecutive bubbles | Same sender's run tucks closer, avatar only on first | The signature density |
| Timestamp | Shown once per minute-group, on the last bubble of the cluster | Less noise than per-message |
| Unread count | Small number beside the bubble, decrements as members read | The defining KakaoTalk detail |
| Date divider | A centered pill when the day changes | Orientation in long threads |

The bubble itself is a sized-to-content shape with the tail and grouping logic, the same run-aware rendering and spring-entry craft as [the iMessage bubble physics](/blogs/imessage-reply-bubble-physics-swiftui/); the difference is the palette, the left-side names, and that unread-count number, which iMessage does not have.

## What does the data model owe a real chat?

Honest message state, because the unread count and delivery ticks are only as truthful as the model behind them. Each message carries a status (sending, sent, delivered, read-by-N), and the UI renders the truth: a message shows "sending" until the backend confirms, never an optimistic "sent" that lies if the network drops. In a group, the read count is derived from per-recipient read receipts, so the model tracks who has read up to which message, not a single boolean.

This is where a clone usually cheats and shouldn't: faking the read count as a random number looks fine in a screenshot and breaks the moment the app is real. The same pending-until-confirmed discipline governs any networked UI; treating "sent" as the truth before the server agrees is the messaging version of the optimistic-state bug. Real-time delivery rides a WebSocket via [URLSessionWebSocketTask](https://developer.apple.com/documentation/foundation/urlsessionwebsockettask) (the layout is yours; the transport is a standard chat backend), and offline messages queue with a visible pending state rather than vanishing.

## What completes the KakaoTalk feel?

The surrounding chrome and the input bar, where Korean messenger conventions show. The chat input is a multiline field that grows with content, a "+" for attachments (KakaoTalk leans heavily on stickers and emoticons, so the sticker tray is a first-class panel, not an afterthought), and the send button appearing only when there is text. The friends list and chat list are separate tabs, and the friends list shows profile status messages under names, a detail Western messengers mostly dropped.

Respect the platform underneath the Korean grammar: Dynamic Type so bubbles grow with the system font, VoiceOver labeling each bubble with sender and content, Reduce Motion calming the message-entry animation, and dark mode (KakaoTalk's palette has a dark variant). A free [VP0](https://vp0.com) design supplies the chat genre's screens, the message list, the input bar with sticker tray, the friends list, so an agent builds the inverted list and message-state model onto a layout already shaped for grouped bubbles and read counts, instead of reinventing chat from a blank prompt. The broader regional-clone discipline, reproduce the conventions, bring your own backend and branding, matches [the Zalo chat clone](/blogs/zalo-chat-app-ui-clone-react-native/) for the neighboring market.

The sticker side of messaging, an in-app tray versus a constrained keyboard extension, is built in [the LINE-style sticker keyboard](/blogs/line-app-sticker-keyboard-react-native/). The same lazy-list discipline that keeps these bubbles smooth drives a [social media feed in SwiftUI](/blogs/social-media-feed-ui-swiftui/).

## Key takeaways: a KakaoTalk chat UI

- **Clone the specific grammar**: yellow-brown palette, left bubbles with names, the per-message unread count, grouped timestamps; vague resemblance reads as a knockoff.
- **Inverted, paged, grouped list**: newest at bottom, history in pages, consecutive bubbles tucked with avatar only on the first.
- **Honest message state**: sending/sent/delivered/read-by-N from a real model, never a faked read count.
- **Sticker tray is first-class**: Korean messengers are sticker-heavy; the attachment panel is core, not an extra.
- **Platform respect under the Korean look**: Dynamic Type, VoiceOver, Reduce Motion, dark mode; bring your own backend and branding.

## Frequently asked questions

**How do I build a KakaoTalk chat UI clone in SwiftUI?** Build an inverted, paged message list with grouped bubbles (left bubbles carry the friend's name and avatar, consecutive messages tuck closer), reproduce the yellow-brown palette and the per-message unread count, and back it with an honest message-state model. A free VP0 design supplies the message list, sticker-tray input, and friends-list screens to build onto, with your own backend and branding.

**What makes KakaoTalk's chat UI different from other messengers?** The signatures: a warm yellow-and-brown palette, friend bubbles on the left showing name and avatar, an unread count rendered as a small number beside each message that decrements as group members read it, grouped timestamps, and a first-class sticker tray. iMessage, by contrast, has no per-message read count and no left-side names.

**How do I render a chat message list correctly in SwiftUI?** Inverted with the newest message at the bottom and the scroll pinned there (ScrollViewReader or a rotated List), loading history in pages as the user scrolls up rather than all at once, and grouping consecutive messages from one sender with the avatar only on the first and the timestamp once per minute-cluster.

**How should the app handle the unread count and message status?** From a real data model, not a faked number: each message tracks sending, sent, delivered, and read-by-N, with the group read count derived from per-recipient read receipts. The UI shows "sending" until the backend confirms, never an optimistic "sent," because a faked count looks fine in a screenshot and breaks in a real app.

**Is it legal to clone the KakaoTalk interface?** Reproducing the UI patterns as a learning piece or a base for your own messenger is fine; copying KakaoTalk's actual brand assets, name, logo, and proprietary stickers, is not. Build the recognizable layout with your own branding and your own real-time backend.

## Frequently asked questions

### How do I build a KakaoTalk chat UI clone in SwiftUI?

Build an inverted, paged message list with grouped bubbles (left bubbles carry the friend's name and avatar, consecutive messages tuck closer), reproduce the yellow-brown palette and the per-message unread count, and back it with an honest message-state model. A free VP0 design supplies the message list, sticker-tray input, and friends-list screens, with your own backend and branding.

### What makes KakaoTalk's chat UI different from other messengers?

The signatures: a warm yellow-and-brown palette, friend bubbles on the left showing name and avatar, an unread count rendered as a small number beside each message that decrements as group members read it, grouped timestamps, and a first-class sticker tray. iMessage, by contrast, has no per-message read count and no left-side names.

### How do I render a chat message list correctly in SwiftUI?

Inverted with the newest message at the bottom and the scroll pinned there (ScrollViewReader or a rotated List), loading history in pages as the user scrolls up rather than all at once, and grouping consecutive messages from one sender with the avatar only on the first and the timestamp once per minute-cluster.

### How should a chat app handle unread counts and message status?

From a real data model, not a faked number: each message tracks sending, sent, delivered, and read-by-N, with the group read count derived from per-recipient read receipts. The UI shows 'sending' until the backend confirms, never an optimistic 'sent,' because a faked count looks fine in a screenshot and breaks in a real app.

### Is it legal to clone the KakaoTalk interface?

Reproducing the UI patterns as a learning piece or a base for your own messenger is fine; copying KakaoTalk's actual brand assets, name, logo, and proprietary stickers, is not. Build the recognizable layout with your own branding and your own real-time backend.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
