RORK LABJP
PRICE — Rork Max spans $200 to $1,800 per month, with the upper tiers aimed at heavier builders and teamsFREE — The free tier lands at roughly five prompts per week, enough to try it but not to build on continuouslySHIP — App Store publishing is automated through builds, certificates, and submission, so you can ship an iOS app without a Mac or XcodeSIM — A browser-streamed simulator lets you watch your app run in a real Apple environment from your own browserNATIVE — It reaches HealthKit, ARKit and LiDAR, NFC, Dynamic Island, and Metal 3D — territory React Native cannot touchFUNDING — Rork raised a $15M seed led by Left Lane Capital, announced April 9, 2026, and acquired app builder PaperlinePRICE — Rork Max spans $200 to $1,800 per month, with the upper tiers aimed at heavier builders and teamsFREE — The free tier lands at roughly five prompts per week, enough to try it but not to build on continuouslySHIP — App Store publishing is automated through builds, certificates, and submission, so you can ship an iOS app without a Mac or XcodeSIM — A browser-streamed simulator lets you watch your app run in a real Apple environment from your own browserNATIVE — It reaches HealthKit, ARKit and LiDAR, NFC, Dynamic Island, and Metal 3D — territory React Native cannot touchFUNDING — Rork raised a $15M seed led by Left Lane Capital, announced April 9, 2026, and acquired app builder Paperline
Articles/Dev Tools
Dev Tools/2026-07-24Advanced

Resolving App Config in Three Layers: Merging Defaults, User, and Remote With Bounded Overrides

A single type-safe layer that merges compiled defaults, user preferences, and remote config. So a broken remote value never takes your app down, each key gets its own override strength, plus schema validation and range clamping, built from a real production incident.

Rork532React Native224Config ManagementRemote Config8Architecture22

Premium Article

Late one night I opened my own wallpaper app on my iPhone, and a full-screen ad appeared every time I swiped to the next image. Twice, three times, inside half a minute. My stomach dropped.

It wasn't a bug in the code. The interstitial cooldown value I kept in remote config had somehow been set to something tiny, and that value had shipped straight to the app. Worse, the same config was shared across all six of the wallpaper apps I maintain as an indie developer, so every one of them broke at once.

What this drove home for me was how dangerous the assumption "remote config is safe because I can fix it remotely" really is. Yes, you can push a fix quickly. But for the twenty-odd minutes it takes that fix to reach every device, the app keeps running, exposed. The place to defend was never the delivery side. It was the device receiving the value.

This article is about a design that merges three sources, compiled defaults, user preferences, and remote config, into one type-safe layer, so that a broken value can arrive without taking the app down. It's based on the code I put into all six apps after that night.

Start From the Fact That Config Has Three Sources

In most apps, config quietly ends up being three-layered whether you plan for it or not. Let me lay them out in order.

The first is the defaults compiled into the binary. They're always present, even offline. This is where the source of truth for types and initial values lives.

The second is user preferences. Stored locally on the device (AsyncStorage or MMKV), they represent choices the user made deliberately, things like prefetch count or theme.

The third is remote config. External input arriving from something like Firebase Remote Config, holding values the operator wants to change quickly for everyone, typically ad frequency or the timing of a review prompt.

The trouble is merging these three with a naive "last one wins" override. That night's incident happened precisely because remote could overwrite anything. Having three layers is unavoidable. What you must avoid is giving every layer the same strength.

Give Each Key Its Own Override Strength

The heart of the design is declaring, per value, who is allowed to override it and how far. I settled on three policies.

locked — nobody can override

A flag like which onboarding version to show breaks the experience if it flips by accident, so I mark it locked. Neither remote nor the user can touch it; it stays at its default. It's a safety valve, deliberately made immovable.

user — user preference wins

A pure preference like prefetch count gets the user policy. Remote stays out of it, and only the value the user chose overrides the default. It simply isn't a value the operator should be changing behind their back.

remote — allow overrides, but only within a range

A value the operator wants to tune, like the ad cooldown, gets the remote policy. But I don't trust it wholesale. Each key defines a min/max, and the incoming value is always clamped into that range. That 3-second value from the incident now arrives raised to a floor of 60 seconds.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A type-safe merge layer that resolves defaults, user prefs, and remote config with per-key override strength (locked / user / remote)
How to keep one broken remote value from cascading, per-key fallback to defaults plus min/max clamping, written out in full
The real config incident across six wallpaper apps and the operational calls it forced (how to set bounds, what to log)
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
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 $10 for lifetime access
View Membership →

Related Articles

Dev Tools2026-08-01
Every Experiment Kept Landing on the Same Devices: Hash Choice and Salt Position, Measured Across a Million IDs
On-device experiment assignment looked fine in isolation, then collapsed the moment two experiments ran side by side. Here is what one million IDs revealed about four hash functions, why the culprit was the concatenation order rather than hash quality, and the implementation I settled on, with the measured numbers.
Dev Tools2026-07-24
Collapsing Duplicate Requests Into One: A Reference-Counted Single-Flight Layer
When several components fire the same API call at launch, you get a burst of identical requests. Here is a single-flight layer that shares one in-flight promise instead: how to build the key that decides the folding, the trap of handing out a failed promise forever, the trap of one caller's abort cancelling everyone, and the test that keeps it all from regressing, with the real network numbers alongside.
Dev Tools2026-07-14
Designing Seams That Survive AI Regeneration in Rork
Every follow-up prompt to Rork can quietly wipe out logic you wrote by hand. Protecting it with prompts is a patch, not a fix. Here is how to separate generated code from code you own, and draw a boundary that regeneration cannot reach, with working Zustand and service-layer examples.
📚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
See all →