RORK LABJP
NATIVE — Rork Max reaches AR and LiDAR scanning, Metal-backed 3D, Dynamic Island, Siri Intents, HealthKit, NFC, App Clips, and on-device Core MLIOS27 — iOS 27 Developer Beta 4 extends Siri AI to iPhone 15 Pro and 15 Pro Max plus the 16 and 17 lines, with noticeably faster responses than the first betaDESIGN — Apple's own design kits for iOS, iPadOS, and macOS 27 are now available for Figma and Sketch, ready for when you lay out UI for the new OSCANARY — Android 17, codenamed Cinnamon Bun, retires Developer Previews in favor of continuously updated Canary builds, which changes when you schedule testingSPARK — Gemini Spark in Android 17 drives apps directly to automate multi-step errands like booking a ride or placing an orderSCALE — Rork raised $2.8M from a16z and now draws roughly 743,000 visits a monthNATIVE — Rork Max reaches AR and LiDAR scanning, Metal-backed 3D, Dynamic Island, Siri Intents, HealthKit, NFC, App Clips, and on-device Core MLIOS27 — iOS 27 Developer Beta 4 extends Siri AI to iPhone 15 Pro and 15 Pro Max plus the 16 and 17 lines, with noticeably faster responses than the first betaDESIGN — Apple's own design kits for iOS, iPadOS, and macOS 27 are now available for Figma and Sketch, ready for when you lay out UI for the new OSCANARY — Android 17, codenamed Cinnamon Bun, retires Developer Previews in favor of continuously updated Canary builds, which changes when you schedule testingSPARK — Gemini Spark in Android 17 drives apps directly to automate multi-step errands like booking a ride or placing an orderSCALE — Rork raised $2.8M from a16z and now draws roughly 743,000 visits a month
Articles/Dev Tools
Dev Tools/2026-06-21Advanced

Why "Save to Photos" Fails on Only Some Devices in Your Rork App — expo-media-library Permission Scopes and Save Design

Your Rork app's image-saving feature works perfectly on your phone but fails for a subset of users. The real cause is expo-media-library permission scopes. Here is a save flow and album design that handles writeOnly permission, iOS limited access, and Android 14 partial access.

expo-media-library3permissions7React Native218Rork526image saving

Premium Article

It never fails on my own iPhone, yet the reviews say "it won't save"

When you run a few wallpaper apps as an indie developer, an odd review shows up every so often: "I tap the button and nothing appears in Photos." On my own devices, it never fails — not during development, not before submission. And yet, one star at a time, the "it won't save" reports keep accumulating.

When I chased it on real devices, the cause was almost never a failed image download or a full disk. It was the permission scope of expo-media-library ending up in a state I hadn't anticipated, depending on the OS version and on a choice the user made in a permission dialog at some point in the past.

What makes this mismatch nasty is that it's hard to reproduce on a developer's device. Most developers tap "Allow Access to All Photos" on first launch and then develop with full access forever after. Real users, meanwhile, are a mix: some picked "Selected Photos Only," some chose "Allow only a portion" on Android 14, and some declined out of suspicion because the app demanded read access when all they wanted to do was save. Here, I'll share how to design a save-only permission correctly and build a save flow that absorbs these device differences.

Why saving succeeds on one device and fails on another

A expo-media-library grant is not a simple allow/deny binary. Each OS has tiers, and those tiers have grown finer year by year.

iOS holds photo-library access in four states: full access, limited access (the user can see only the photos they picked), denied, and "add-only." That last one — add-only — lets you save but never read existing photos. It is a save-only permission, and it is the key to this whole problem.

Android branches further by version. Android 12 and earlier used WRITE_EXTERNAL_STORAGE, Android 13 introduced READ_MEDIA_IMAGES, and Android 14 added partial access (READ_MEDIA_VISUAL_USER_SELECTED), the equivalent of "selected photos only." The tricky part: if your app only writes an image it created into Pictures/ via MediaStore, read permission is actually unnecessary from Android 10 onward. Despite that, if your implementation requests read permission anyway, you ask save-only users for a heavy grant, and your denial rate climbs.

Put plainly, three combinations decide whether a save succeeds.

FactorTypical developerThe user who gets stuck
iOS access stateFull accessLimited / add-only / denied
Android versionLatest test deviceBehavior differs on 13 and 14
Breadth of permission requestedRead + write togetherWants only to save, declines read

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
If reviews say "can't save" while it always works on your own device, you'll be able to isolate the per-device permission-scope differences and find the real cause
You'll get a save flow and album-creation code that handles writeOnly permission, iOS limited access, and Android 14 partial access, ready to drop into your own app
You'll design a save flow that doesn't swallow permission denials or album failures, and instead routes users to a path they can recover from themselves
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-04-23
Why Your Rork App Can't Save Images to the Camera Roll — A Complete Fix
Image and video saving often breaks the moment a Rork-generated app leaves the simulator. This guide walks through the permission model, expo-media-library quirks, and Android 13+ scoped storage changes that reliably trip people up.
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-30
What Renovate may bump in an Expo app, and what it must never touch
Turning on automated dependency updates in a Rork-generated app also hands Renovate the 123 packages Expo SDK 57 pins. Measured on 2026-07-30, six of them sit a full major version behind npm latest. Here is how to generate the ignore list from the SDK instead of maintaining it by hand.
📚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 →