◉RORK LABJP
●GPT6SOL — Rork added GPT-6 Sol to its model menu on September 22. It offers Low, Medium and High effort and is included in Pro and Max●11/01 — Apps that were granted a Google Play target API level extension must be updated by November 1, thirty-seven days from now●EXPOIMAGE — An expo-image report shows Android apps crashing when an image fails to load while its view is being resized●NEW — When an Android crash leaves a blank screen that looks frozen●RN0.88 — React Native 0.88 stable is scheduled for October 12. No first-party date for the SDK 58 stable release yet●ENROLL — Enrolling in the Apple Developer Program as an individual or an organization affects your store name and later transfers●GPT6SOL — Rork added GPT-6 Sol to its model menu on September 22. It offers Low, Medium and High effort and is included in Pro and Max●11/01 — Apps that were granted a Google Play target API level extension must be updated by November 1, thirty-seven days from now●EXPOIMAGE — An expo-image report shows Android apps crashing when an image fails to load while its view is being resized●NEW — When an Android crash leaves a blank screen that looks frozen●RN0.88 — React Native 0.88 stable is scheduled for October 12. No first-party date for the SDK 58 stable release yet●ENROLL — Enrolling in the Apple Developer Program as an individual or an organization affects your store name and later transfers
Articles/Getting Started
◈ Getting Started/2026-09-25Beginner

Building the Same Gallery Grid with Opus 5.5 and GPT-6 Sol in Rork — Choosing a Model by Its Effort Steps

Rork's model menu now lists Opus 5.5 and GPT-6 Sol. I built the same three-column gallery screen with both, compared their effort settings, and kept the code I'd actually ship. Here is what differed and how I chose.

Rork572Opus 5.5GPT-6 Soleffortgallery screenFlatList10expo-image7model choice

On Monday morning I opened a Rork project and the model menu had changed. Claude Opus 5.5 and GPT-6 Sol were sitting next to GPT-6 Astra, which had arrived earlier. The changelog entry is dated September 22 and says both are included in the Pro and Max plans; on the free plan, the menu shows you which plan unlocks them.

Whenever a new model shows up, there is one thing I always do first. I ask it to rebuild the three-column gallery screen I've been refining in my wallpaper app for years. Thumbnails in a grid, tap to open, pull to refresh — nothing more. It's a small screen, but it's the fastest way I know to feel how a tool behaves.

This time I built that one screen with Opus 5.5 and again with GPT-6 Sol. Below is how I set the effort level on each, where the two diverged, and which one I decided to keep using.

Decide the screen before you decide the model

If I may put the conclusion first: write the full spec of the screen before you pick a model. If the spec is still moving while you compare two models, you'll never know afterwards whether a difference came from the model or from your own wording.

Here is the single prompt I gave to both. I used it twice, word for word.

Build one gallery screen.
- Square thumbnails in 3 columns (size computed from the screen width)
- Tapping a thumbnail navigates to the detail screen /wallpaper/[id]
- Pull down to reload the list
- Use expo-image for the images
- Use a placeholder array of 12 items; loading must live in one place so I can swap in an API later
- Do not add anything not listed here: no search, no favorites, no tabs

That last line turned out to be the one that mattered most. Unless you say up front not to add unlisted features, a model will helpfully add them, and reading and removing the extras takes longer than writing the prompt did.

Opus 5.5 — why I moved effort back down to Medium

Opus 5.5 offers five effort steps: Low, Medium, High, Extra High, and Max. I picked Max without thinking. More steps meant the top one must be best — that was my assumption.

It didn't go well. The generation took a long time, and the screen came back with a favorites heart and an empty search bar, even though the prompt explicitly said not to add them. Raising effort seemed to push the model to think past the edges of the instruction — at least that is how it looked on my machine.

I restored to the earlier point and sent the same prompt at Medium. This time I got exactly the three-column grid, pull-to-refresh, and navigation to the detail screen. Loading was gathered into a single reload function, so there was no doubt where the API call would go later.

That is where I drew a line for myself. When the spec is fully written, start effort from the bottom. I only turn it up when I haven't managed to write the spec.

GPT-6 Sol — three effort steps, and where it differed

GPT-6 Sol has three effort steps: Low, Medium, and High. With fewer steps, my hand doesn't hover over the menu. To keep the comparison fair, I sent the identical prompt at Medium.

The skeleton that came back was strikingly similar. A FlatList with numColumns for the three columns, cell size computed from the window width, expo-image for thumbnails. Up to that point, the two were the same.

The differences were in two details. For column spacing, Sol put gap on columnWrapperStyle, while Opus gave each cell its own margin. For the empty state, Sol added a "No wallpapers yet" message I hadn't asked for; Opus left it blank. Neither is wrong. What showed through was each model's temperament in filling the parts I hadn't specified.

I tried Low as well. It returned a version where refreshing didn't toggle back on every reload, and I had to ask for a fix. For this screen, the middle of the three steps was the right place to sit.

The gallery screen I kept — readable even if you don't write code

After lining up both outputs, here is the version I kept. If you don't write code, you only need to follow three spots: the COLUMNS number, the SAMPLE array, and where onPress goes.

import { useCallback, useState } from "react";
import { FlatList, Pressable, StyleSheet, Text, useWindowDimensions, View } from "react-native";
import { Image } from "expo-image";
import { useRouter } from "expo-router";
 
type Wallpaper = { id: string; title: string; thumb: string };
 
const COLUMNS = 3;   // change the column count here and nowhere else
const GAP = 4;
 
// The image host comes from an env variable (only EXPO_PUBLIC_ names reach the app)
const IMAGE_BASE = process.env.EXPO_PUBLIC_IMAGE_BASE ?? "";
 
// Placeholder data to be replaced by the API later
const SAMPLE: Wallpaper[] = Array.from({ length: 12 }, (_, i) => ({
  id: String(i + 1),
  title: `Sample ${i + 1}`,
  thumb: `${IMAGE_BASE}/thumb-${i + 1}.jpg`,
}));
 
export default function GalleryScreen() {
  const { width } = useWindowDimensions();
  const size = (width - GAP * (COLUMNS + 1)) / COLUMNS;   // cell size from the screen width
  const router = useRouter();
  const [items, setItems] = useState<Wallpaper[]>(SAMPLE);
  const [refreshing, setRefreshing] = useState(false);
 
  // Loading lives here and only here. Swap this body for the API call later
  const reload = useCallback(async () => {
    setRefreshing(true);
    try {
      await new Promise((resolve) => setTimeout(resolve, 600));
      setItems((prev) => [...prev].reverse());
    } finally {
      setRefreshing(false);
    }
  }, []);
 
  return (
    <FlatList
      data={items}
      numColumns={COLUMNS}
      keyExtractor={(w) => w.id}
      contentContainerStyle={{ padding: GAP }}
      columnWrapperStyle={{ gap: GAP, marginBottom: GAP }}
      refreshing={refreshing}
      onRefresh={reload}
      renderItem={({ item }) => (
        <Pressable
          accessibilityLabel={item.title}
          onPress={() => router.push({ pathname: "/wallpaper/[id]", params: { id: item.id } })}
          style={{ width: size, height: size }}
        >
          <Image
            source={{ uri: item.thumb }}
            style={StyleSheet.absoluteFill}
            contentFit="cover"
            transition={150}
          />
        </Pressable>
      )}
      ListEmptyComponent={
        <View style={styles.empty}>
          <Text>No wallpapers yet</Text>
        </View>
      }
    />
  );
}
 
const styles = StyleSheet.create({
  empty: { padding: 32, alignItems: "center" },
});

A word on each choice. I took Sol's gap for the spacing — per-cell margin is a common reason the last column ends up a few points narrower than the others. I also kept Sol's empty state. The try / finally is mine: if a reload fails, refreshing must not stay stuck on.

The cell size comes from useWindowDimensions so the three columns hold on iPad and in landscape. I once had to rework a wallpaper screen laid out with fixed widths when the app moved to iPad, and since then this one line goes in from the start.

How I decided which one to keep using

Here is the side-by-side.

ItemClaude Opus 5.5GPT-6 Sol
Effort steps5 (Low / Medium / High / Extra High / Max)3 (Low / Medium / High)
Step I used for this screenMedium (Max added features)Medium (Low left refreshing broken)
How it fills unspecified partsLeaves them outAdds an empty state
Plans that include itPro / MaxPro / Max
What I use it forWriting out a screen whose spec is settledA first draft when the spec still has holes

If you are on the free plan, choosing either of these shows the plan that unlocks it. Before paying, it helps to separate whether you're stuck on price or on how you're writing the prompt. On this one screen, I confirmed twice that the cause was my prompt.

Rork rewrites code on every generation, so whichever model you continue with, you'll want a habit of reading only the lines that changed. My routine is in "Reading only what Rork rewrote — the diff review I run on every re-export". For the SwiftUI side, where I tested how far Rork Max can be trusted feature by feature, see "Testing Rork Max's SwiftUI native generation across 30 features".

Pick the smallest list screen in your own app, copy just the "do not add anything not listed here" line from the prompt above, and build it once with each model at Medium. Turning effort up can wait until after that.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Dev Tools2026-06-19
When Rork-Built Lists Stutter: Designing Image Caching and Prefetch
A FlatList from Rork starts stuttering once the images pile up. Here is how I restore smoothness with expo-image caching, recyclingKey, prefetch, and a move to FlashList, with the device numbers I measured.
◈ Getting Started2026-09-20
Two logins to check first when Expo Go stops opening your preview
When the QR code stops loading your Rork preview on a real device, check the logins before the router. Here is which path needs a sign-in on both ends, and which paths are untouched.
◈ Getting Started2026-09-14
Rork No Longer Creates New Expo Projects: Keep Yours, or Rebuild It in SwiftUI?
You can no longer start an Expo project in Rork, but existing ones keep building and shipping. Here is how to decide whether to stay on Expo or rebuild in SwiftUI, and what quietly goes missing when you rebuild.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links