app-icon
Generate app icons for your React Native Expo app with iOS 26 support
What this skill does
# App Icon Generation Workflow
## Overview
Generate professional app icons using AI and configure them for both iOS (with iOS 26 Liquid Glass support) and Android platforms in Expo apps.
## Step 0: Verify SnapAI Setup (CRITICAL - DO THIS FIRST)
[SnapAI](https://github.com/betomoedano/snapai) is a free, open-source CLI built by the [Code with Beto](https://codewithbeto.dev) team. It calls OpenAI's image API directly using your personal API key, which is stored locally at `~/.snapai/config.json`. SnapAI ships no telemetry, has no backend server, and collects zero data — your credentials never leave your device.
**Before attempting to generate icons, check if SnapAI is configured:**
1. Check if SnapAI is configured:
```bash
npx snapai config --show
```
2. **If the config check fails or shows no API key:**
- SnapAI requires an OpenAI API key to generate icons
- Each icon costs approximately $0.04 via OpenAI's image generation API
- Ask the user: "SnapAI requires an OpenAI API key. Do you have one, or would you like me to help you set it up?"
3. **If the user has an API key:**
- Ask them to provide it securely
- Configure it for them with:
```bash
snapai config --api-key <their-api-key>
```
- Verify the setup worked:
```bash
snapai config --show
```
4. **If the user needs to get an API key:**
- Direct them to: https://platform.openai.com/api-keys
- Explain: "You'll need to:
1. Create an OpenAI account if you don't have one
2. Navigate to API keys section
3. Click 'Create new secret key'
4. Copy the key (starts with 'sk-')
5. Come back here and provide it to me"
- Once they provide the key, configure it using the command above
**Important Notes:**
- SnapAI is open source — your API key is stored in a local config file and sent directly to OpenAI. No intermediary servers, no data collection.
- The tool itself is free; you only pay standard OpenAI API costs (~$0.04 per icon).
- Do NOT proceed with icon generation if SnapAI is not configured
- The key must start with "sk-" to be valid
- You can handle the configuration for the user - just ask for their API key
## Step 1: Understand the App Context
- Read the `app.json` to understand the app name and current icon configuration
- Ask the user what the app is about if not clear from context
- Identify the app's theme, purpose, and target aesthetic
## Step 2: Get Style Preferences
Ask the user what style they'd like for the icon. Available styles:
- `minimalism` - Clean, Apple-inspired minimalism (2-3 colors max)
- `glassy` - Premium glass aesthetic with semi-transparent elements
- `gradient` - Vibrant gradients, Instagram-inspired
- `neon` - Cyberpunk, futuristic with glowing effects
- `material` - Google Material Design
- `ios-classic` - Traditional iOS with subtle gradients
- `pixel` - Retro 8-bit/16-bit game art style
- `geometric` - Bold, angular compositions
Or let the user provide a custom style description.
## Step 3: Generate Icon with SnapAI
**Pre-flight check:** Verify SnapAI is configured before running (see Step 0)
Generate a 1024x1024 icon with **transparent background** (critical for both platforms):
```bash
npx snapai icon --prompt "YOUR_PROMPT_HERE" --background transparent --output-format png --style STYLE_NAME
```
**Important flags:**
- `--background transparent` - REQUIRED for iOS 26 and Android adaptive icons
- `--output-format png` - Ensures PNG format
- `--style` - Optional, enhances the visual style
- `--quality high` - Optional, for final production icons
The icon will be saved to `./assets/icon-[timestamp].png`
## Step 4: Create iOS 26 .icon Folder Structure
Create the new iOS 26 Liquid Glass icon format:
1. Create the folder structure:
```bash
mkdir -p assets/app-icon.icon/Assets
```
2. Copy the generated PNG:
```bash
cp assets/icon-[timestamp].png assets/app-icon.icon/Assets/icon.png
```
3. Create `assets/app-icon.icon/icon.json` with this basic configuration:
```json
{
"fill": "automatic",
"groups": [
{
"layers": [
{
"glass": false,
"image-name": "icon.png",
"name": "icon"
}
],
"shadow": {
"kind": "neutral",
"opacity": 0.5
},
"translucency": {
"enabled": true,
"value": 0.5
}
}
],
"supported-platforms": {
"circles": ["watchOS"],
"squares": "shared"
}
}
```
## Step 4.5: Create Android-Optimized Adaptive Icon
Android adaptive icons have a smaller safe area (~66% of the canvas) compared to iOS. The main icon generated by SnapAI is optimized for iOS safe areas, which means it may appear too large and get clipped on Android devices with circular or squircle masks.
To ensure your icon displays correctly on all Android device shapes (circles, squircles, rounded squares), create a scaled-down version:
**Using ImageMagick (recommended):**
```bash
# Scale the icon to 66% and center it on a 1024x1024 transparent canvas
magick assets/icon-[timestamp].png \
-resize 66% \
-gravity center \
-background transparent \
-extent 1024x1024 \
assets/android-icon.png
```
**Alternative - Using sips + ImageMagick (macOS):**
```bash
# Step 1: Resize to 66% (676x676)
sips -Z 676 assets/icon-[timestamp].png --out /tmp/icon-resized.png
# Step 2: Create the final centered image
magick -size 1024x1024 xc:transparent /tmp/icon-resized.png \
-gravity center -composite assets/android-icon.png
```
**Note:** If ImageMagick is not installed, install it with:
```bash
brew install imagemagick
```
## Step 5: Update app.json
Update the `app.json` to configure icons for both platforms:
### For iOS:
```json
{
"expo": {
"ios": {
"icon": "./assets/app-icon.icon"
}
}
}
```
### For Android:
Use the Android-optimized icon created in Step 4.5:
**Option 1: Simple (with solid background color)**
```json
{
"expo": {
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/android-icon.png",
"backgroundColor": "#ffffff"
}
}
}
}
```
**Option 2: Comprehensive (recommended)**
Since the icon has a transparent background, you can use it for all three Android adaptive icon fields:
```json
{
"expo": {
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/android-icon.png",
"backgroundImage": "./assets/android-icon.png",
"monochromeImage": "./assets/android-icon.png"
}
}
}
}
```
**Benefits of Option 2:**
- `foregroundImage` - Main icon displayed
- `backgroundImage` - Provides layered depth effect on Android 8.0+
- `monochromeImage` - Used for themed icons on Android 13+ (automatically recolored by system)
**Note:**
- For Option 1, ask the user for their preferred `backgroundColor`, or use white (#ffffff) as default
- For Option 2, the same transparent PNG works perfectly for all three fields
- Option 2 provides better integration with Android's Material You theming
## Step 6: Verify and Test
1. Verify the folder structure exists:
```bash
ls -la assets/app-icon.icon/
```
2. Verify app.json is valid JSON:
```bash
cat app.json | jq .
```
3. Inform the user to test the app with:
```bash
npx expo prebuild --clean
npx expo run:ios
npx expo run:android
```
## Important Notes
- **Transparent background is critical** - The icon must have a transparent background for both iOS Liquid Glass effect and Android adaptive icons
- **iOS 26 .icon format** - The `.icon` folder enables Liquid Glass effects on iOS 26+
- **Dual-asset workflow** - This skill generates two icon assets:
- `icon-[timestamp].png` - Main icon optimized for iOS safe areas (used in `.icon` folder)
- `android-icon.png` - Scaled to 66% and centered for Android adaptive icon safe areas
- **Why two assets?** - iOS and Android have different safe zones. iOS allows content closer to edges (~80-85%), while Android adaptive icons only guarantee ~66% of the center is visible due to aggressive masking (circles, squirclRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.