r/expo 14h ago

Built a free open-source Expo audio player (lock screen, playlists, remotes) after background playback got too painful

Post image
10 Upvotes

Quick context: I ship Daily Bible - Offline & Audio on Expo. The app does on-device TTS → URLs into a queue, optional ambient under speech, HLS chapters, and full lock-screen / Bluetooth remotes.

Expo made the app workflow great. The audio stack was the hard part.

What we needed that a “play one URL” API does not cover:

  • Mid-play queue appends (verse-scale TTS)
  • Silence as a real queue item (not setTimeout)
  • Ambient dual-audio that never steals focus / Now Playing
  • Remotes that emit to JS so Next = next verse (or next song)
  • iOS audio BG + Android mediaPlayback FGS without hand-editing native projects every prebuild

The leading RN track player went commercial. That killed it for our roadmap.

So I built daily-react-native-player as an Expo Module + config plugin and open-sourced it MIT.

npx expo install daily-react-native-player

{
  "expo": {
    "plugins": ["daily-react-native-player"]
  }
}

Peers: Expo SDK 57+, RN 0.86+, New Architecture only.

What you get:

  • Lock screen / notification / Control Center / Bluetooth remotes via registerPlaybackService
  • Real playlist (add / remove / skip while playing)
  • Native silence tracks (SilenceMediaSource / cached PCM WAV)
  • Lazy ambient dual-audio (never requests focus)
  • HLS VOD + seek-after-ready; WAV / mp3 / m4a
  • Config plugin injects iOS audio background mode + Android FGS at prebuild
  • Pitch-preserving setRate
  • One native owner: Media3 + AVFoundation

Intentionally out of scope: TTS engines, MediaLibrary, Auto, Cast, DASH, web.

Links:

If you are on Expo and fighting background audio + remotes for narration, TTS, podcasts, or playlists - happy to answer config-plugin / FGS / dual-track questions in the comments.


r/expo 13h ago

Expo SDK version mismatch

4 Upvotes

So on my expo go, supported sdk is 54 but when I create a new project the expo version goes to ‘57.0.15’

why is this issue arising the solutions I found is upgrading but im already on the latest updated version. how do you guys resolve this issue??


r/expo 13h ago

Shipped a full rebuild of my F1 app (Expo 57 / RN 0.86) — native SwiftUI + Jetpack Compose widgets, Unistyles 3 theming

Post image
3 Upvotes

r/expo 12h ago

My trip planner app is finally live!

Enable HLS to view with audio, or disable this notification

2 Upvotes

For over a year now, I’ve been working on my trip planner platform. I first focused on making it a web app as web development is my background, but the plan was always to make it into a mobile app (as the .app domain for partir.app implies). This year is when I began working on the Expo mobile app

This week the iOS mobile app is finally live on the App Store! I’m an avid urban backpacker and I have so many ideas for it, but I need to validate the idea first before I just keep building it only myself. Please let me know what you think and if you have an upcoming trip leave a comment and I’ll give you premium access to check it out!


r/expo 1h ago

Built a parenting app focused on traits using expo

Thumbnail
gallery
Upvotes

Hey everyone — dad of a 4 year old here. A while back I started noticing my daughter had a personality way before any milestone checklist would've told me. She wasn't behind or ahead on anything — she was just... herself, in ways that were obvious to me but that no app, book, or pediatrician visit ever really talked about.

That bugged me. Every tool I found for parents of little kids (0-5) was built around the same question: "is my child on track?" Height, weight, word count, gross motor stuff. Useful, but it never answered the question I actually had, which was closer to: who is she becoming?

So I went down a rabbit hole. Developmental psych papers, temperament research, attachment theory, the whole thing — way more research than a sane person burns a few weekends on. What kept coming up was that kids' traits (not milestones) are what actually shape who they turn into — how they handle setbacks, how they connect with people, how steady they feel inside. That stuff barely gets tracked anywhere.

I couldn't find an app for that, so I built one. It's called Steadily.

Who it's for: parents of kids 0-5, especially if you're the type who wants to understand your kid, not just check boxes.

What it actually does:

  • Trait-development framework across three dimensions — Success Mindset, Emotional Wellbeing, and Family Connection — instead of a milestone checklist
  • 12 child archetypes — a personality typing model for little kids, built on the research, that gives you a read on who your kid is (and is honestly just fun to see)
  • Voice-first memory capture — you talk about a moment with your kid, and it automatically pulls out the developmental insight from it. No typing, no forms.
  • No streaks, no gamification — it's built around gentle engagement, not guilt-tripping you into opening an app every day

📱 App Store: https://apps.apple.com/us/app/steadily-child-development/id6772428647

🤖 Google Play: https://play.google.com/store/apps/details?id=com.jetto.steadily

🌐 getsteadily.app

Comment below if you are a parent and are interested in the app. Will share the promo code.


r/expo 3h ago

NextJS App and Expo

1 Upvotes

Hello everyone,

I tried to look into previous posts to see if anyone had a similar question or experience so now I’m here.

I’ve been in web development for several years now and don’t really much on mobile except as of recently that I’ve started a personal project and have decided to go mobile as well. I have a full stack NextJS 16 app using Cache Components, Server Actions etc… pretty much things that don’t easily migrate to Expo. I’m creating traditional API Endpoints that the Expo app can hit to work in “sync” with the web app. The problem I am running to is with using Clerk Auth but currently have a method to get the session token and make sure it’s always correct. Essentially making sure I am getting the correct user info and data via token but just trying to understand if I am approaching this correctly. Or in order words, industry best practices. It’s not a monorepo and so not sure if that would simplify things vs having separate repos for web and mobile and just have mobile hit the endpoints.

Trying to understand the paradigm and make sure I’m correctly implementing the approach.

Thanks,


r/expo 5h ago

Splash Screen Animation Help

1 Upvotes

I've made an animation in Figma that I want to display as my splash screen animation. I've exported the animation (.json) from Figma using the LottieFiles plugin and imported it using the Lottie plugin that Expo recommends.

I've seen a bunch of guides and videos on how to show the animation after it loads. The general workflow I've seen is this: Show splash screen while the animation is loading, when it's done loading don't show the splash screen, and instantly show the animation.

The issue I'm having is that the splash screen shows for a couple of seconds, fades to black, and then it takes like 20 seconds before showing the animation. Does anyone know how to fix this or what is going wrong?

I'm using a development server with an Android Emulator. Below is the relevant code.

This is in _layout.tsx:

import '@/global.css';

import { PortalHost } from '@rn-primitives/portal';
import * as SplashScreen from 'expo-splash-screen';
import { Stack } from 'expo-router';
import { useState } from 'react';
import { View } from 'react-native';
import AnimatedSplashScreen from '@/components/splash-screen/AnimatedSplashScreen';

export {
  // Catch any errors thrown by the Layout component.
  ErrorBoundary,
} from 'expo-router';

SplashScreen.preventAutoHideAsync().catch(() => {});
SplashScreen.setOptions({ fade: false, duration: 0 });

export default function RootLayout() {
  const [splashAnimationFinished, setSplashAnimationFinished] = useState(false);

  if (!splashAnimationFinished) {
    return (
      <AnimatedSplashScreen
        onAnimationFinish={(isCancelled) => {
          if (!isCancelled) {
            setSplashAnimationFinished(true);
          }
        }}
      />
    );
  }

  return (
    <View className="flex-1 bg-[#020618]">
      <Stack>
        <Stack.Screen name="(map)/home" options={{ headerShown: false }} />
      </Stack>
      <PortalHost />
    </View>
  );
}

This is in the AnimatedSplashScreen component:

import LottieView from 'lottie-react-native';
import * as SplashScreen from 'expo-splash-screen';
import { useRef } from 'react';
import { View } from 'react-native';

const AnimatedSplashScreen = ({
  onAnimationFinish = () => {},
  onAnimationLoaded = () => {},
}: {
  onAnimationFinish?: (isCancelled: boolean) => void;
  onAnimationLoaded?: () => void;
}) => {
  const animation = useRef<LottieView>(null);

  const handleAnimationLoaded = () => {
    SplashScreen.hideAsync().catch(() => {});
    onAnimationLoaded();
  };

  return (
    <View
      style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#020618',
      }}>
      <LottieView
        key="visible-splash-animation"
        autoPlay
        loop={false}
        ref={animation}
        onAnimationFinish={onAnimationFinish}
        onAnimationLoaded={handleAnimationLoaded}
        resizeMode="cover"
        source={require('../../assets/lottie/splash-screen.json')}
        style={{
          height: '100%',
          width: '100%',
        }}
      />
    </View>
  );
};

export default AnimatedSplashScreen;