How RapidNative Generates Layouts Across Screen Sizes

SS

By Sanket Sahu

14th Sep 2026

Last updated: 14th Sep 2026

How RapidNative Generates Layouts Across Screen Sizes

The first time you build a React Native app after a decade of web work, one habit trips you up: reaching for md:. There are no media queries. There is no @screen breakpoint. The grid-cols-4 class you'd type without thinking on the web quietly does nothing on a phone. React Native throws away the entire CSS model most developers grew up with and hands you a single tool — Facebook's Yoga flexbox engine — plus a runtime dimensions API and expects you to make it work on a 320-pixel-wide iPhone SE, a 1366-pixel-wide iPad Pro, and a full-screen browser tab.

That constraint shapes everything about how RapidNative's AI generates code. When a user types "build me a fitness tracker with a workout grid and a stats screen," the generated layout has to render correctly on a device the user has never mentioned, in an orientation nobody agreed to, behind a notch that didn't exist last year. This post explains how we make that work — the system prompt rules, the template scaffolds, the two-preview pipeline, and the runtime primitives we rely on instead of media queries.

Multiple mobile devices showing responsive app layouts Cross-device responsive layouts on iOS, Android, and web — Photo by Domenico Loia on Unsplash

Why "Responsive" Means Something Different in React Native

React Native responsive design is layout that adapts at runtime using flexbox and the Dimensions API, not at compile time using breakpoints. The runtime measures the actual viewport when the app mounts, hands those numbers to the Yoga engine, and lets flex properties (flex, flexDirection, flexWrap, flexBasis) redistribute space. There is no equivalent of Tailwind's sm:, md:, or lg: prefixes for a native app.

That's a real mental shift. On the web, "responsive" means declaring how a layout should look at each breakpoint and letting the browser pick. On React Native, "responsive" means writing a single layout that works at any size because flex ratios, percentage widths, and safe-area insets do the redistribution for you. If you write your CSS in absolute pixels, your app breaks the moment somebody opens it on a Pixel 8 Pro. If you write it in flex ratios, it doesn't.

This has a knock-on effect on AI code generation. A model trained mostly on web code will happily emit w-1/4 md:w-1/2 and think it's being helpful. On React Native, md: is silently dropped by NativeWind. The result compiles, ships, and looks perfect at 375 pixels — then falls apart on a tablet. Preventing that is job number one for our system prompt.

The Three Pillars of Our Responsive Approach

Every generated RapidNative app rests on three interlocking primitives. None of them are novel individually. What matters is how the AI is instructed to combine them.

1. Flexbox with Computed Percentage Basis

Yoga runs the show. Every grid, row, column, and card in a generated RapidNative screen is a flex container. For multi-column grids specifically, the system prompt gives the model an explicit formula rather than trusting it to reinvent one on every generation:

Parent: flex-row flex-wrap gap-[x]
Default child: shrink-0 basis-[computed%] min-w-0

Compute basis as: (100% - (gap * (columns - 1))) / columns
Two columns → basis-[48%]
Three columns → basis-[31%]
Four columns → basis-[23%]

The formula bakes in gap accounting so that a four-column grid on a 375-pixel phone stays a four-column grid on a 428-pixel Pro Max — it's percentage-driven, not pixel-driven. The rule also explicitly bans flex-1 inside flex-wrap containers, because the combination breaks wrapping (Yoga expands the first row to fill available space and no children ever reach a second row). Two lines in the prompt cover a class of bug we used to see constantly.

2. SafeAreaView with Edge-Aware Configuration

The next primitive is react-native-safe-area-context. Every generated screen wraps its content in SafeAreaView, but how it wraps matters more than most tutorials admit. Tab screens need different insets from regular screens, because the tab bar already sits below the home indicator:

// Regular screen — protect all four edges
<SafeAreaView className="flex-1">
  {/* content */}
</SafeAreaView>

// Tab screen — the tab bar already covers the bottom
<SafeAreaView className="flex-1" edges={['top', 'left', 'right']}>
  {/* content */}
</SafeAreaView>

The system prompt spells this out because getting it wrong is one of the most common visual bugs in AI-generated mobile code — content that either hides behind a notch or floats above a doubled-up bottom bar. The edges prop is a runtime signal to react-native-safe-area-context about which insets to honor, and it resolves against whatever the OS reports for the current device: 59 points at the top of an iPhone with Dynamic Island, 44 on an older notched device, 20 on an iPhone SE, zero on most Android phones.

Person holding smartphone with app interface Safe-area handling adapts at runtime to notches, Dynamic Islands, and home indicators — Photo by NordWood Themes on Unsplash

3. NativeWind for Styling, With No Web Breakpoints

Generated apps use NativeWind 4.2 — a compiler that translates Tailwind class strings into React Native StyleSheet objects at build time. The tailwind.config.js in the fullstack-supabase scaffold ships without breakpoints defined:

module.exports = {
  content: ['./app/**/*.{js,jsx,ts,tsx}', './components/**/*.{js,jsx,ts,tsx}'],
  presets: [require('nativewind/preset')],
  theme: {
    extend: {
      colors: {
        background: 'rgb(var(--background) / <alpha-value>)',
        foreground: 'rgb(var(--foreground) / <alpha-value>)',
        // ...30+ semantic tokens driven by CSS variables in theme.ts
      },
    },
  },
};

There's no screens: { sm: ..., md: ... } block, because a native app doesn't have screens in the media-query sense. The result is a stylesheet that resolves once, at build time, using flex properties that redistribute at runtime. This is faster than the web equivalent (no reflow) and simpler to reason about (no cascade of overrides for each viewport).

The one thing the prompt explicitly bans is any pretense of web-style responsiveness. Classes like md:w-1/2, space-x-4, and grid-cols-3 are silently dropped by NativeWind — they compile without error but do nothing at runtime. Instead of trusting the model to remember that, we enumerate the unsupported classes in a dedicated UNSUPPORTED_TAILWIND_SECTION in the system prompt.

Runtime Sizing: When Percentages Aren't Enough

Some layouts genuinely need to know how big the screen is right now — hero images that should fill the width edge-to-edge, or carousels that need to snap at exactly one viewport per page. For those cases, RapidNative generates code that pulls dimensions from the runtime:

import { Dimensions, Image } from "react-native";

const screenWidth = Dimensions.get("window").width;

<Image
  source={{ uri: image }}
  style={{ width: screenWidth, height: 320 }}
  resizeMode="cover"
/>

The Dimensions.get('window') call returns the actual pixel width of the container the app is rendering into — 375 on a base iPhone, 428 on a Pro Max, 810 on an iPad, whatever the browser is currently set to on web. For content that needs to react to orientation changes, the prompt swaps in the hook form, useWindowDimensions(), which re-renders when the viewport changes. The result is a single component that behaves identically across every device without a single breakpoint.

The Two-Preview Pipeline: Design Time vs Runtime

There's a distinction inside RapidNative that shapes how users experience responsive layout, and it's worth surfacing because it explains a class of "why does it look different on my phone?" questions:

  • The editor preview renders the app inside an iframe at a fixed 375×812 artboard — iPhone X class. Safe-area insets are injected via CSS overlay (59 points top, 34 bottom) to simulate a Dynamic Island phone. This is running on a Lifo instance that reads the project's virtual file system.
  • The device preview runs on a real iOS or Android device via Expo Go, or via an orchd-managed workload for the web bundle. Safe-area insets come from the actual operating system. The layout Yoga produces is genuinely the layout the user sees.

The editor deliberately shows a single canonical viewport rather than a device switcher, and that's a design decision, not an oversight. Multi-artboard editors optimize for pixel-perfect layouts at every breakpoint, which is the wrong optimization for React Native. The right optimization is a layout written in flex ratios and percentage basis that adapts at runtime. Adding an artboard switcher would tempt users to fine-tune each size individually — the exact anti-pattern the framework is trying to move you away from.

For real cross-device testing, users scan a QR code and the same bundle runs on their actual phone. The two-preview architecture means a layout the AI generated in the editor iframe (375×812) is running unchanged on a Pixel 7 (412×915), a Galaxy Fold (285×653 folded, 673×841 unfolded), and an iPad Mini (744×1133). Yoga does the reflow. No breakpoints involved.

Developer testing app on multiple devices Testing generated code on real hardware — the layout the AI produced adapts at runtime — Photo by Nordwood Themes on Unsplash

Prompt Engineering: Where the Rules Actually Live

The interesting part of any AI code generator isn't the model — it's what you tell the model. RapidNative's system prompt is composed by a builder function (buildSystemPrompt) that assembles priority-ordered sections before every generation. The relevant ones for layout are:

SectionPriorityRole
ROLE_SECTION100Establishes the model as a React Native + Expo engineer
RESPONSIBILITIES_SECTION95Includes "responsive layouts optimized for multiple device sizes"
MOBILE_NATIVE_SECTION90Flex-row / flex-wrap / basis formula, image dimensions rule
UNSUPPORTED_TAILWIND_SECTION85Bans grid-cols-, space-x-, md: prefixes
IMPORT_RULES_SECTION84Forces react-native-safe-area-context, not RN's built-in
UI_DESIGN_SECTION60Edge spacing, minimum touch targets, WCAG contrast

The priority ordering matters. When the total prompt approaches the model's context budget, lower-priority sections are trimmed first. Responsive-layout rules sit near the top precisely because getting them wrong produces a broken app; UI polish rules sit lower because a slightly off-brand shade of blue is a cosmetic problem, not a functional one.

Template-specific rules stack on top of the core prompt. The nativewind-themed template — used for UI-first generations without a backend — adds a detailed set of rules about SafeAreaView edge configuration, ScrollView contentContainerStyle (because NativeWind's contentContainerClassName isn't supported), and gradient handling via expo-linear-gradient. Each rule exists because an earlier generation failed silently, and adding an explicit prompt line was cheaper than adding a runtime validator.

What Actually Ships: The Generated Dependencies

Every generated project pulls a specific, pinned stack. This isn't automatic — it's the scaffold in tools/project-templates/fullstack-supabase/scaffold/mobile/package.json, and it's what gives the AI a stable target to write against:

{
  "expo": "^57.0.19",
  "expo-router": "~57.0.18",
  "react-native": "0.86.3",
  "react-native-safe-area-context": "~5.7.0",
  "nativewind": "4.2.1",
  "tailwindcss": "3.4.18",
  "expo-linear-gradient": "~57.0.1"
}

Notably absent: any dedicated "responsive" library. No react-native-responsive-screen, no react-native-size-matters, no custom breakpoint hook. The stack ships flexbox, Dimensions, useWindowDimensions, and SafeAreaView — and that's genuinely all it needs. Adding another abstraction on top would fight the framework rather than lean into it.

Expo Router 57 is the piece that makes a single codebase render on iOS, Android, and web. The app/ directory structure works identically across all three targets. A file at app/(tabs)/index.tsx becomes the home tab on iOS, the same on Android, and a route at / in the web bundle. The AI writes one component and gets three platforms.

Cross-Platform Nuances the Prompt Handles

There are a handful of cross-platform differences that will bite a naive React Native codebase, and the prompt encodes rules for each:

  • Web bundle behavior: Expo Web renders the same components using react-native-web, but text selection, scroll behavior, and cursor styles differ from native. The generated _layout.tsx uses Stack without web-specific overrides — the defaults work.
  • Android status bar: iOS handles the status bar as part of the safe area automatically; Android often needs explicit StatusBar configuration. The prompt instructs the model to set StatusBar in the root layout, not per-screen.
  • Platform-specific extensions: React Native supports .ios.tsx, .android.tsx, and .web.tsx file extensions for platform-specific overrides. The prompt reserves these for genuine platform differences (haptics, native modules) rather than layout differences.
  • Keyboard handling: iOS pushes content up when the keyboard appears; Android resizes the viewport. The prompt uses KeyboardAvoidingView with a behavior prop that switches on Platform.OS.

Each of these rules exists because a prior generation shipped a bug that only manifested on one platform. Encoding the fix in the prompt is cheaper than encoding it in a validator, because the validator would only catch the mistake after the model made it.

How Users Verify a Layout Actually Works

Testing responsive behavior on generated code follows a two-step workflow that mirrors the two-preview pipeline:

  1. Iterate in the editor. The 375×812 preview is the fastest feedback loop — every AI edit re-renders in under a second, and layout regressions are visible immediately. This catches the majority of issues, because most generated bugs are structural (missing flex-wrap, wrong SafeAreaView edges, absolute widths).
  2. Verify on a real device. Scan the QR code and the same code runs in Expo Go on the user's actual phone or tablet. This catches the minority of issues that depend on device-specific chrome — Dynamic Island alignment, Samsung's rounded corners, iPad split-view.

For teams building an app that needs to run on tablets specifically, the workflow is to prompt for the base layout, verify it in the editor, scan the QR code to an iPad, and iterate on any issues from there. There's no separate "tablet mode" to switch into — the same code just works, because it was written in ratios from the start.

The Practical Takeaway

React Native responsive design isn't the web version with a different config file. It's a genuinely different model: layout is a runtime negotiation between the Yoga engine, the OS-reported viewport, and the safe-area insets. RapidNative's job is to consistently generate code that fits that model, and the way it does that is by baking the rules into the system prompt rather than into a post-generation validator.

The three primitives — flex with computed basis, edge-aware SafeAreaView, and NativeWind without web breakpoints — do most of the work. Dimensions and useWindowDimensions cover the edge cases where percentages aren't enough. The two-preview pipeline lets users see what the AI generated at a canonical viewport and then verify on real hardware. And the prompt engineering ensures the model doesn't reach for md: or grid-cols-4 out of web-shaped muscle memory.

If you want to see the generated output from a prompt, start a free RapidNative project — type in what you want, watch the layout render in the editor, then scan the QR to see the same layout adapt on your own phone or tablet. The whiteboard-to-app and PRD-to-app flows use the same generation pipeline described here.

FAQ

Does RapidNative use media queries or breakpoints?

No. React Native has no concept of CSS media queries, and NativeWind's sm:/md:/lg: prefixes are silently dropped in native builds. Generated apps rely on flexbox ratios, percentage basis, and the Dimensions API to adapt at runtime instead of at build-time breakpoints.

How does an app generated at 375×812 in the editor work on a tablet?

Because the layout is written in flex ratios and percentages rather than absolute pixel widths, Yoga (the layout engine) redistributes space at runtime based on the actual viewport. A four-column grid with basis-[23%] stays four columns on a phone and four columns on a tablet — each column is just wider on the tablet.

What handles the notch, Dynamic Island, and home indicator?

SafeAreaView from react-native-safe-area-context. The generated code specifies which edges to protect (all four for regular screens; top/left/right for tab screens), and the library resolves the actual inset values from the OS at runtime.

Does the generated app work on web as well as iOS and Android?

Yes. Expo Router uses the same app/ directory to produce iOS, Android, and web bundles. react-native-web translates the components into DOM elements for the web bundle. Users can share the QR-code preview as a URL that runs in a browser.

Can I switch to a tablet or landscape view in the RapidNative editor?

The editor renders a single canonical iPhone X viewport (375×812). To verify tablet or landscape behavior, scan the QR code from the editor onto a physical tablet, or open the web preview URL and resize your browser. The layout adapts at runtime rather than requiring a separate design pass per device.

Start now

Ready to build your app?

Turn your idea into a production-ready React Native app in minutes.

Free tools to get you started

Questions

Frequently asked questions

What is RapidNative?

RapidNative is an AI-powered mobile app builder. Describe the app you want in plain English and RapidNative generates real, production-ready React Native screens you can preview, edit, and publish to the App Store or Google Play.

Can I export the code?

Yes. RapidNative generates clean React Native and Expo code that you can export at any time. No lock-in, no proprietary format. Hand it to your developers or keep building inside RapidNative.

Is RapidNative free to use?

Yes. You can build apps on the free plan with no credit card required. Paid plans unlock unlimited AI generations, code export, and direct publishing to the App Store and Google Play.

Do I need to know how to code?

No. Most users build apps by describing what they want in plain English. Developers can drop into the code whenever they want more control, but coding is optional.

How long does it take to build an app?

Most users have a working first screen in under a minute. A full MVP usually takes a few hours instead of the weeks or months traditional development requires.