claude-skill-app-onboarding-questionnaire

Claude Code skill that designs and builds high-converting questionnaire-style app onboarding flows modelled on proven conversion patterns from top subscription apps like Noom, Headspace, and Duolingo.

22 stars

Best use case

claude-skill-app-onboarding-questionnaire is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Claude Code skill that designs and builds high-converting questionnaire-style app onboarding flows modelled on proven conversion patterns from top subscription apps like Noom, Headspace, and Duolingo.

Teams using claude-skill-app-onboarding-questionnaire should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/claude-skill-app-onboarding-questionnaire/SKILL.md --create-dirs "https://raw.githubusercontent.com/Aradotso/trending-skills/main/skills/claude-skill-app-onboarding-questionnaire/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/claude-skill-app-onboarding-questionnaire/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How claude-skill-app-onboarding-questionnaire Compares

Feature / Agentclaude-skill-app-onboarding-questionnaireStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Claude Code skill that designs and builds high-converting questionnaire-style app onboarding flows modelled on proven conversion patterns from top subscription apps like Noom, Headspace, and Duolingo.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# App Onboarding Questionnaire

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

A Claude Code skill that analyses your existing app codebase and generates a complete, high-converting questionnaire-style onboarding flow — including all copy, screen designs, and production-ready code — modelled on proven patterns from top subscription apps.

## What It Does

When you run `/app-onboarding-questionnaire` in your project, the skill:

1. **Analyses your codebase** — reads your app's source, manifest/plist files, and existing screens to understand your app's purpose, target users, and required permissions
2. **Defines the user transformation** — constructs a before/after narrative that drives the onboarding story
3. **Designs a screen-by-screen blueprint** — using a 14-screen psychological conversion framework
4. **Drafts all copy** — headlines, questions, answer options, CTAs, testimonials, social proof
5. **Builds the screens** — in your app's native framework (SwiftUI, React Native, Flutter, Jetpack Compose, etc.)

## Installation

### Option 1: Global skills directory

```bash
cd ~/.claude/skills
git clone https://github.com/adamlyttleapps/claude-skill-app-onboarding-questionnaire.git app-onboarding-questionnaire
```

### Option 2: Project-level dependency

Add to your project's `.claude/settings.json`:

```json
{
  "skills": [
    "github:adamlyttleapps/claude-skill-app-onboarding-questionnaire"
  ]
}
```

## Usage

Navigate to your app project directory and run:

```
/app-onboarding-questionnaire
```

The skill is interactive — it asks clarifying questions and builds incrementally. Progress is saved to Claude Code's memory system so you can resume across sessions.

## The 14-Screen Framework

| # | Screen | Conversion Purpose |
|---|--------|--------------------|
| 1 | Welcome | Hook — show the end state, create desire |
| 2 | Goal Question | "What are you trying to achieve?" — psychological investment |
| 3 | Pain Points | "What prevents you?" — builds empathy |
| 4 | Social Proof | Persona-matched testimonials |
| 5 | Tinder Cards | Swipe agree/disagree on pain statements |
| 6 | Personalised Solution | Mirror pains back with app solution stats |
| 7 | Comparison Table | Life with vs without the app *(optional)* |
| 8 | Preferences | Functional personalisation for the demo |
| 9 | Permission Priming | Benefit-framed pre-sell before system dialogs |
| 10 | Processing Moment | "Building X just for you..." anticipation builder |
| 11 | App Demo | User actually uses the core app mechanic |
| 12 | Value Delivery | Tangible output + share/viral moment |
| 13 | Account Gate | Optional sign-in to save what they created |
| 14 | Paywall | Hard paywall with trial, social proof, pricing |

Not every app needs every screen — the skill adapts based on your app's complexity and type.

## Key Differentiators

### App Demo Screen
Instead of a tour, users *do* something — pick recipes, complete an exercise, categorise a transaction — and receive a tangible result. This is Screen 11 and is the highest-impact screen for conversion.

### Permission Priming (Screen 9)
The skill auto-detects required permissions from your codebase:

- **iOS**: reads `Info.plist` for `NSCameraUsageDescription`, `NSLocationWhenInUseUsageDescription`, etc.
- **Android**: reads `AndroidManifest.xml` for `uses-permission` entries
- **React Native / Flutter**: checks both

For each permission found, it generates a benefit-framed priming screen shown *before* the system dialog. This converts at 70–80%+ vs ~40% for cold prompts.

### Viral / Share Moment (Screen 12)
The demo output is designed to be shareable — a meal plan, a workout, a savings projection. This is where organic growth originates.

## Code Examples

### SwiftUI — Goal Question Screen

```swift
// Generated by /app-onboarding-questionnaire
import SwiftUI

struct GoalQuestionView: View {
    @EnvironmentObject var onboardingState: OnboardingState
    
    let goals = [
        OnboardingOption(id: "lose_weight", emoji: "⚖️", title: "Lose weight", subtitle: "Reach a healthier body"),
        OnboardingOption(id: "build_muscle", emoji: "💪", title: "Build muscle", subtitle: "Get stronger and leaner"),
        OnboardingOption(id: "eat_healthier", emoji: "🥗", title: "Eat healthier", subtitle: "Improve my nutrition"),
        OnboardingOption(id: "save_time", emoji: "⏱️", title: "Save time cooking", subtitle: "Quick, easy meals")
    ]
    
    var body: some View {
        VStack(spacing: 24) {
            OnboardingHeader(
                title: "What's your main goal?",
                subtitle: "We'll personalise everything around this"
            )
            
            VStack(spacing: 12) {
                ForEach(goals) { goal in
                    OnboardingOptionRow(
                        option: goal,
                        isSelected: onboardingState.selectedGoal == goal.id
                    ) {
                        onboardingState.selectedGoal = goal.id
                    }
                }
            }
            
            Spacer()
            
            PrimaryButton(title: "Continue", isEnabled: onboardingState.selectedGoal != nil) {
                onboardingState.advance()
            }
        }
        .padding()
    }
}
```

### React Native — Tinder Swipe Cards Screen

```tsx
// Generated by /app-onboarding-questionnaire
import React, { useState } from 'react';
import { View, Text, StyleSheet, Animated, PanResponder } from 'react-native';
import { useOnboarding } from '../context/OnboardingContext';

const PAIN_STATEMENTS = [
  "I don't know what to cook each week",
  "I end up wasting food I've bought",
  "Healthy eating feels too complicated",
  "I spend too long deciding what to make",
];

export function TinderCardsScreen() {
  const { addAgreedPain, advance } = useOnboarding();
  const [currentIndex, setCurrentIndex] = useState(0);
  const position = new Animated.ValueXY();

  const panResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onPanResponderMove: (_, gesture) => {
      position.setValue({ x: gesture.dx, y: gesture.dy });
    },
    onPanResponderRelease: (_, gesture) => {
      if (gesture.dx > 120) {
        swipe('agree');
      } else if (gesture.dx < -120) {
        swipe('disagree');
      } else {
        Animated.spring(position, { toValue: { x: 0, y: 0 }, useNativeDriver: true }).start();
      }
    },
  });

  const swipe = (direction: 'agree' | 'disagree') => {
    if (direction === 'agree') {
      addAgreedPain(PAIN_STATEMENTS[currentIndex]);
    }
    Animated.timing(position, {
      toValue: { x: direction === 'agree' ? 500 : -500, y: 0 },
      duration: 250,
      useNativeDriver: true,
    }).start(() => {
      position.setValue({ x: 0, y: 0 });
      if (currentIndex + 1 >= PAIN_STATEMENTS.length) {
        advance();
      } else {
        setCurrentIndex(i => i + 1);
      }
    });
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Do these sound familiar?</Text>
      <Text style={styles.subtitle}>Swipe right if yes, left if no</Text>
      <Animated.View
        style={[styles.card, { transform: position.getTranslateTransform() }]}
        {...panResponder.panHandlers}
      >
        <Text style={styles.cardText}>{PAIN_STATEMENTS[currentIndex]}</Text>
      </Animated.View>
    </View>
  );
}
```

### Flutter — Processing / Loading Screen

```dart
// Generated by /app-onboarding-questionnaire
import 'package:flutter/material.dart';

class ProcessingScreen extends StatefulWidget {
  final VoidCallback onComplete;
  const ProcessingScreen({required this.onComplete, super.key});

  @override
  State<ProcessingScreen> createState() => _ProcessingScreenState();
}

class _ProcessingScreenState extends State<ProcessingScreen>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  int _stepIndex = 0;

  final List<String> _steps = [
    'Analysing your goals...',
    'Matching your preferences...',
    'Crafting your personal plan...',
    'Almost ready!',
  ];

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: const Duration(seconds: 4))
      ..addListener(() {
        final newIndex = (_controller.value * _steps.length).floor().clamp(0, _steps.length - 1);
        if (newIndex != _stepIndex) {
          setState(() => _stepIndex = newIndex);
        }
      })
      ..forward().whenComplete(widget.onComplete);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(value: _controller.value),
            const SizedBox(height: 32),
            AnimatedSwitcher(
              duration: const Duration(milliseconds: 400),
              child: Text(
                _steps[_stepIndex],
                key: ValueKey(_stepIndex),
                style: Theme.of(context).textTheme.titleMedium,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
```

### SwiftUI — Permission Priming Screen (auto-generated from Info.plist)

```swift
// Generated from detected NSCameraUsageDescription in Info.plist
struct CameraPermissionPrimingView: View {
    @EnvironmentObject var onboardingState: OnboardingState
    
    var body: some View {
        VStack(spacing: 32) {
            Image(systemName: "camera.fill")
                .font(.system(size: 64))
                .foregroundColor(.accentColor)
            
            VStack(spacing: 12) {
                Text("Scan ingredients instantly")
                    .font(.title2.bold())
                Text("Point your camera at any ingredient or barcode and we'll find matching recipes in seconds — no typing needed.")
                    .multilineTextAlignment(.center)
                    .foregroundColor(.secondary)
            }
            
            VStack(spacing: 8) {
                Label("Identify 10,000+ ingredients", systemImage: "checkmark.circle.fill")
                Label("Scan barcodes for nutrition info", systemImage: "checkmark.circle.fill")
                Label("Works offline for pantry items", systemImage: "checkmark.circle.fill")
            }
            .foregroundColor(.primary)
            
            Spacer()
            
            PrimaryButton(title: "Enable Camera Access") {
                // System prompt shown AFTER this priming screen
                onboardingState.requestCameraPermission()
            }
            
            Button("Not now") {
                onboardingState.skipPermission(.camera)
            }
            .foregroundColor(.secondary)
        }
        .padding(32)
    }
}
```

## Onboarding State Management Pattern

The skill generates a central state object to track progress across all screens:

```swift
// SwiftUI example
class OnboardingState: ObservableObject {
    @Published var currentScreen: OnboardingScreen = .welcome
    @Published var selectedGoal: String?
    @Published var agreedPains: [String] = []
    @Published var preferences: UserPreferences = .default
    @Published var demoResult: DemoOutput?
    
    // Persisted to UserDefaults so onboarding survives app restarts
    func advance() {
        let next = currentScreen.next(given: self)
        withAnimation { currentScreen = next }
        save()
    }
    
    func save() {
        // Skill generates serialisation code appropriate to your stack
    }
}
```

## Configuration Options

When you run `/app-onboarding-questionnaire`, the skill asks about:

| Option | Description |
|--------|-------------|
| App type | Subscription, freemium, one-time purchase |
| Core loop | The single thing users do in your app |
| Target audience | Who the app is for (used for copy tone) |
| Paywall timing | Whether to show paywall before or after account creation |
| Screens to skip | Comparison table, account gate, etc. |
| Brand colours | Used in generated SwiftUI/CSS/Flutter theme code |

## Resuming a Session

Progress is saved to Claude Code's memory. To resume:

```
/app-onboarding-questionnaire resume
```

To restart from a specific screen:

```
/app-onboarding-questionnaire --from=paywall
```

## Troubleshooting

**Skill doesn't detect my permissions correctly**
- iOS: ensure `Info.plist` is at the project root or `<AppName>/Info.plist`
- Android: ensure `AndroidManifest.xml` is at `app/src/main/AndroidManifest.xml`
- React Native: the skill checks both locations automatically

**Generated code uses wrong framework**
- The skill infers your framework from file extensions (`.swift`, `.tsx`, `.dart`, `.kt`)
- If detection fails, specify explicitly: `/app-onboarding-questionnaire --framework=swiftui`

**Paywall screen doesn't match my payment provider**
- The skill generates a UI shell; wire up your payment provider (RevenueCat, StoreKit 2, stripe-react-native) separately
- RevenueCat is the recommended integration — the skill generates compatible purchase call sites

**Want fewer screens for a simpler app**
- The skill asks about complexity during setup
- You can also specify: `/app-onboarding-questionnaire --screens=welcome,goal,processing,paywall`

## Reference

The framework is based on analysis of the [Mob](https://www.mob.co.uk/) recipe app's 19-screen onboarding flow, widely regarded as one of the highest-converting onboarding experiences on the App Store, combined with patterns from Noom, Headspace, and Duolingo.

Related Skills

web-access-claude-skill

22
from Aradotso/trending-skills

Give Claude Code full internet access with three-layer channel dispatch, CDP browser automation, and parallel sub-agent task splitting

token-dashboard-claude-analytics

22
from Aradotso/trending-skills

Local token cost analytics dashboard for Claude Code sessions — reads JSONL transcripts and provides per-prompt cost breakdowns, heatmaps, and usage insights.

openclaude-multi-llm

22
from Aradotso/trending-skills

Use Claude Code's full tool system with any OpenAI-compatible LLM — GPT-4o, DeepSeek, Gemini, Ollama, and 200+ models via environment variable configuration.

oh-story-claudecode-writing

22
from Aradotso/trending-skills

网文写作 skill 包,覆盖长篇与短篇网络小说的扫榜、拆文、写作、去AI味全流程

holyclaude-ai-workstation

22
from Aradotso/trending-skills

Deploy a full AI coding workstation with Claude Code, web UI, headless browser, and 5 AI CLIs in a single Docker container

free-code-claude-cli

22
from Aradotso/trending-skills

Build and use free-code, the open-source fork of Claude Code CLI with telemetry removed, guardrails stripped, and all experimental features unlocked.

everything-claude-code-harness

22
from Aradotso/trending-skills

Agent harness performance system for Claude Code and other AI coding agents — skills, instincts, memory, hooks, commands, and security scanning

deepclaude-proxy

22
from Aradotso/trending-skills

Use Claude Code's autonomous agent loop with DeepSeek V4 Pro, OpenRouter, or any Anthropic-compatible backend at up to 17x lower cost.

codeburn-claude-cost-dashboard

22
from Aradotso/trending-skills

Interactive TUI dashboard for visualizing Claude Code token usage, costs, and task breakdowns by project, model, and activity type.

clui-cc-claude-overlay

22
from Aradotso/trending-skills

Command Line User Interface for Claude Code — a floating macOS desktop overlay with multi-tab sessions, permission approval UI, voice input, and skills marketplace.

clawgod-claude-code-patch

22
from Aradotso/trending-skills

Runtime patch for Claude Code that unlocks hidden features, removes restrictions, and enables advanced capabilities like multi-agent swarms and computer use.

claude-peers-mcp

22
from Aradotso/trending-skills

Enable multiple Claude Code instances to discover each other and exchange messages in real-time via a local broker daemon and MCP server.