From Idea to App — Practical Techniques
Introduction
Modaal is an AI system for building native iOS apps. You describe an idea or a task, and the AI agent generates code, builds the project, analyzes errors, and iterates with you. The quality of the result depends directly on how you phrase your request and whether you ask for a plan first. There’s a single control for that — the Plan toggle in the composer:- Plan off (the default) — the agent works directly: it writes code, builds the project, debugs, fixes, and iterates with you.
- Plan on — the agent produces a structured implementation plan (a feature spec) without writing code. On a brand-new project, its first prompt runs Refine: it turns your idea into a PRD and scaffolds the project.
The Plan toggle
You control planning with the Plan button next to the composer. Leave it off for most work; turn it on when you want a thorough plan before any code is written.
Plan off (default): the agent executes tasks directly — best for simple tasks and fast iteration.

Plan on: describe your feature and get a structured implementation plan — for deep research, complex tasks, and feature planning.
The two produce different deliverables. With Plan on, the deliverable is the plan itself — a feature spec at
specs/<feature>/spec.md — and no code is written yet. With Plan off, the deliverable is working code: the agent implements your request directly. If a spec already exists from a Plan-on session, the agent reads it and builds from it.
How it fits together
Starting a brand-new project? Turn Plan on. On your very first prompt it automatically runs Refine — it captures your idea into a PRD, confirms key decisions (like architecture), scaffolds the project, and writes the first feature spec. (You don’t pick Refine separately; with Plan on, the agent detects the project has no code yet and adapts.) Already have a project? Two typical workflows: Structured: Plan on → Plan off → repeatWith Plan on — Planning
What it does
With Plan on, the agent produces a thorough written plan before any code is written. It:- Does not edit, create, or modify any source code
- Reads any file in the codebase for research
- Produces a single output:
spec.mdinside the feature directory - Can continue or update an existing feature spec
- Brand-new project (no code yet) → the Refine flow (below)
- Existing project → researches your codebase and writes a feature spec referencing real files and patterns to reuse
Refine: the first prompt on a new project
When you start from scratch with Plan on, your first prompt is the Refine step. You come in with an idea — anything from a single sentence to a multi-page description with Figma links — and the agent turns it into a structured project. Refine has two phases:- Phase A — Understand the idea → confirm key decisions (architecture, platforms) → write the PRD → scaffold the project
- Phase B — select the first feature from the PRD → create the feature directory → write its
spec.md
- Reads your description (text, images, Figma links — whatever you provide)
- Researches the knowledge base for architecture guidance and platform patterns
- Confirms key decisions with you (architecture, platforms, scope)
- Writes a structured PRD to
PRD.md - Scaffolds the project (creates the Xcode project structure)
- Plans the first implementable feature and writes
spec.md
A guitar tuner app. It listens to the microphone, detects the pitch, and shows whether the string is in tune.The agent expands this into a PRD: the main tuner screen, tuning selection (standard, drop-D, open-G), visual feedback (needle + color), session history (as a provisional suggestion). It notes that microphone access and audio analysis are core, while cloud sync is deferred. Then it scaffolds the project and writes a feature spec for the first iteration. A detailed description:
I’m building a local services marketplace. Here’s what I need: User side: Browse services by category, view provider profiles with ratings, book appointments with date/time picker, in-app chat with provider, pay via Stripe, rate after service. Provider side: Create/edit profile, manage availability calendar, accept/reject bookings, view earnings dashboard. Target: iOS 18+, iPhone only. Need to support Ukrainian and English.Here the agent preserves everything as-is, adds structure (user flows, acceptance criteria, technical considerations), and doesn’t invent extra features. Figma-based:
Here’s my Figma design: [link]. Build this app exactly as designed. The first tab is a feed, the second is search, the third is profile.The agent uses Figma MCP to pull design context and screenshots, then generates a PRD based on the UI structure. Just an attachment: You can attach a PRD, design doc, or screenshot with no text at all. The agent reads the attachment and works from its content.
Planning on an existing project
For an existing app, Plan on makes the agent research the codebase thoroughly, understand existing patterns, and produce a detailed feature spec — without writing any code. How it works:- Parse User Input — reads your feature description and checks for existing feature context
- Determine Feature Context — decides whether to continue an existing feature or create a new one:
- If the request refines/extends the current feature → updates the existing spec
- If it describes a clearly different feature → creates a new feature directory
- If ambiguous → asks you to choose
- Research the Codebase — reads source files, identifies patterns, finds reusable code, checks the knowledge base
- Write the Spec — creates or updates
spec.mdwith: Overview, User Scenarios, Technical Approach (Architecture, Key Design Decisions, Existing Code to Reuse), Implementation Steps (phased), Files to Create/Modify, Risks & Open Questions, Testing Strategy - Report Completion — summarizes findings and flags open questions
Add push notification support. Users should be able to opt in/out per category (promotions, reminders, social). Store preferences locally and sync with the backend. Show an onboarding prompt on first launch.The agent explores the existing codebase, understands the current architecture and patterns, and produces a detailed spec referencing actual files and functions to reuse. Updating an existing feature plan:
The notification spec needs to also handle silent push for background data sync. Add a section covering the background modes capability and how it integrates with the existing sync service.The agent reads the existing
spec.md, incorporates the new requirement, and overwrites with the revised version — preserving sections that are still valid.
After the plan is ready, turn Plan off to implement.
With Plan off — building directly
This is the default. The agent executes your request directly — it writes code, builds the project, and iterates with you. Use it for anything that produces code: continuous feature-building, fast prototyping, and short, specific one-off tasks. You and the agent co-create: there’s an idea, there’s momentum, there’s a result. With Plan off, the agent:- Generates code, builds the project, and iterates with you
- Verifies its work (runs the project after changing Swift sources)
- Suggests alternatives and improvements
- Can ask you clarifying questions via structured prompts
- Commits after completing a logical unit of work (asking you first)
spec.md for context and implements from it. On its own, Plan off doesn’t write a spec — it goes straight to the code.
Working directly isn’t “sloppy.” The agent still follows the project’s architectural rules (RIBs or MVVM), uses semantic design tokens, and structures modules correctly. It just doesn’t write a formal plan before it starts.
How it works
Plan off handles two kinds of request, and the agent picks the right shape per turn:- Execute — an imperative request (“build the project”, “fix the crash in ProfileViewModel.swift:42”, “extract this into a helper”). The agent does the work, verifies it (runs the project if Swift sources changed), and reports what changed with file/line citations.
- Answer — a question (“why is the build failing?”, “what does this function do?”, “where is the device list populated?”). The agent reads the relevant files and answers directly, with citations — it doesn’t start editing code just to answer.
spec.md and implements from it — you get the best of both worlds: thorough planning followed by fast execution.
When to use it
- You’re validating an idea and want to see results fast
- You want a clickable prototype quickly
- Requirements aren’t fully clear yet — you want to iterate
- You’re implementing a feature that was already planned with Plan on
- You need a one-off action: a build, a debug session, a specific fix, a refactor
Prompt Examples
Starting from scratch:I want to build a habit tracker. The main screen shows today’s habits as a checklist. Tapping a habit marks it done with a satisfying animation. There’s a stats screen showing streaks.The agent starts with the main screen, then adds navigation and the statistics screen. After each step — build, verify, next step. Implementing a planned feature:
Let’s implement this. Start with the notification preferences screen.The agent reads the spec from your Plan-on session, picks up the first implementation step, and starts building. Iterating on what exists:
The habit list looks too plain. Let’s add a card-based layout — each habit is a rounded card with the habit icon on the left, name in the center, and a circular progress indicator on the right.The agent understands the context (which view to change), updates the layout, builds, and shows the result. Changing direction:
Actually, let’s pivot. Instead of a checklist, make it a ring-based UI like Apple’s Activity rings. Each habit is a ring, and filling it gives visual feedback.The agent handles pivots smoothly — generates the new UI and preserves what didn’t change (models, services). Technical request:
Add CloudKit sync. When a habit is completed on one device, it should appear on other devices within a few seconds. Use CKSubscription for real-time updates.You can give precise technical instructions. The agent doesn’t simplify — it follows your level of detail. Build:
Build the project.or
Build only the watchOS target.Build debugging:
The build is failing with “Cannot find type ‘ThemeProviding’ in scope” in TunerView.swift. Fix it.Give the agent the full error. It analyzes imports, module dependencies, and suggests a fix. Runtime debugging:
The app crashes on launch. The crash log shows EXC_BAD_ACCESS in SceneDelegate.swift line 14.The agent checks crash context, runtime logs, and suggests a fix. Precise edit:
In MainView.swift, change the navigation title from “Home” to use the localized string .mainScreenTitle instead.Refactoring:
Extract the booking flow (BookingDateView, BookingConfirmView, BookingPaymentView) into a separate SPM module called BookingFeature under Libraries/.
Feature Artifacts
Turning Plan on produces a written artifact — a feature spec — that Plan off then implements:
Plan off doesn’t create a spec of its own — it builds directly. But when a spec from a Plan-on session exists, Plan off reads it and implements from it. That’s the structured workflow: plan with Plan on, build with Plan off, against the same feature directory.
Case Studies
Case 1. “Build Me an App” — From One Sentence to a Prototype
Situation: You have an idea and want to see results as fast as possible. No specs, no requirements — just a sentence. Approach: Plan on (Refine) → Plan off Step 1 (Plan on / Refine):A meal planning app. You pick recipes for the week, and it generates a shopping list.The agent generates a PRD: weekly planner screen (calendar grid), recipe catalog (with mock data), auto-generated shopping list grouped by category. Immediately marks as deferred: backend, auth, sharing. Then scaffolds the project and writes a feature spec for the first iteration. Step 2 (Plan off):
Let’s build this. Start with the weekly planner screen — a horizontal scroll of 7 day cards. Tapping a day opens a sheet to add recipes.Then you iterate:
The day cards are too small on iPhone SE. Make them fill the width and stack vertically instead — a scrollable list of 7 rows.
Add a “Generate Shopping List” button at the bottom of the planner. It should aggregate all ingredients from selected recipes, merge duplicates (2 onions + 1 onion = 3 onions), and group by supermarket aisle.
The shopping list looks good but needs a “check off” feature — tapping an item strikes it through.From one sentence to a working prototype — a few hours.
Case 2. Complex UI from Figma
Situation: A designer created a detailed mockup in Figma. You need to translate it to code pixel-perfect. Multiple screens, custom components, animations. Approach: Plan off (with Figma MCP)Here’s the Figma design for the onboarding flow: https://figma.com/design/abc123/Onboarding?node-id=1-2 Build all 4 onboarding screens exactly as designed. Each screen has a full-bleed illustration, title, subtitle, and a “Continue” button. The last screen has “Get Started” instead. Add a page indicator at the bottom. Swipe gesture between screens.The agent pulls design context via Figma MCP (colors, fonts, spacing, layout), generates SwiftUI views with the closest matching semantic tokens, and builds the project. Iteration:
The illustration on screen 2 is clipped at the bottom on smaller devices. Make it aspect-fit instead of aspect-fill, and add 16pt bottom padding before the title.
Add a subtle parallax effect to the illustrations — as the user swipes, the illustration on the next screen should slide in slightly faster than the text.
Case 3. Adding a Feature to an Existing App
Situation: You have a working app and want to add a complex feature. You want the agent to understand the existing code before proposing changes. Approach: Plan on → Plan off Step 1 (Plan on):Add push notification support. Users should be able to opt in/out per category (promotions, reminders, social). Store preferences locally and sync with the backend. Show an onboarding prompt on first launch.The agent researches the codebase, identifies the existing architecture and patterns, and produces a detailed
spec.md referencing actual files, functions, and modules to reuse.
Step 2 (Plan off):
Let’s implement this. Start with the notification preferences screen.The agent reads the spec it just wrote, picks up the first implementation step, and starts building.
Case 4. Technical Feature: Camera + CoreML
Situation: You need to add object detection via the camera using CoreML. This is a UIKit-heavy feature (AVCaptureSession) that integrates into a SwiftUI wrapper. Approach: Plan off, with technical detailAdd a camera scanner feature to the app. Requirements:Notice: the prompt tells the agent which architecture to use (RIBs), which system frameworks (AVFoundation, CoreML, Vision), and where to place the code. The more technical detail you give, the more precise the result. Iteration:
- Use AVCaptureSession with the back camera, preview in a full-screen layer
- Run a CoreML model (YOLOv8 — I’ll add the .mlmodel file later, use a placeholder for now) on every nth frame
- Overlay bounding boxes on detected objects with labels and confidence scores
- In RIBs: create a ScannerRIB under Main. The interactor manages the capture session lifecycle. The view is a UIViewController with AVCaptureVideoPreviewLayer, not a SwiftUI view.
- Add a “Scan” button on the main screen that attaches the ScannerRIB.
The bounding box overlay flickers. The issue is likely that we’re updating UI on a background thread. Dispatch the overlay updates to the main queue. Also, add a confidence threshold — only show boxes with confidence > 0.7.
Case 5. “Fix My Build” — A Debug Session
Situation: After a refactoring, the project stopped building. Lots of errors, and you don’t want to dig through them yourself. Approach: Plan off (build + debug) Step 1:Build the project.The agent runs the build, gets the error log, analyzes it. Step 2 (the agent responds with analysis, you provide context):
Fix all the build errors. The refactoring was moving SettingsInteractor from the Main module to a new SettingsFeature module — some imports and dependency wiring are probably broken.Context about what you refactored helps the agent understand the root cause instead of just patching symptoms. Step 3 (if there are still errors after the fix):
Build again. If there are still errors, fix them too.An iterative build-fix cycle is a normal pattern. The agent keeps context between iterations.
Case 6. Prototype Evolution: From Quick Builds to Structure
Situation: You started with Plan off, built a prototype, and it grew to 12 screens. Now you want to add a complex feature (subscription with paywall, trial period, purchase restoration) and feel you need more structure. Approach: Plan on → Plan off (or a detailed Plan-off prompt) You can turn Plan on to get a thorough spec first, or give a spec-level prompt directly with Plan off:Add a subscription system with these requirements:This is a Plan-off prompt, but with planning-level detail. The agent implements step by step, building after each step.
- Paywall screen: Shown when user tries to access premium features. Two plans: Monthly (39.99). Highlight annual as “Best Value”. Show feature comparison table.
- Purchase flow: Use StoreKit 2. Handle: successful purchase, cancelled, failed, pending (Ask to Buy). Show appropriate UI for each state.
- Trial: 7-day free trial for annual plan. Show trial badge on paywall. When trial ends, auto-convert to paid (standard StoreKit behavior).
- Restore: “Restore Purchases” button on paywall and in Settings. Verify receipt server-side (mock the server call for now, return success).
- Premium gate: Create a PremiumAccessService that checks subscription status. Inject via @Environment. Premium features: unlimited habits (free = 5), custom icons, stats export.
- Entitlement check: On launch, verify current entitlements via StoreKit 2 Transaction.currentEntitlements. Cache status locally for offline access.
Prompting Tips
Detail Level Drives the Result
All three are valid prompts. The difference is how much you control the result.
Structure Complex Requests
For features with multiple components, use numbered lists. The agent treats them as checklists — implements item by item and marks them done.Attach Files for Context
You can attach files (images, documents, PDFs) to any prompt. The agent reads and incorporates them — useful for design references, PRDs from other tools, or API documentation. You can even send just an attachment with no text, and the agent will interpret it.Give Context When Debugging
Bad:“The app crashes.”Good:
“The app crashes when I tap the ‘Save’ button on the edit profile screen. Console shows: ‘Fatal error: Unexpectedly found nil while unwrapping an Optional value’ in ProfileViewModel.swift.”
Reference Specific Files
“InSpecific file + specific UI element + specific change = the agent doesn’t waste time searching.BookingView.swift, the date picker is showing dates in the past. Add aminimumDateconstraint set to today.”
Pivoting Is Normal
With Plan off you can change direction at any time. The agent adapts on the spot. You don’t need to start a new project — just say:“Scrap the tab-based navigation. Let’s switch to a sidebar layout — the sidebar shows categories, and the main area shows the selected category’s content.”
Toggling Plan Is Free
Plan on and Plan off share the same project context. The agent picks up all context automatically — active feature, constitution, knowledge base.Summary: Plan on or Plan off?
Modaal uses the same knowledge base, constitution, and architectural templates either way. The difference isn’t in code quality — it’s in how much planning happens before the code gets written.