Skip to content
Skip to content
Goodspeed

Build Your First App in a Weekend

A step-by-step guide to building your first production-ready mobile app using automated tools.

GUIDE BODY

The New Way to Build Apps

Building a mobile app used to require months of work, deep technical knowledge, and a team of specialists. That has changed. AI tools can now generate production-quality code, design screens, write tests, and handle deployment. If you have a validated idea and basic technical literacy, you can ship a real app in days, not months.

This guide walks you through the entire process from blank screen to published app.

Prerequisites

You do not need to be an expert developer. But you do need:

  • Basic programming knowledge: Understanding of variables, functions, and data structures. You should be able to read JavaScript or TypeScript code, even if you cannot write it from scratch.
  • A computer with Node.js installed: Node 18 or later. Install from nodejs.org.
  • An Apple Developer account ($99/year) if you want to publish to the iOS App Store.
  • A Google Play Developer account ($25 one-time) for Android.
  • A validated app idea: See our guide on validating app ideas.

Step 1: Choose Your Tech Stack

For most indie developers building cross-platform apps, the stack looks like this:

  • React Native with Expo: Build for iOS and Android from one codebase
  • TypeScript: Type safety that catches bugs early
  • Supabase: Database, authentication, and serverless functions
  • RevenueCat: Subscription management and in-app purchases

Why React Native?

Native development means maintaining two codebases (Swift for iOS, Kotlin for Android). React Native lets you write once and run on both platforms. Expo adds a managed workflow that handles the build system, over-the-air updates, and native module configuration.

# Create a new Expo project
npx create-expo-app my-app --template expo-template-blank-typescript
cd my-app

Step 2: Set Up Your Project Structure

A well-organized project saves you hours of confusion later. Here is a recommended structure:

my-app/
  app/                    # Screens (Expo Router file-based routing)
    (auth)/               # Auth screens (login, signup)
    (tabs)/               # Main app tabs
    _layout.tsx           # Root layout
  components/             # Reusable UI components
  hooks/                  # Custom React hooks
  lib/                    # Third-party integrations
  services/               # API and data layer
  types/                  # TypeScript type definitions
  assets/                 # Images, fonts, icons
  supabase/
    migrations/           # SQL migration files

Expo Router uses file-based routing, similar to Next.js. Each file in the app/ directory becomes a screen.

Step 3: Set Up Authentication

Every app needs user accounts. Supabase provides email/password auth, social login (Google, Apple, Twitter), and magic links out of the box.

npm install @supabase/supabase-js

Create a Supabase client:

// lib/supabase.ts
import { createClient } from '@supabase/supabase-js';
import AsyncStorage from '@react-native-async-storage/async-storage';

export const supabase = createClient(
  process.env.EXPO_PUBLIC_SUPABASE_URL!,
  process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!,
  {
    auth: {
      storage: AsyncStorage,
      autoRefreshToken: true,
      persistSession: true,
    },
  }
);

Authentication Hook

// hooks/useAuth.ts
import { useEffect, useState } from 'react';
import { supabase } from '../lib/supabase';
import { Session } from '@supabase/supabase-js';

export function useAuth() {
  const [session, setSession] = useState<Session | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    supabase.auth.getSession().then(({ data: { session } }) => {
      setSession(session);
      setLoading(false);
    });

    const { data: { subscription } } = supabase.auth.onAuthStateChange(
      (_event, session) => setSession(session)
    );

    return () => subscription.unsubscribe();
  }, []);

  return { session, user: session?.user, loading };
}

Step 4: Design Your Screens

Before writing screen code, sketch your app on paper or in Figma. Identify:

  • Onboarding flow: What do users see the first time they open the app?
  • Core screens: What are the two to four screens where users spend most of their time?
  • Settings: Profile, preferences, subscription management.
  • Navigation: Tabs, stack navigation, or drawer?

Using AI for Screen Generation

AI tools excel at generating React Native screen code. When prompting an AI to generate screens, be specific:

  • Describe the exact data shown on screen
  • Specify the interaction patterns (pull to refresh, infinite scroll, swipe to delete)
  • Mention the color scheme and design tokens
  • Reference component libraries you are using

A good prompt looks like this:

Create a React Native screen that shows a list of workout sessions.
Each item displays: exercise name, duration, date, and calories burned.
Use FlatList with pull-to-refresh. Empty state shows an illustration
and "Start your first workout" CTA. Use dark theme (#0D0D0F background,
#111114 card background, #FF4500 accent color).

Step 5: Connect Your Database

Supabase gives you a Postgres database with a REST API generated automatically from your schema.

Create Tables

Write SQL migrations to define your schema:

-- supabase/migrations/001_initial.sql
CREATE TABLE profiles (
  id UUID PRIMARY KEY REFERENCES auth.users(id),
  display_name TEXT,
  avatar_url TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Enable Row Level Security
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

-- Users can read and update their own profile
CREATE POLICY "Users manage own profile"
  ON profiles FOR ALL
  USING (auth.uid() = id);

Query Data from Your App

// services/profiles.ts
import { supabase } from '../lib/supabase';

export async function getProfile(userId: string) {
  const { data, error } = await supabase
    .from('profiles')
    .select('*')
    .eq('id', userId)
    .single();

  if (error) throw error;
  return data;
}

Step 6: Add Core Features

With auth and data in place, build your app-specific features. Focus on the two or three features that make your app valuable. Everything else can wait.

Common Feature Patterns

Data lists with search and filter:

const [search, setSearch] = useState('');
const filtered = items.filter(item =>
  item.name.toLowerCase().includes(search.toLowerCase())
);

Pull-to-refresh:

<FlatList
  data={items}
  refreshing={refreshing}
  onRefresh={handleRefresh}
  renderItem={({ item }) => <ItemCard item={item} />}
/>

Offline support: Cache data locally using AsyncStorage or expo-sqlite so the app works without an internet connection.

Step 7: Set Up Analytics

You cannot improve what you do not measure. Add analytics from day one.

// lib/posthog.ts
import PostHog from 'posthog-react-native';

const apiKey = process.env.EXPO_PUBLIC_POSTHOG_API_KEY;

export const posthog = apiKey
  ? new PostHog(apiKey, { host: 'https://us.i.posthog.com' })
  : null;

export function trackEvent(name: string, properties?: Record<string, any>) {
  if (!posthog) return;
  posthog.capture(name, properties);
}

Track key events: sign up, core feature usage, subscription starts, and errors.

Step 8: Configure Monetization

If your app is free, skip this step. Otherwise, set up RevenueCat for subscriptions:

npm install react-native-purchases

RevenueCat handles receipt validation, subscription status, and cross-platform purchases. Configure your products in App Store Connect and Google Play Console, then map them in RevenueCat's dashboard.

Step 9: Build and Test

Development Testing

npx expo start

This starts the Expo development server. Test on:

  • iOS Simulator (Mac only)
  • Android Emulator (Android Studio)
  • Physical devices using the Expo Go app

Preview Builds

For testing native features that Expo Go does not support:

npx eas build --profile preview --platform ios

This creates a build you can install directly on your test device.

Step 10: Submit to the App Store

Prepare your store listing:

  • App name and subtitle: Clear and keyword-rich
  • Screenshots: Show your app's best features. Use a tool like Screenshots.pro or create them in Figma.
  • Description: Focus on benefits, not features. What problem does the app solve?
  • Keywords: Research with AppTweak or Sensor Tower
  • Privacy policy: Required by both stores. Use a generator like iubenda.

Build for Production

npx eas build --profile production --platform all

Submit

npx eas submit --platform ios
npx eas submit --platform android

EAS Submit handles uploading your build to App Store Connect and Google Play Console.

Timeline: What to Expect

| Phase | Duration | Output | |-------|----------|--------| | Setup | 1 day | Project, auth, database | | Core screens | 2-3 days | Main features working | | Polish | 1-2 days | Animations, error handling, edge cases | | Testing | 1-2 days | Bug fixes, device testing | | Store prep | 1 day | Screenshots, descriptions, metadata | | Review | 1-7 days | Apple/Google review process |

Total: roughly one to two weeks from start to store listing.

Common Mistakes to Avoid

  • Building too many features: Ship with two or three core features. Add more based on user feedback.
  • Skipping error handling: Every network call can fail. Show clear error messages and retry options.
  • Ignoring performance: Test on older devices. A FlatList with 10,000 items needs virtualization.
  • No analytics: You will be flying blind without event tracking. Add it on day one.
  • Hardcoding strings: Use constants for colors, spacing, and text. It makes changes painless later.

Next Steps

Your app is live. Now the real work begins: listening to users, fixing bugs, adding features, and growing your audience. Check out our guides on user acquisition, ASO, and push notification strategy to keep the momentum going.

Ready to start building?