🚀 Just released my iOS app!
🎧 It’s called Tuneo — a clean, ad-free offline music player for iPhone.
I built it for myself because I couldn’t find a good way to play my own MP3s without ads or login walls.
Now it’s live on the App Store, and I’d love for you to try it!
📱 Import your own audio files
🎶 Edit tracks, manage playlists
📴 100% offline + runs in the background
🚫 No ads, no tracking, no login
App store: https://apps.apple.com/us/app/offline-music-player-tuneo/id6748915689
Website: https://tuneo.arcade.build/
Tech Stack
Built with React Native + Expo, using:
- expo-router for navigation
- react-native-track-player for audio playback
- expo-file-system, expo-media-library, and expo-document-picker for importing and managing files
- zustand for global state management
- shopify/flash-list for performance-optimized lists
And several other libraries for UI, blur effects, gestures, icons, and font support
No backend, everything runs locally on-device.
Challenges Faced While Building Tuneo
- Migrated from expo-audio to react-native-track-player to enable background audio and lock screen controls.
- Built a custom queue system with support for history, shuffle without immediate repeats, and repeat modes.
- Redesigned file storage architecture to avoid duplication and provide better user access via the iOS Files app.
- Used zustand with multiple stores to separate concerns and avoid race conditions in state management.
- Resolved iPad modal presentation issues by dynamically using fullScreenModal on iPad and modal on iPhone.
- Switched from FlatList to Shopify FlashList to ensure 60fps performance with large music libraries.
- Wrote detailed iOS permission descriptions to pass App Store review for file access and audio playback.
- Implemented support for multiple audio formats (MP3, FLAC, WAV, AAC, OGG, M4A) with robust error handling.
- Iterated import system from manual picking to batch import, folder scanning, and duplicate detection.
- Added reactive storage calculations to show real-time, accurate file space usage.
- Handled iOS audio session interruptions (calls, other audio apps) to maintain seamless playback state.
- Integrated native modules using Expo Dev Client and EAS build config for full native feature support.
Conclusion
Thanks so much for reading and if you give it a try, thank you even more. Just an indie dev trying to build something useful!!
Please consider following me on my socials.
X / Twitter: @ArcadeBuilds
Github: @the-arcade-01
Top comments (0)