v260301.05 2:47a

AlpacApps Infra

AlpacApps is an open-source property management platform. Set up a super low cost do-it-all system from scratch — messaging, marketing, tenant management, and finance. You just need to set up the required (mostly free) accounts, then tell Claude Code what you have, where it is, and what you ideally want. Then watch the AI magic transpire.

Starting from: $0/month infrastructure • ~$10/month for Claude Code (API + Sonnet)
Alpacas in a server room
The philosophy: You set up the (mostly free) vendor accounts and gather credentials. Then tell Claude Code what you have and what you want — it handles all the terminal work: database migrations, CLI setup, edge function deployment, git pushes.

What can you build with this?

A full-stack business platform. The layers build on each other — pick what you need.

Your Customers & Partners
Consumers Banks/Payment Systems External Services
Capabilities
User Login Email SMS Payments E-Signatures AI Features
Google OAuth • Resend • Telnyx • Square • SignWell • Gemini
Your Business
CRM & customer management — contacts, relationships, communications, documents, payments
Foundation
Database + Auth + Storage Website + Hosting Tailwind CSS v4
Supabase • GitHub Pages • Tailwind • Free

Architecture & Cost Calculator

Browser → GitHub Pages (static HTML/CSS/JS) → Supabase (PostgreSQL + Auth + Edge Functions) ↗ ↓ Optional: Background Workers (cloud VM) —› Cloudflare R2 (media storage, optional)

Key principle: No backend server. All application logic runs client-side in the browser. Supabase provides the database, authentication, and serverless functions. For file storage, you can use Supabase Storage (1 GB free) or Cloudflare R2 (10 GB free, zero egress fees). GitHub Pages serves static files for free.

CSS: Tailwind CSS v4 is available alongside existing CSS custom properties. The Tailwind source (styles/tailwind.css) defines AAP design tokens (colors, fonts, shadows, radii) and is compiled to styles/tailwind.out.css by GitHub Actions CI on every push. Use npm run css:build locally or npm run css:watch for development. All pages load both site.css (custom properties) and tailwind.out.css (utility classes).

Select what you need

Core services are pre-selected. Toggle optional ones on or off.

How much will you build?

This mainly affects your Claude Code plan and usage-based services.

Estimated annual cost $0

GitHub1. GitHub + Starter Template Free

First, get a GitHub account and create your project from the starter template. Everything here is done in your browser — no terminal needed.

Create a GitHub account

You'll need a free GitHub account to host your site and store your code. If you already have one, skip to the next step.

  1. Go to github.com/signup and sign up with your email
  2. Verify your email address (GitHub will send you a confirmation link)
  3. That's it — a free account is all you need. GitHub Pages hosting is free for public repositories.

Create your project from the template

Choose a name for your project. This will become your repository name on GitHub (lowercase with hyphens, no spaces, e.g., my-salon-app).

  1. Go to the template repository: github.com/rsonnad/alpacapps-infra
  2. Click the green "Use this template" button → "Create a new repository"
  3. Enter your project name as the Repository name (e.g., my-salon-app)
  4. Make sure Public is selected (required for free GitHub Pages hosting)
  5. Click "Create repository" — GitHub copies all the template files into your own repo

Turn on GitHub Pages

  1. In your new repo, go to Settings (gear icon near the top)
  2. Click Pages in the left sidebar
  3. Under "Source," select Deploy from a branchmain/ (root)Save
  4. Wait 1–2 minutes. Your site is live at https://<username>.github.io/<project-name>/

Download the project to your computer

You need a copy of your project on your computer. This takes two steps:

a) Open a terminal

  • Mac: Press Cmd + Space, type Terminal, press Enter
  • Windows: Press Win + R, type cmd, press Enter

b) Paste this command into your terminal

Click Copy below, then paste into your terminal (Ctrl+V on Windows, Cmd+V on Mac) and press Enter:

git clone https://github.com/USERNAME/my-salon-app.git
cd my-salon-app

This downloads your project files into a folder on your computer. You'll point Claude Code at this folder in the next step.

Windows: Git not installed? If you see "git is not recognized," download Git from git-scm.com, install it (use all defaults), then close and reopen your terminal and try again. Mac already has Git built in.

Connect Git to your GitHub account

Before Claude Code can push code to your repository, Git needs to know your GitHub credentials. The easiest way is GitHub CLI, which handles this through your browser — no passwords or tokens to manage.

a) Install GitHub CLI

  • Mac: Paste into Terminal: brew install gh
    Don’t have Homebrew? Paste this first: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • Windows: Paste into your terminal: winget install --id GitHub.cli
    Then close and reopen your terminal.

b) Log in to GitHub through your browser

Paste this into your terminal and press Enter:

gh auth login

It will ask a few questions — pick these answers:

  1. Where do you use GitHub?GitHub.com
  2. Preferred protocol?HTTPS
  3. Authenticate Git with GitHub credentials?Yes
  4. How would you like to authenticate?Login with a web browser

It will show a one-time code and open your browser. Paste the code, click Authorize, and you’re done.

How to verify it worked: Run gh auth status in your terminal. You should see your GitHub username and “Logged in to github.com.”

Project structure included in the template:

your-repo/
├── index.html              # Landing page
├── styles.css              # Global styles
├── shared/                 # Shared JavaScript modules
│   ├── supabase.js         # Supabase client singleton
│   ├── auth.js             # Authentication
│   └── ...                 # Other services
├── spaces/                 # Public-facing pages
│   ├── index.html
│   ├── app.js
│   └── admin/              # Admin dashboard
│       ├── index.html
│       ├── app.js
│       └── manage.html
└── supabase/               # Edge functions (deployed via CLI)
    └── functions/

Claude2. Install Claude Code

Claude Code is your AI developer. Once it's set up, you won't need to use the terminal again — but if Claude asks you to do something in the terminal or bash something, just ask it to do it by itself. Claude can handle everything from here, but sometimes forgets.

Recommended: Claude Pro ($20/month) or higher The free tier works, but you'll hit usage limits quickly when setting up infrastructure. The Pro plan ($20/month) gives you significantly more usage. For intensive development, consider Max ($100) or Max+ ($200).

You do (one time)

  1. Sign up for Claude Pro ($20/month recommended)
  2. Download the Claude desktop app — Claude Code is built in
  3. Open the app and click the Code tab in the top right to open Claude Code
  4. Point it at the project folder you cloned in Step 1
Stuck on any step? Take a screenshot, paste it into the Claude desktop app, and ask: “What do I do?” — Claude can read screenshots and will walk you through it.
Already comfortable with the terminal? You can also install Claude Code as a standalone CLI: npm install -g @anthropic-ai/claude-code, then run claude from your project directory. Same features, same skills — these instructions just assume the desktop app.

Run the setup wizard

Once Claude Code is open in your project folder, type:

/setup-alpacapps-infra

Claude will ask you what you're building, which services you need, then walk you through the entire setup — creating your database, deploying edge functions, configuring webhooks, and building your CLAUDE.md (checked into repo) and CLAUDE.local.md (gitignored credentials). You don't need to read the rest of this guide unless you want to understand what's happening under the hood.

Slash command not working? The /setup-alpacapps-infra skill requires the Max plan ($100/month) or higher. If you're on the Pro plan, type this instead:
Read .claude/skills/setup-alpacapps-infra/SKILL.md and follow those instructions to set up my project
This does the exact same thing — Claude reads the setup guide and walks you through it step by step.

What the rest of this guide is for

The sections below explain each service in detail. For each one, you:

  1. You create the account and copy credentials (in your browser)
  2. You give Claude the credentials (just paste them into the chat)
  3. Claude handles everything else — updates your config files, installs CLIs, creates tables, writes edge functions, deploys, and pushes code

You never need to edit files yourself. Just tell Claude what you want in plain English.

"Set up Supabase. Here are my credentials: project ref is abc123, anon key is eyJ..."
installs Supabase CLI, links project, updates CLAUDE.md + CLAUDE.local.md, creates tables with RLS, creates storage buckets, commits and pushes

Supabase3. Supabase Free

Database, storage, auth, and serverless edge functions — all in one.

You do (in your browser)

  1. Sign up at supabase.com/dashboard (GitHub login works)
  2. Go to supabase.com/dashboard/projects and click New Project
  3. If prompted to create an organization first, give it any name (e.g. “Personal”) and select the Free plan
  4. Set a database password — save this securely (you’ll paste it to Claude)
  5. Choose a region close to your users, click Create new project, and wait 1-2 minutes
Where to find your project ref: After your project is created, look at the URL in your browser’s address bar. It will look like:
https://supabase.com/dashboard/project/abcdefghijk/...
The highlighted part (a random string of letters and numbers) is your project ref. You can also find it on your project’s home page under Project SettingsGeneral.

Paste your project ref here — the links below will update so you can click straight to the right pages:

  1. Go to API settings: supabase.com/dashboard/project/___/settings/api and copy:
    • Project URL (e.g., https://abcdefghijk.supabase.co)
    • Anon public key (safe to embed in frontend — RLS protects your data)
    • Project ref (the abcdefghijk part of the URL)
  2. Go to Database settings: supabase.com/dashboard/project/___/settings/databaseConnection stringSession pooler tab and copy it

Give Claude these credentials

## Supabase Details
- Project ID: `YOUR_PROJECT_REF`
- URL: `https://YOUR_PROJECT_REF.supabase.co`
- Anon key: `your-anon-key-here`
- Database password: `your-db-password`

### Direct Database Access (for Claude)
Session pooler connection string (paste yours from Database settings):
psql "postgres://postgres.YOUR_PROJECT_REF:YOUR_URL_ENCODED_PASSWORD@aws-0-REGION.pooler.supabase.com:5432/postgres" -c "SQL HERE"

URL-encode special characters in password (! = %21, @ = %40).

### Supabase CLI Access (for Claude)
If CLI not installed: npm install -g supabase && supabase login && supabase link --project-ref YOUR_PROJECT_REF
supabase functions deploy <function-name>
supabase secrets set KEY=value

For Claude: Run these directly. Don't ask the user.

Then tell Claude

"Set up my Supabase project. Install the CLI, link it, create the core database tables for [your domain], enable RLS on all tables, and create storage buckets for photos and documents." Claude will install the CLI, login, link, create shared/supabase.js, run SQL for tables + RLS + storage policies, commit, and push.

Google4. Google Sign-In (Optional) Free

If your app needs user login (admin dashboard, customer accounts, etc.), the easiest option is “Sign in with Google.” Supabase has built-in support — you just need to create a Google Cloud project and get OAuth credentials.

Same Google Cloud project: This step and Step 10 (Google Gemini) both use Google Cloud. Create one project and use it for both — no need to set up two.

1. Create a Google Cloud project

  1. Go to console.cloud.google.com → New Project
  2. Name it anything (e.g., “My Salon App”) and click Create
  3. Make sure the new project is selected in the top-left dropdown

2. Set up the OAuth consent screen

This is the screen users see when they click “Sign in with Google.”

  1. Go to APIs & Services → OAuth consent screen
  2. Choose External (unless you’re on Google Workspace and only want internal users) → click Create
  3. Fill in the required fields:
    • App name: your app’s name (what users see)
    • User support email: your email
    • Developer contact email: your email
  4. Click Save and Continue through the Scopes, Test Users, and Summary steps (defaults are fine)
Publishing status: Your app starts in “Testing” mode, which means only test users you add can sign in. To let anyone sign in, click Publish App on the consent screen page. Google may ask you to verify your app if you use sensitive scopes, but basic sign-in (email/profile) doesn’t require verification.

3. Create OAuth credentials

  1. Go to APIs & Services → Credentials
  2. Click + Create CredentialsOAuth client ID
  3. Application type: Web application
  4. Name: anything (e.g., “Supabase Auth”)
  5. Under Authorized redirect URIs, add:
    https://YOUR_PROJECT_REF.supabase.co/auth/v1/callback
  6. Click Create and copy the Client ID and Client Secret

4. Connect to Supabase

  1. Go to your Supabase dashboard → Authentication → Providers
  2. Find Google in the list and toggle it on
  3. Paste your Client ID and Client Secret
  4. Click Save

Give Claude these credentials

### Authentication (Google OAuth via Supabase)
- Google Client ID: `your-client-id.apps.googleusercontent.com`
- Auth is handled by Supabase Auth (no edge function needed)
- Redirect URI: `https://YOUR_PROJECT_REF.supabase.co/auth/v1/callback`
- Sign-in method: supabase.auth.signInWithOAuth({ provider: 'google' })

Then tell Claude

"Set up Google Sign-In. Create a login page with a 'Sign in with Google' button using Supabase Auth, and add an auth check to the admin pages so only authenticated users can access them." Claude will create shared/auth.js, add login/logout UI, set up auth guards on admin pages, commit, and push.

Resend5. Resend (Email) Free

You do (in your browser)

  1. Sign up at resend.com/signup (free: 3,000 emails/month)
  2. Recommended: Add your domain at resend.com/domains and set up DNS records. Without this, you can only send from onboarding@resend.dev.
  3. Create an API key at resend.com/api-keys and copy it

Give Claude these credentials

### Email (Resend)
- API key: `re_your_key_here` (store as Supabase secret: RESEND_API_KEY)
- From address: notifications@yourdomain.com (or onboarding@resend.dev)

Then tell Claude

"Set up email sending with Resend. Store the API key as a Supabase secret and create a send-email edge function." Claude will run supabase secrets set, create the edge function, deploy it, commit, and push.

Telnyx6. Telnyx (SMS) Pay-as-you-go

You do (in your browser)

  1. Sign up at telnyx.com/sign-up and add a payment method
  2. Buy an SMS-capable number at portal.telnyx.com → Numbers (~$1/month)
  3. Note the phone number in E.164 format (e.g., +12125551234)
  4. Create a Messaging Profile at portal.telnyx.com → Messaging
  5. Set inbound webhook URL:
    https://YOUR_PROJECT_REF.supabase.co/functions/v1/telnyx-webhook
  6. Assign your phone number to this profile, note the Messaging Profile ID
  7. Get your API key at portal.telnyx.com → API Keys and copy it
10DLC Registration (Required for US) — do this now, it takes time. Go to Messaging → Compliance. Create a Brand (Sole Proprietor), then a Campaign (use case: business notifications). Assign your number. Approval can take days to weeks — SMS won't work without it.

Give Claude these credentials

### SMS (Telnyx)
- API key: `KEY_your_key_here`
- Messaging Profile ID: `your-profile-id`
- Phone number: `+12125551234`
- Config stored in `telnyx_config` table
- Edge functions: `send-sms` (outbound), `telnyx-webhook` (inbound)
- Deploy webhook with `--no-verify-jwt`
- Auth: Bearer token (NOT Basic auth like Twilio)
- API: https://api.telnyx.com/v2/messages

Then tell Claude

"Set up Telnyx SMS. Create the telnyx_config and sms_messages tables, write the send-sms and telnyx-webhook edge functions, and deploy with --no-verify-jwt." Claude will create tables, insert config, write both edge functions, deploy, create shared/sms-service.js, commit, and push.

Square7. Square (Payments) Pay-as-you-go

You do (in your browser)

  1. Sign up at squareup.com/signup
  2. Create an app at developer.squareup.com/console → Apps
  3. Copy from the Developer Dashboard:
    • Application ID (starts with sq0idp-)
    • Access Token — Sandbox for testing, Production for real charges
    • Location ID — Square Dashboard → Locations

Give Claude these credentials

### Payments (Square)
- Application ID: `sq0idp-your-app-id`
- Sandbox Access Token: `your-sandbox-token`
- Location ID: `your-location-id`
- Environment: sandbox (switch to production when ready)
- Config stored in `square_config` table
- Edge function: `process-square-payment`
- Sandbox SDK: https://sandbox.web.squarecdn.com/v1/square.js
- Production SDK: https://web.squarecdn.com/v1/square.js

Then tell Claude

"Set up Square payment processing. Create the config and payments tables, a process-square-payment edge function, and a client-side square-service.js module." Claude will create tables, insert config, write the edge function + client module, deploy, commit, and push.

Stripe8. Stripe (Payments) Pay-as-you-go

Stripe handles ACH bank transfers (0.8% capped at $5), card payments (2.9% + 30¢), and outbound payouts to associates via Stripe Connect ($0.25/payout).

You do (in your browser)

  1. Sign up at dashboard.stripe.com/register
  2. Get your API keys at dashboard.stripe.com/apikeys:
    • Publishable key (starts with pk_test_ or pk_live_)
    • Secret key (starts with sk_test_ or sk_live_)
  3. Set up a webhook at dashboard.stripe.com/webhooks:
    https://YOUR_PROJECT_REF.supabase.co/functions/v1/stripe-webhook
  4. Subscribe to events: payment_intent.succeeded, payment_intent.payment_failed, transfer.paid, transfer.failed, account.updated
  5. Copy the Webhook Signing Secret (starts with whsec_)
  6. (Optional) Enable Stripe Connect for outbound associate payouts

Give Claude these credentials

### Payments (Stripe)
- Publishable key (test): `pk_test_...`
- Secret key (test): `sk_test_...`
- Publishable key (live): `pk_live_...`
- Secret key (live): `sk_live_...`
- Webhook signing secret: `whsec_...`
- Config stored in `stripe_config` table
- Edge functions: `process-stripe-payment`, `stripe-webhook`
- Deploy webhook with `--no-verify-jwt`
- Stripe.js v3: https://js.stripe.com/v3/

Then tell Claude

"Set up Stripe payment processing. Create the stripe_config and stripe_payments tables, a process-stripe-payment edge function (PaymentIntent creation), a stripe-webhook edge function (HMAC-verified), and a client-side stripe-service.js module. Support ACH bank transfers and card payments." Claude will create tables, insert config, write and deploy both edge functions, create the client module, commit, and push.

SignWell9. SignWell (E-Signatures) Free

You do (in your browser)

  1. Sign up at signwell.com/sign_up (free: 3 docs/month, 25 with credit card)
  2. Copy your API key at signwell.com → Settings → API
  3. Add a webhook at signwell.com → Settings → Webhooks:
    https://YOUR_PROJECT_REF.supabase.co/functions/v1/signwell-webhook
  4. Subscribe to the document_completed event

Give Claude these credentials

### E-Signatures (SignWell)
- API key: `your-signwell-api-key`
- API base: https://www.signwell.com/api/v1
- Auth: X-Api-Key header
- Config stored in `signwell_config` table
- Deploy webhook with `--no-verify-jwt`

Then tell Claude

"Set up SignWell for e-signatures. Create the config table, a webhook edge function, and client-side signwell-service.js and pdf-service.js modules." Claude will create the table, insert config, write and deploy the webhook, create client modules, commit, and push.

Google Gemini10. Google Gemini (AI Matching) Free

Optional. Useful for fuzzy matching (e.g., matching bank transaction sender names to tenants).

Already set up Google Sign-In? You already have a Google Cloud project from Step 4. Use the same project — just grab a Gemini API key below.

You do (in your browser)

  1. Get a free API key at aistudio.google.com/apikey

Give Claude these credentials

### AI Matching (Google Gemini)
- API key: `your-gemini-key` (store as Supabase secret: GEMINI_API_KEY)

Then tell Claude

"Store my Gemini API key as a Supabase secret." Claude will run: supabase secrets set GEMINI_API_KEY=your_key_here

Cloudflare11. Cloudflare R2 (Object Storage) Free

Optional. S3-compatible object storage with 10 GB free and zero egress fees. Great for documents, manuals, PDFs, and media that don’t need Supabase Storage’s RLS.

You do (in your browser)

  1. Sign up at dash.cloudflare.com/sign-up (free, no credit card)
  2. Go to R2 Object Storage in the left sidebar → Create bucket
  3. Name your bucket (e.g., your project name), choose a region, click Create bucket
  4. In bucket Settings, enable Public Development URL (allows public read access via a pub-*.r2.dev URL)
  5. Go to R2 Object StorageManage R2 API TokensCreate API token
  6. Give it Object Read & Write permission, apply to your bucket, create the token
  7. Copy the Access Key ID and Secret Access Key (shown only once!)

Give Claude these credentials

### Cloudflare R2
- Account ID: `your-cloudflare-account-id` (from the R2 dashboard URL or Overview page)
- Bucket name: `your-bucket-name`
- Public URL: `https://pub-xxxx.r2.dev` (from bucket Settings → Public Development URL)
- Access Key ID: `your-access-key`
- Secret Access Key: `your-secret-key`

Then tell Claude

"Store my R2 credentials as Supabase secrets and create the R2 upload helper and config table." Claude will: supabase secrets set R2_ACCOUNT_ID=... R2_ACCESS_KEY_ID=... R2_SECRET_ACCESS_KEY=... R2_BUCKET_NAME=... R2_PUBLIC_URL=..., create r2_config table, create supabase/functions/_shared/r2-upload.ts (S3-compatible upload with AWS Sig V4)

12. Background Workers (Optional)

Some features need always-on processes that can’t run in the browser or in Supabase Edge Functions. These run on a cloud VM (any provider: DigitalOcean, Google Cloud, Hetzner, etc.).

What runs here

Typical sizing

Tier Spec Cost Good for
Basic 2 vCPU, 2 GB RAM ~$12/mo A few lightweight pollers + image gen
Full 2 vCPU, 4 GB RAM ~$24–32/mo All workers including Claude Code automation (bug fixer, feature builder)

You do

  1. Spin up an Ubuntu VM on any cloud provider
  2. Install Node.js 18+, Tailscale (if you have a home server), and Caddy/nginx as needed
  3. Clone your repo and set up each worker as a systemd service
  4. Workers query Supabase directly using the REST API or service role key

Then tell Claude

“Set up the background workers on my server at [IP]. Create systemd services for the bug fixer, device pollers, and image gen worker. Add SSH access details to CLAUDE.local.md.”

13. Custom Domain (Optional)

No rush on this step. Your site is already live at https://<username>.github.io/<project-name>/ and that works great while you’re building. Come back to this when you’re ready to share your app with the world under your own brand name.

1. Buy a domain

If you don’t already own one, buy a domain from any registrar. Here are popular options:

2. Tell GitHub about your domain

  1. Go to your repo on GitHub
  2. Click SettingsPages (left sidebar)
  3. Under Custom domain, type your domain (e.g., myapp.com) and click Save
  4. GitHub will show a message that a DNS check is pending — that’s normal until you complete step 3

3. Point your domain to GitHub Pages (DNS settings)

This is the key step: you need to tell your domain registrar to send traffic to GitHub’s servers. The exact screens look a little different at each registrar, but you’re doing the same thing everywhere.

Find your DNS settings:

Add these records:

TypeName / HostValue / Points to
A@185.199.108.153
A@185.199.109.153
A@185.199.110.153
A@185.199.111.153
CNAMEwww<username>.github.io
What do these mean?
  • The four A records tell browsers “when someone types myapp.com, go to GitHub’s servers.”
  • The CNAME record makes www.myapp.com work too, by pointing it to your GitHub Pages address.
  • The @ symbol means “the root domain” (i.e., myapp.com with nothing in front of it).

If your registrar already has default records (like parking page records), delete those first, then add the ones above.

4. Turn on HTTPS

  1. Wait 5–30 minutes for DNS changes to propagate (sometimes up to 24 hours)
  2. Go back to your repo’s SettingsPages
  3. The DNS check should now show a green checkmark
  4. Check the box for Enforce HTTPS — GitHub provides a free SSL certificate automatically

How do I know it’s working?

Visit your domain in a browser. If you see your site, you’re done. If not:

14. CLAUDE.md Templates

Claude Code uses two files for project context: CLAUDE.md (checked into the repo) for shareable project context, and CLAUDE.local.md (gitignored) for credentials and operator directives. Enter your project name and download both.

CLAUDE.md (checked in) includes:

CLAUDE.local.md (gitignored) includes:

Tip: The setup wizard (Step 2) builds both files for you automatically as it sets up each service. Don't forget to add CLAUDE.local.md to your .gitignore.

15. Day-One Checklist

You do (in your browser)

Core Stack — Free:

User Login — Free (Google OAuth):

Email — Free (Resend):

SMS — Pay-as-you-go (Telnyx):

Payments — Free until you process (Square):

Payments — Free until you process (Stripe):

E-Signatures — Free tier (SignWell):

Optional:

Then tell Claude

Once you've given Claude your credentials, tell it to set everything up. You can either use the setup skill or paste this prompt:

"I've set up all my vendor accounts. Please:
  1. Set up the project structure and push to GitHub
  2. Install and link the Supabase CLI
  3. Create the database tables I need for [your domain]
  4. Set up email sending with Resend
  5. Set up SMS with Telnyx
  6. Set up payment processing with Square
  7. Set up e-signatures with SignWell
  8. Deploy all edge functions and store API keys as secrets"

Or just type /setup-alpacapps-infra in Claude Code — the skill walks through the same setup interactively, asking what services you need as it goes.

Claude handles everything from there — creating tables, writing edge functions, deploying, setting secrets, committing, and pushing. You never need to touch the terminal yourself.

16. Mobile App (iOS & Android) Free to develop

The mobile app wraps the same web codebase in a native shell using Capacitor 8. Residents get a native app experience (home screen icon, push notifications, no browser chrome) while you maintain a single codebase.

How It Works

Web App (HTML/CSS/JS) → Capacitor WebView → Native iOS / Android App ↓ Same Supabase backend as web

Capacitor takes your existing web code, loads it inside a native WebView, and gives you access to native device APIs (push notifications, camera, status bar) through JavaScript plugins. There's no need to learn Swift or Kotlin — your web skills are all you need.

Tech Stack

LayerTechnologyNotes
Native shellCapacitor 8Wraps web content in native WebView
UIVanilla HTML/CSS/JSDark theme, bottom tab bar, no framework needed
AuthSupabase AuthInline email/password + Google OAuth
DataSupabase JS SDKSame client as web app
OTA Updates@capgo/capacitor-updaterPush code updates without App Store review
Push Notifications@capacitor/push-notificationsFCM (Android) + APNs (iOS)

Development Tools

PlatformIDERequirements
iOSXcode 15+macOS only, free from App Store. Apple Developer account ($99/year) for App Store distribution
AndroidAndroid StudiomacOS, Windows, or Linux. Google Play Console ($25 one-time) for Play Store distribution

On the Phone

PlatformRuntimeMin Version
iPhone / iPadWKWebView (Safari engine)iOS 16+
AndroidAndroid WebView (Chromium engine)Android 6.0+ (API 23)

On iOS, the app runs inside Apple's WKWebView (same engine as Safari). On Android, it uses the system WebView powered by Chromium. Both provide near-native performance for web content.

Build & Deploy

Claude does this

Claude Code handles the build process. The workflow is:

  1. Build web assets — A script (copy-web.js) copies your web files into the mobile project, injects capacitor.js, and patches any redirect-based navigation
  2. Sync to nativenpm run sync from the mobile/ directory copies web assets into the iOS and Android native projects
  3. Run on device — Open Xcode (iOS) or Android Studio (Android) and press Play
# From the mobile/ directory:
npm run sync          # Build + sync to both platforms
npm run open:ios      # Open Xcode — press Play to run
npm run open:android  # Open Android Studio — press Run

Key Design Decisions