Avatar

Represents a user with an image, initials fallback, and optional presence status. Multi-part over Radix Avatar; size and shape flow to every part through Context.

JE

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add avatar

Usage#

usage.tsxTSX
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"export function Example() {  return (    <Avatar>      <AvatarImage src="/jordi.jpg" alt="Jordi Espinosa" />      <AvatarFallback>JE</AvatarFallback>    </Avatar>  )}

Anatomy#

import {  Avatar,  AvatarImage,  AvatarFallback,  AvatarStatus,  AvatarBadge,} from "@/components/ui/avatar"<Avatar>  <AvatarImage />  <AvatarFallback />  <AvatarStatus />  <AvatarBadge /></Avatar>

Sizes#

Five fixed sizes, from xs (24px) to xl (64px). The status dot and fallback text scale with the box.

J
xs24px
J
sm32px
JE
md40px
JE
lg48px
JE
xl64px

Shape#

Circular by default; set shape="square" for a rounded-square avatar (e.g. organizations).

JE
circlePeople
JE
squareOrganizations

Fallback#

When no image is provided or it fails to load, Radix shows the fallback. Use delayMs to avoid a flash while a valid image loads.

JEKO

The fallback adapts to the box. A small avatar (xs/sm) shows a single initial so the glyph never crowds the silhouette; md and up show two. Pass the same two-letter string everywhere and let the size decide, or override per instance with maxInitials.

J
xs24px
J
sm32px
JE
md40px
JE
lg48px
JE
xl64px

Color#

color tints the initials fallback with a soft background and strong text from a single categorical token - the same palette as the Badge hues, so it re-themes across all four themes. Use it to distribute initials across users, teams, or tags. It only paints the fallback; an image, when present, covers it.

KO
default
JE
brand
MJ
purple
AL
pink
RT
teal
SD
orange

Status#

AvatarStatus adds a presence dot that sits outside the silhouette and reuses the status tokens (online/away/busy/offline).

JE
onlineActive now
JE
awayIdle
JE
busyDo not disturb
JE
offlineLast seen earlier

The position prop controls which corner the dot occupies - useful when another element (icon, badge) already occupies the default bottom-right corner.

JE
bottom-rightdefault
JE
top-right
JE
bottom-left
JE
top-left

Logo badge#

AvatarBadge is the same corner overlay as AvatarStatus, but it holds a brand or app mark instead of a presence dot. Drop an <img> or icon inside and it fits the coin, which carries a ring-background gap so it reads off the photo behind it. Use it to tag who someone is on another platform, an org badge, or a verified mark.

SStripe
Stripe
FFigma
Figma
SSpotify
Spotify
DDropbox
Dropbox

The coin's shape is its own, independent of the avatar: keep the round coin or set shape="square" for the classic app-icon look.

JEDropbox
circledefault
JEDropbox
squareApp icon

It scales with the avatar and takes the same position prop as the status dot, so you can move it off the default bottom-right corner.

JSpotify
xs24px
JSpotify
sm32px
JESpotify
md40px
JESpotify
lg48px
JESpotify
xl64px

Stack#

AvatarGroup stacks collaborators into one cluster. It owns the overlap, the ring-background separation, and the hover lift, so the children stay plain Avatars with no per-instance ring or z-index. Cap the visible count with max and the rest collapse into a +N chip; pass total when the real count exceeds the avatars you render. Match the group's size to its children; the overlap tightens as the box grows.

sm
JMLS+5
md
JEMDLCSR+5
lg
JEMDLCSR+5

Reach for renderOverflow to swap the default chip for a richer affordance, like a Tooltip that names the people the stack hides. See the full API on the Avatar Group page.

Examples#

Common patterns where avatars appear in product UI - combined with other components.

JE

Jordi Espinosa

Product Designer

Admin

Team members

  • J
    Jordi Espinosa
    jordi@koala.ui
    Admin
  • M
    Marie Dubois
    marie@koala.ui
    Editor
  • L
    Liam Chen
    liam@koala.ui
    Viewer
  1. J
    Jordi Espinosa
    The new token system is really clean. Switching themes feels instant now.
  2. M
    Marie Dubois
    Agreed, and the shadow scale is exactly what the cards needed.
  3. L
    Liam Chen
    Shipping this to staging today. Will update once QA signs off.

API reference#

Avatar

The root, over Radix Avatar.Root (a <span>): forwards all its props, and its size and shape flow to every part. Also exported as AvatarRoot. Every part accepts className, merged last.

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"24, 32, 40, 48 or 64px. Also scales the status dot, the badge and the initials cap.
shape"circle" | "square""circle"The silhouette; the image and fallback inherit its radius.
color"default" | "brand" | "purple" | "pink" | "teal" | "orange""default"Tints the initials fallback only. An image covers it.

AvatarImage

The photo, over Radix Avatar.Image (an <img> rendered once it loads). Forwards all its props.

PropTypeDefaultDescription
srcstring-The image URL.
altstring-The person's name, for assistive tech.
onLoadingStatusChange(status: "idle" | "loading" | "loaded" | "error") => void-Called as the image loads or fails.

AvatarFallback

The initials or icon shown when there is no image or it fails, over Radix Avatar.Fallback. Forwards all its props.

PropTypeDefaultDescription
maxInitialsnumber1 at xs and sm, 2 aboveCaps how many characters of a string child render. Any other node renders as is.
delayMsnumber-Waits before showing, to avoid a flash of initials while a valid image loads.

AvatarStatus

A presence dot on a corner, ringed off the avatar. Forwards all native <span> props.

PropTypeDefaultDescription
variant"online" | "away" | "busy" | "offline""online"The dot color, from the status tokens.
position"bottom-right" | "top-right" | "bottom-left" | "top-left""bottom-right"The corner the dot sits on.

AvatarBadge

A corner coin for a small logo or mark (an <img> or icon inside). Forwards all native <span> props.

PropTypeDefaultDescription
position"bottom-right" | "top-right" | "bottom-left" | "top-left""bottom-right"The corner the badge sits on.
shape"circle" | "square""circle"The coin shape, independent of the avatar's.

FAQ#

The fallback reads the resolved `size` from context and caps initials to fit the box: `xs` and `sm` show one initial so the glyph never crowds the silhouette, while `md` and up show two. Pass the same two-letter string everywhere and let size decide, or override per instance with `maxInitials`.