Skip to content

ComponentsDisplay

Avatar

A user or workspace image with an automatic fallback to initials or an icon while it loads or when it fails. Five sizes, circle and square shapes, deterministic fallback colors, a presence dot, and stacked groups with a "+N" overflow.

Source
shadcnNTOM

Installation

pnpm dlx shadcn@latest add @desyne/avatar

The CLI installs dependencies and any other components this one uses.

Usage

tsx
import { Avatar, AvatarGroup } from "@/components/ui/avatar";
tsx
<Avatar src={user.image} alt={user.name} fallback="OM" />

One component, no sub-parts

Unlike shadcn's Avatar / AvatarImage / AvatarFallback trio, this avatar takes src, alt and fallback as props. It tracks the image's loading state itself and shows the fallback until the image has loaded, or for good if it fails.

When to use

  • Avatar: to identify a person, team or workspace next to their name or content.
  • Badge: for a status label; use the avatar's status prop for presence.
  • Item: a list row with an avatar as its media, a name and a secondary line.
  • Use shape="square" for organizations, workspaces and apps, and circles for people, so the two are easy to tell apart.

Anatomy

tsx
<AvatarGroup max={4}>        {/* optional stack with a "+N" overflow */}
  <Avatar                    {/* root span: size, shape */}
    src="…"                  {/* <img>, shown once loaded */}
    fallback="OM"            {/* initials or icon while loading / on error */}
    status="online"          {/* presence dot in the corner */}
  />
</AvatarGroup>
PartRendersNotes
Avatar<span>Root. Sized by size, carries data-slot="avatar".
Image<img>Rendered when src is set. Hidden (but still loading) until it fires load; removed if it fires error.
Fallback<span>The fallback content, shown while the image loads or after it fails. Tinted when colorful is set.
Status<span role="img">A dot sized to 28% of the avatar, labelled with the status name.
AvatarGroup<div>Overlaps its children and adds a ring around each. With max, renders a "+N" avatar for the rest.

Examples

Sizes

md (32px) is the default. xs and sm fit inline text, table rows and dense lists; lg and xl suit headers and profile cards. Fallback text scales with the size.

OMxs · 20px
OMsm · 24px
OMmd · 32px
OMlg · 40px
OMxl · 56px

Shapes

circle (default) for people, square for organizations, workspaces and apps.

JLPerson
NAWorkspace

Fallbacks

The fallback shows while the image loads, and stays if it fails to load or there's no src. Pass initials, or any node such as an icon for guests. Always pass alt with the person's name: it becomes the image's alt text, and the fallback's accessible name when no image is shown.

shadcnBroken imageSD

Colorful fallbacks

colorful tints the fallback with one of six soft palettes, picked from a hash of alt (or the fallback text when alt is empty). The same name always gets the same color, so people are recognizable across the app, in light and dark mode.

OMJLINWKSDLBAOKT

Status

status adds a presence dot in the bottom-right corner: online (success), busy (danger), away (warning) or offline (muted). The dot has a background-colored ring so it stays visible on any surface.

OMonline
JLbusy
INaway
WKoffline

With name

Next to a visible name, pass alt="" so the name isn't read twice; the image (or fallback) is then treated as decorative.

shadcnm@example.com
Isabella Nguyen commented 5m ago

Group

AvatarGroup overlaps avatars and rings each one with the background color. max shows that many avatars and collapses the rest into a "+N" avatar. Its size prop sizes the "+N" avatar and every child that doesn't set its own size, so you set it once on the group. A child with an explicit size keeps it. Tighten the overlap with a -space-x-* class.

OMJLINWK
OMJLIN

Recipes

Account menu

An avatar as the trigger of a Menu. Wrap it in a React Aria Button with an aria-label, since the avatar alone isn't focusable.

Comment thread

A list of comments with avatars aligned to the first line of each message.

  1. Isabella Nguyen 2h ago

    The new onboarding checklist tested well. Five of six participants finished setup without help.

  2. William Kim 1h ago

    Nice. Can we ship it behind a flag on Thursday and watch activation for a week?

  3. Olivia Martin 12m ago

    Flag is ready. I'll turn it on for 20% of new workspaces.

Project card

A square workspace avatar in a Card header and a small AvatarGroup of the team in the footer.

AT
Atlas redesign
New navigation and dashboard for the Q4 launch.
On track
OMJLINWK
Due Nov 14

Accessibility

  • With an image, alt is the image's alt text. When no image is shown and alt is set, the fallback gets role="img" and aria-label={alt}.
  • While an image is still loading, the fallback is aria-hidden and the (invisible) <img> carries the name.
  • With alt="" (the default), the avatar is decorative: the image has empty alt text and the fallback is aria-hidden. Use this when the name is already visible next to the avatar.
  • The status dot is role="img" with aria-label set to the status name ("online", "busy", "away", "offline"), so it's announced as a separate image. If presence is shown elsewhere in text, you can omit status.
  • The "+N" avatar in a group has aria-label="N more". Give the group itself role="group" and an aria-label such as "6 collaborators" for context.
  • Avatars aren't interactive. To make one clickable, wrap it in a button or link with an accessible name, as in the account menu recipe.

Styling

Data attributes

AttributeOnPresent when
data-slot="avatar"Avatar rootAlways
data-slot="avatar-group"AvatarGroupAlways

AvatarGroup styles its children through *:data-[slot=avatar]:… (ring and full rounding), so anything you render inside with data-slot="avatar" joins the stack.

Customizing

  • className on Avatar goes to the root span; use it for custom sizes (size-12 text-base) or rings.
  • The ring color in groups is ring-background. Override it on a colored surface with *:data-[slot=avatar]:ring-card on the group.
  • colorful palettes are defined in the component source as OKLCH values with dark-mode pairs. Edit that array to match your brand.

API Reference

Avatar

Prop

Type

Also accepts every prop of <span>.

AvatarGroup

Prop

Type

Also accepts every prop of <div>.

  • Item: list rows with an avatar as media.
  • Badge: labels next to a name, like roles or "Verified".
  • Menu: account menus triggered by an avatar.
  • Card: profile and project cards.