# Avatar Picker — React Native component for Expo

> 90 code-drawn avatars in flat, ink, crayon, pencil and pixel styles, with a grid or carousel picker.

90 different hand-drawn characters in 5 illustration styles — flat colour on a blob, black ink line art, crayon, pencil sketch and pixel art (18 each) — drawn entirely in code, no image files. Plus an AvatarPicker as a scrolling grid or a swipeable carousel, with style tabs, a live preview and a spring selection ring.

- Docs: https://expokit.in/docs/components/avatar-picker
- Tier: Pro (ExpoKit Pro plan)
- Also called: avatar picker, avatar library, profile avatar selector, cartoon avatars
- Category: Selection
- Platforms: iOS, Android, web
- Expo Go: yes, no development build needed
- npm dependencies: expo-haptics, react-native-svg
- Uses ExpoKit items: kit, tabs
- Variants: Picker, Carousel, Flat, Ink, Crayon, Pencil, Pixel

## Installation

This component is part of ExpoKit Pro. With a Pro plan, log the CLI in once and add it like any other item:

```bash
npx @expokit/cli@latest login
```

Plans: https://expokit.in/pricing

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `Avatar.id` | `string \| null` | — | Built-in avatar id, e.g. "flat-01" or "pencil-07". Unknown ids show a neutral placeholder. |
| `Avatar.size` | `number` | `48` | Width and height in points. |
| `Avatar.shape` | `"circle" \| "rounded" \| "square"` | `"circle"` | Tile shape (rounded follows the kit radius). |
| `Avatar.backgroundColor` | `string` | `the avatar's pastel` | Tile colour behind the character; "transparent" for none. |
| `Avatar.accessibilityLabel` | `string` | `"<name> avatar"` | Screen-reader label. |
| `selectedAvatar` | `string \| null` | — | Selected id (controlled). |
| `defaultAvatar` | `string` | — | Initial id when uncontrolled. |
| `onSelect` | `(id, avatar) => void` | — | Called with the id and its definition. |
| `styles` | `AvatarStyle[]` | `all four` | Which styles to offer: "flat" \| "ink" \| "crayon" \| "pencil" \| "pixel". One style hides the tabs. |
| `include` | `string[]` | — | Only these ids, in this order. |
| `exclude` | `string[]` | — | Hide these ids. |
| `maxAvatars` | `number` | — | Show at most this many. |
| `columns` | `number` | `4 / 6 / 8` | Grid columns (phone / medium / expanded). |
| `avatarSize` | `number` | `fills the column` | Avatar size in the grid. |
| `shape` | `"circle" \| "rounded" \| "square"` | `"circle"` | Shape of the tiles, ring and preview. |
| `backgroundColor` | `string \| (avatar) => string` | `each avatar's pastel` | One colour for every tile, or one per avatar. |
| `showTabs` | `boolean` | `true with 2+ styles` | Style tabs: All, Flat, Ink, Crayon, Pencil, Pixel. |
| `layout` | `"grid" \| "carousel"` | `"grid"` | Scrolling grid, or one swipeable row (avatarSize defaults to 64 there). |
| `showPreview` | `boolean` | `true` | Large preview of the selection with its name, style and id. |
| `emptyMessage` | `string` | `"No avatars match these filters."` | Shown when the filters leave nothing. |
| `accent` | `string` | `theme accent` | Selection ring, check badge and tab colour. |
| `haptics` | `boolean` | `true` | Selection tick. |
| `style` | `StyleProp<ViewStyle>` | — | Style for the root. |
| `className` | `string` | — | Tailwind classes on the root when using NativeWind or Uniwind. |
| `AVATARS / getAvatar / filterAvatars` | `exports` | — | The catalogue ({ id, name, style, background, component }), lookup by id, and the same filter the picker uses. |

## Behaviour & accessibility

- **Artwork**: Every avatar is react-native-svg paths and rects: no PNGs, URLs or base64, so it works offline and looks the same on iOS, Android and web. Each style has its own 18 characters; ids are stable: flat-01…18, ink-01…18, crayon-01…18, pencil-01…18, pixel-01…18.
- **Motion**: The selection ring and check badge spring in, tiles squish while pressed, and the preview pops when the choice changes. Category tabs slide their underline.
- **Layout**: layout="grid" fills its width (4 columns on phones, 6 on medium, 8 on expanded screens unless you pass columns) and scrolls inside a bounded parent. layout="carousel" is one swipeable row.
- **Reduced motion**: Press squish and the preview pop are skipped; the ring appears instantly.
- **Haptics**: A selection tick when you pick an avatar or switch tabs. Turn off with haptics={false}.
- **Screen readers**: The grid is a radio group; each tile reads its character's name and selected state. <Avatar> reads as an image labelled with the name.

## FAQ

### How do I make an avatar picker in React Native?

Use ExpoKit's Avatar Picker, a Pro component: with ExpoKit Pro, the ExpoKit CLI copies a ready-made avatar picker into your Expo or React Native app as plain TypeScript you can edit. It works on iOS, Android and web, and in Expo Go.

### Does Avatar Picker work in Expo Go?

Yes. Avatar Picker runs in Expo Go on iOS and Android with no development build — its packages (expo-haptics, react-native-svg) are all included in Expo Go.

### How do I add Avatar Picker to my Expo app?

With ExpoKit Pro, add it with the ExpoKit CLI: it copies the component's source into your app and installs expo-haptics, react-native-svg, so the code is yours to change. The install command is on this page for Pro members.

### Is Avatar Picker free?

Avatar Picker is part of ExpoKit Pro. With a Pro plan, log the CLI in once and it installs the full source into your app.

### Can I change how Avatar Picker looks?

Yes. It takes its colours, radius and light / dark mode from useKit(), so wrapping your app in <KitProvider accent radius> re-skins it with every other ExpoKit component. The code lives in your project, so you can also edit anything directly.

## More

- Live preview, variants and code: https://expokit.in/docs/components/avatar-picker
- Every ExpoKit component, screen, template and chart: https://expokit.in/llms.txt
- Install commands and props for every free component: https://expokit.in/llms-full.txt
- Pricing: https://expokit.in/pricing
