◉RORK LABJP
●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●SDK 58 — SDK 58 Beta has been out since Sep 15. The stable date is still unconfirmed●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 3 days left●Q&A — People are asking why expo-widgets render blank only in production builds●RORK — GPT-6.1 Sol was added on Sep 29, available on Pro and Max plans●NEW — Building an app for a client? Decide who owns the publishing account first●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●SDK 58 — SDK 58 Beta has been out since Sep 15. The stable date is still unconfirmed●RN 0.88 — React Native 0.88.x is scheduled for Oct 12, 3 days left●Q&A — People are asking why expo-widgets render blank only in production builds●RORK — GPT-6.1 Sol was added on Sep 29, available on Pro and Max plans●NEW — Building an app for a client? Decide who owns the publishing account first
Articles/Dev Tools
⬡ Dev Tools/2026-06-26Advanced

Keep Audio Playing in the Background and Add Lock Screen Controls in a Rork App

How to make a Rork-generated Expo app keep playing music or healing sounds in the background and expose lock screen and Control Center controls, with working expo-audio code and the platform-specific gotchas.

Rork577Expo213expo-audio4React Native238background audio3

✦ Premium Article

The first thing that betrays you when you build a sound app is the moment the audio that played perfectly in preview goes silent the instant you return to the home screen or lock the device. When I rebuilt Relaxing Healing — a sleep and meditation sound app I have run as a personal developer for years — in Rork, the freshly generated code only played in the foreground. For an app people use right before falling asleep, going silent the moment the screen turns off is a fatal flaw.

Rork outputs React Native (Expo) code, so this is not a Rork-specific problem; it is solved in Expo's audio configuration. But pasting the official minimal sample as-is gives you no lock screen play button, and on Android the audio quietly stops after a few minutes. Here is the implementation that makes both background playback and lock screen controls work, using expo-audio (Expo SDK 54), laid out in the order I hit each wall.

Why generated code stops in the background

"Just playing" audio and "keeping audio playing while the app is backgrounded" are, from the OS's point of view, two different permissions. The former works with the default audio session state; the latter only works once three things are all in place.

First, on iOS, unless you declare audio in the background execution modes, the audio session is suspended the moment the app moves to the background. Second, you need to switch the audio session itself into a mode that plays in the background. Third, on Android, unless you actively post a lock screen (media) notification, the OS stops the process's audio after about three minutes. Generated code usually satisfies none of these three.

1. Add expo-audio and declare background mode

Add expo-audio to the project you exported from Rork, and enable iOS background audio through the plugin configuration in app.json (or app.config.js). Writing it via the plugin sets UIBackgroundModes without you touching the native Info.plist.

{
  "expo": {
    "plugins": [
      [
        "expo-audio",
        {
          "microphonePermission": false
        }
      ]
    ],
    "ios": {
      "infoPlist": {
        "UIBackgroundModes": ["audio"]
      }
    },
    "android": {
      "permissions": ["android.permission.FOREGROUND_SERVICE", "android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"]
    }
  }
}

Build a dev build without this, and you get a low-reproducibility bug: it appears to work in the iOS simulator but stops the instant you background it on a real device. I burned half a day on exactly this gap, so I strongly recommend declaring it up front. After changing the config you need npx expo prebuild and a rebuild (UIBackgroundModes is not honored in Expo Go).

✦

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
✦Turn a sound or music app that goes silent on screen lock into one that keeps playing with full lock screen controls
✦You'll learn the correct pairing of expo-audio's setAudioModeAsync and setActiveForLockScreen, with code that runs
✦Ship with the iOS/Android divergences already handled — the Android 3-minute cutoff and interruption recovery
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 $15 for lifetime access
View Membership →

Related Articles

⬡ Dev Tools2026-08-31
Three Minutes After the Screen Locked, My expo-audio Ambient Sound Went Silent
Why expo-audio stops playing when the screen locks, diagnosed as three separate layers: build config, audio session, and lock screen integration. The three-minute stop on Android is documented behavior.
⬡ Dev Tools2026-05-05
Taking a Rork Podcast App to Production — Migrating to expo-audio, Recovering from Interruptions, and Resumable Downloads
Implementation notes for making a Rork podcast app survive real use: migrating off expo-av before SDK 55 removes it, recovering from call interruptions, resuming broken downloads, and budgeting storage against iCloud backup.
⬡ Dev Tools2026-09-04
EAS secret visibility does not keep a value out of your app — deciding prefix and visibility separately
The EXPO_PUBLIC_ prefix decides what ships inside your app; EAS visibility decides who can read it. Why stacking them blanks a value on OTA updates, and how to check your build.
📚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