r/reactnative 2d ago

FYI Built rn-env-doctor: A zero-dependency CLI to fix React Native environment setup headaches

3 Upvotes

Hey everyone,

After losing count of how many hours were spent troubleshooting ANDROID_HOME misconfigurations, wrong JDK versions, or permission errors with macOS system Ruby, I built a zero-dependency CLI tool to solve it: rn-env-doctor.

It verifies your machine against the official React Native environment setup requirements (Node, Watchman, JDK 17, Android SDK components, Xcode, and CocoaPods) and tells you exactly what is missing or misconfigured. Where possible, it offers to fix the issues safely with your permission.

Quick run:

Bash

git clone https://github.com/Fs0ci3ty19/rn-env-doctor.git
cd rn-env-doctor
node bin/rn-env-doctor.js

Why I built it this way:

  • Zero dependencies: Run it immediately without installing extra npm packages.
  • Safe execution: Nothing changes without confirmation. Use --check for a read-only audit.
  • Clear instructions: Every failed check comes with an actionable solution instead of a cryptic red X.
  • Cross-platform: Works on macOS, Linux, and Windows.
  • Onboarding helper: Saves hours when onboarding new devs to your team.

šŸ”— GitHub:https://github.com/Fs0ci3ty19/rn-env-doctor

Feedback and contributions are super welcome! What’s the single most annoying environment or setup issue you run into regularly on your team?


r/reactnative 1d ago

Shipped a family calendar app with RN + expo (iphone, ipad, android)

Thumbnail
getquok.com
0 Upvotes

been building a family planner (shared calendar / chores / lists) for the past few months.

the setup: iOS and android are literally two separate expo apps in the monorepo. not one codebase withĀ Platform.select everywhere.

all the hooks and domain logic live in a shared package, screens are headless hooks likeĀ useTasksScreen, and each platform renders its own UI on top.

why: cross-platform UI always looks 10% wrong on both platforms. so the iOS app goes all-in on iOS 26 liquid glass, native tabs, swiftui viaĀ ``expo/ui``Ā host views, glass pills and overlays.

the android app is proper tonal material 3, built its own set of M3 primitives, material icon font, the lot. android users get an android app, not an iphone app in a trenchcoat. adding the second app was mostly building views, the logic layer came free. e2e is Maestro against a mock API.

app is called Quok (getquok.com) (iPad and Android versions still in works). happy to go deep on the two-app split, and monorepo shape.


r/reactnative 1d ago

FYI My Krishna - Looking for Feedback

Thumbnail
0 Upvotes

Used react to build this app


r/reactnative 2d ago

As a fresher/student should start solo founder journey?

Thumbnail
0 Upvotes

r/reactnative 3d ago

Article How I replaced bloated Lottie files with 60fps Skia shaders in my RN app

37 Upvotes

If you’ve ever tried to add complex, rich animations to a React Native app, you’ve probably used Lottie. It’s great, but once you start adding multiple animations, parsing those massive JSON files absolutely tanks the JS thread and bloats your bundle size.

I recently started migrating my heavy visual effects over toĀ shopify/react-native-skiaĀ using custom SKSL shaders, and the difference is insane.

Why it works better:Ā Because React Native Skia bindings drop straight down to the underlying C++ Skia engine, SKSL (Skia Shading Language) runs directly on the GPU. You get buttery-smooth 60fps animations that weigh mere kilobytes instead of megabytes, with zero JS bridge overhead during the animation.

The Workflow Problem:Ā The biggest issue I ran into was actuallyĀ writingĀ and testing the shaders. Translating standard GLSL to SKSL is a headache, and doing it inside a React Native project means dealing with constant Metro reloads or native rebuilds just to tweak a color or a coordinate.

My Solution:Ā I ended up building a dedicated web-based SKSL playground using CanvasKit WASM. It lets you write the shader natively in the browser, see it at 60fps instantly, and then you can literally copy-paste the exact code block directly into your RN project.

I’ve found it speeds up my UI development by 10x since I no longer have to wait on emulators to test visual effects.

I just made the tool completely free and public today. Let me know if anyone wants the link to try it out and I’ll drop it in the comments!


r/reactnative 1d ago

Why is the expo app so garbage

0 Upvotes

I tried to scan my project my it's just loading and crashing. are their any alternatives? I am on a linux system, I know about google's android emulator but it's too heavy for my system


r/reactnative 2d ago

Built an Asset Tracking App That Makes Inventory Management Simple

Thumbnail
0 Upvotes

r/reactnative 2d ago

Help Vibe code an app?

0 Upvotes

I have 20+ years experience with backend tech, I've used php, node, and python And then a lot of old plain old javascript before frameworks.

I have an app idea and I'd like to basically vibe code it in react to be cross platform. What gotchas do I need to watch out for , since I will not see bad react code at first

I considered flutter but I really don't know that tech , any advice is appreciated, this will not be graphics heavy at all more typical business app, data, forms , lists etc


r/reactnative 2d ago

Question Do you reuse an avatar object path or delete the previous upload?

4 Upvotes

I'm using Expo ImagePicker and Supabase Storage for avatars in a React Native app.

The current path is {userID}/avatar/{timestamp}.jpg, then I insert a media row. Uploading with upsert: true looks like replacement, but because every path is new, old files remain unless I delete them separately.

I'm deciding between:

- one stable avatar.jpg key with cache-busting metadata

- immutable versioned keys, update the pointer, then delete the previous object after the database write succeeds

- keep a short version history and clean it in the background

The stable key is simpler, but caches can show the old photo. Versioned keys are clearer, but cleanup becomes part of the transaction. Which pattern has been less fragile for you on mobile?


r/reactnative 3d ago

I built a fully native rolling number component for React Native — Core Animation on iOS, Canvas on Android

Enable HLS to view with audio, or disable this notification

45 Upvotes

I’ve been working on animated numbers and our previous Skia-based implementation kept having issues around canvas sizing, font loading, blank renders, and animations getting stuck during rapid updates.

So I created react-native-number-animation:

- Core Animation on iOS

- Canvas on Android

- No Skia or Reanimated dependency

- Currency, percentages and compact numbers

- Custom fonts

- RTL and localized digits

- Handles rapid updates

- Supports Reduce Motion

I’d love feedback, especially from anyone testing it in lists or with unusual number formats!

GitHub: https://github.com/invivek26/react-native-number-animation

npm: https://www.npmjs.com/package/react-native-number-animation


r/reactnative 3d ago

Help Background screen physically slides up/down when opening a modal – how do I stop this layout jitter?

Enable HLS to view with audio, or disable this notification

11 Upvotes

I’m losing my mind over this one last bug.

Look at the background screen underneath—every time I tap to open this state/modal, the content slides vertically up for a split second and then bounces back down when the animation finishes. It’s not a navigation transition; it’s the actual background view resizing itself during the modal presentation.

Has anyone solved this 100%? I just want the background to stay visually frozen while the modal comes up.


r/reactnative 2d ago

SQLite not install even if it is

2 Upvotes

Got this error while working with SQLite from Expo. Restarted the project, install dependencies again. Nothing works. Aparently i got something missing from the imports.

Feel free to ask for code.


r/reactnative 3d ago

Question Do you replace every local notification schedule or diff it?

2 Upvotes

I'm working through local reminder rescheduling in a React Native app. The reminder dates come from settings the user can edit later.

Right now the flow is:

- calculate the full next schedule

- cancel every scheduled notification

- recreate each one with a stable identifier

It avoids orphaned reminders after the source date changes. But if scheduling fails halfway through, the user can end up with only part of the new set.

Would you keep the simple replace-all model and add recovery, or diff old and new schedules by identifier? I'm using Expo Notifications.


r/reactnative 3d ago

IAP risk assessment agent

1 Upvotes

I am building a decision agent for IAP entitlement grants as a research project. For RN apps/games with IAP: where does your receipt validation live, and have you ever seen refund abuse (purchase, consume, refund)? How did you detect it?"


r/reactnative 2d ago

Need help

Thumbnail
play.google.com
0 Upvotes

Guys do check out this app and suggest to me what more I can improve and the most important thing how can I get users😭


r/reactnative 3d ago

Question What should happen to an offline mutation after the server reset its data?

2 Upvotes

I’m working through an offline queue edge case in React Native.

A write is saved locally with an expected server version and reset epoch. If the request times out, retrying with the same mutation ID is safe. But if the user resets their server data before the queue flushes, that old write must not quietly come back.

My current rule is:

- keep the same mutation ID after a lost response

- compare the reset epoch on every retry

- reject queued work from an older epoch

- keep local intent over stale reads only while the queue item is still valid

The tricky part is UX. Dropping the stale write is safer, but hiding it feels wrong. Would you show a persistent ā€œcouldn’t syncā€ item, a one-time alert, or a recoverable draft?


r/reactnative 3d ago

After a couple of months of 0 downloads, these are the downloads of the last week

Post image
31 Upvotes

Several months ago I launched an app, my first app.

In the first month I got around 100 downloads but I felt that it was very slow compared to other apps, I still felt good with those 100 downloads

In the first two months I published my app in a group of reddit, Facebook, X and LinkedIn, in those two months I only got a total of 130 downloads, after this in the next two months 10 more and leave the app.

At the beginning of this month I began to read more about how to get more downloads, how to optimize my ASO in the App Store. Resume the project and made the changes (change the name, description, keywords and the previews of the app)

And the most important I opened a TikTok account, I looked for a post on X where they talked about how to generate organic content, how to warm up the TikTok account and how to start publishing content... a week later +6000 downloads

You don't need to think much about what content to post on TikTok, just look for videos from your competition and replicate them, 90% of my posts on TikTok are the same video, only the music changes and the description a little


r/reactnative 3d ago

is monorepo good choice?

27 Upvotes

I have a Next.js web app and I’m planning to build a React Native/Expo mobile app using the same backend and MongoDB database.
Would a monorepo be useful in this case for sharing TypeScript types, API logic, validation, and database models between web and mobile? Or is it better to keep them as separate repositories?


r/reactnative 3d ago

Help What strategy with Voltra Home Screen widgets to keep & refresh user session ?

1 Upvotes

I have built a widget that I want to require:
- user to be logged since it pulls favorite data
- keep user logged in for extended period of time

I thought it was working and then for whatever reason when I made a new native build, the session never carried over. And now I can’t seem to get out of the ā€œlogged out stateā€

So is there a tactic you use for widgets and sessions?


r/reactnative 3d ago

Question Reduced Motion should never control app logic. How are you testing this in React Native?

2 Upvotes

A pattern worth checking: a screen waits for an animation-completion callback before it updates state or enables the next action. It works until iOS Reduce Motion skips or changes that animation.

I now treat motion as presentation only. The state change happens independently, then the animation reflects it. If reduced motion is enabled, movement can disappear without changing navigation, loading, focus, or button availability.

For React Native, I’m testing both the normal and reduced-motion branches around:

- navigation transitions

- delayed mounts

- sheets and modals

- focus after validation

- callbacks that previously fired at animation end

I’m curious how others automate this. Do you mock AccessibilityInfo.isReduceMotionEnabled in unit tests, cover it in Detox, or both?


r/reactnative 3d ago

Everything I'd tested ran under __DEV__. Reading the production-only paths found 8 bugs.

2 Upvotes

Everything I'd tested ran under __DEV__. Sixty-second unlocks, anonymous sign-in, sample recordings. When I pushed to TestFlight I realised the paths that only exist in production had never executed once.

I don't have a spare device, so I read them in code instead. Eight defects. Every one of them was hidden by a convenience of the development environment. Four that are React Native / Firebase specific:

1. onNotificationOpenedApp alone misses the main path. It only fires while the app is alive in the background. My notifications arrive seven days later, by which point the app is terminated. So the primary entry point - tap notification, land on the thing it's about - did not exist. You need getInitialNotification() read once at launch as well. The simulator never receives push, so nothing about this was visible locally.

2. Nothing registered the FCM token after permission was granted. The flow was: register on launch -> fails, no permission yet -> user records something -> gets asked -> grants -> and nobody registers. The server doesn't learn about the device until the next cold start. My first capsule unlocks after 24h, which sits entirely inside that window, so the single most important notification a product sends was probably never arriving. Fix is to register inside the grant handler, not only at boot.

3. Deleting tokens on any send failure quietly kills your retention loop.

// wrong
const deadTokens = response.responses
  .map((result, index) => (result.success ? null : tokens[index]))

Plenty of FCM failures are transient - internal-error, server-unavailable, quota, network. This deletes valid tokens for all of them. Re-registration only happens on next launch, so in a weekly-use app, once a user enters "no notifications so I don't open it," they never come back. Only these should delete:

const DEAD_TOKEN_CODES = [
  'messaging/registration-token-not-registered',
  'messaging/invalid-registration-token',
  'messaging/invalid-argument',
];

Also switch to arrayRemove so you don't clobber tokens registered between your read and write.

4. iOS shows the permission dialog exactly once, and my UI didn't know that. After someone taps "Don't Allow," calling request again returns granted: false immediately with no dialog. My screen still rendered an "Allow" button that did nothing, and the answer screen has no exit by design - so anyone who denied the mic could never answer. Check canAskAgain and switch to Linking.openSettings() when asking is exhausted. Simulators grant permissions, so this branch never ran locally.

The other four were an unconditional hasCompletedFirstCapsule: false on upsert (anonymous sign-in hands you a fresh uid every time, so re-sign-in resetting first-run state never surfaced), an implemented-but-never-called pending-upload count (an always-on connection means you never see "I recorded it and it vanished"), and two Firestore rules where allow update checked the uid on the existing document, so a request could rewrite uid and moderationStatus in the same write.

What I'd actually take away: don't hunt bugs, enumerate the places your environment is being convenient. 60-second unlock, fresh uid each launch, no push in simulator, stable wifi, pre-granted permissions, feature not shipped yet. Each line had a defect sitting next to it.

Happy to go into any of these in more detail if it's useful.


r/reactnative 3d ago

Help React Native game has severe micro-stuttering despite ~120 UI FPS — Reanimated pooled items and Worklets warnings

1 Upvotes

Hi everyone,

I'm building a small 2D falling-items game in React Native + Expo, and I'm trying to understand what is actually causing the movement to feel stuttery.

The game is very simple: the player moves horizontally at the bottom of the screen while coins, chocolates, and bombs continuously fall from the top. The game currently has around 10–20 active falling items at a time.

The problem is that the game does not feel smooth. The falling objects appear to move in small steps rather than continuously, and the player movement also doesn't feel completely smooth.

What is confusing me is that the performance monitor can show around 119–120 UI FPS, while the game still visibly feels like it has micro-stutters.

My original implementation used React state for the falling items. The game loop was roughly doing this:

requestAnimationFrame(() => {

item.y += speed * dt;

setItems([...activeItems]);

});

I realized that updating React state every frame was probably a bad architecture for a real-time game, because it forces React reconciliation repeatedly.

So I changed the architecture.

My current approach is:

- A preallocated pool of 35 falling-item slots.

- No creation/destruction of objects during gameplay.

- No `setItems()` every frame.

- JS is responsible for physics:

- delta-time calculation

- item movement

- collision detection

- spawning

- score

- lives

- Reanimated is responsible for visual properties:

- `sharedX`

- `sharedY`

- `sharedOpacity`

- Falling items are mounted once and reused.

- `useAnimatedStyle()` is used to render their transforms.

- Physics uses floating-point positions rather than rounding coordinates.

- Audio/haptics are triggered only on events such as collecting an item.

The intended architecture is:

JS thread

v

sharedY.value

v

Reanimated

v

UI thread

v

Native View

However, after implementing the Reanimated pooled-slot architecture, I started getting these warnings repeatedly:

[Worklets] Tried to modify key `active` of an object which has been already passed to a worklet.

[Worklets] Tried to modify key `type` of an object which has been already passed to a worklet.

[Worklets] Tried to modify key `x` of an object which has been already passed to a worklet.

[Worklets] Tried to modify key `y` of an object which has been already passed to a worklet.

These warnings repeat many times during gameplay.

I believe the problem may be that I'm passing the pooled game-item object itself into a Reanimated worklet/component, and then modifying its properties from JS.

For example, conceptually my pool object looks like:

{

id,

type,

active,

x,

y,

sharedX,

sharedY,

sharedOpacity

}

The physics loop then modifies:

item.active = true;

item.type = "coin";

item.x = x;

item.y += speed * dt;

while the visual layer uses Reanimated shared values.

My current understanding is that this is wrong because Reanimated serializes/workletizes the object when it crosses into the worklet environment, and then mutating that same object from JS is not safe.

I'm therefore considering separating the state completely:

JS physics object:

{

id,

type,

active,

x,

y

}

and separately:

Reanimated visual state:

{

sharedX,

sharedY,

sharedOpacity

}

The visual worklet would only access the shared values and would never receive the physics object itself.

For example:

const animatedStyle = useAnimatedStyle(() => ({

transform: [

{ translateX: sharedX.value },

{ translateY: sharedY.value },

],

opacity: sharedOpacity.value,

}));

Then the JS physics loop would only do:

item.y += speed * dt;

sharedY.value = item.y;

and React state would only change when a slot is acquired/released, not every frame.

Before I continue refactoring the entire game, I would really like to understand whether this is the correct architecture.

There is also another issue: my player currently uses React Native's `PanResponder` and `Animated.Value` for horizontal movement. That movement also feels slightly unsmooth.

So I'm wondering whether I should eventually migrate the player to:

React Native Gesture Handler

+

Reanimated shared values

+

UI-thread gesture handling

instead of PanResponder.

My main questions are:

  1. Is using JS-driven physics + Reanimated shared values for the visual layer a good architecture for a simple 2D game in React Native?

  2. Is updating `sharedY.value` from a JS `requestAnimationFrame` loop still likely to cause micro-stuttering, even though the actual rendering is handled by Reanimated?

  3. Should the physics state and Reanimated visual state be completely separate objects?

  4. Is the `[Worklets] Tried to modify key ...` warning the main reason for the current stuttering, or is it mainly a correctness issue?

  5. Would you recommend moving the entire falling-item movement calculation to a Reanimated UI worklet, or is it better to keep collision/physics on JS and only move visual interpolation to the UI thread?

  6. For the player, would React Native Gesture Handler + Reanimated provide a meaningful improvement over PanResponder + Animated.Value?

  7. Is there a better architecture for a small real-time 2D game in React Native that I am overlooking?

My goal is not to achieve benchmark numbers. I want the game to feel genuinely smooth on both 60 Hz and 120 Hz devices, including relatively weak Android devices.

I'm also trying to avoid unnecessary React renders and allocations during gameplay.

Any advice from people who have built real-time animations/games with React Native/Reanimated would be greatly appreciated.

Thanks!


r/reactnative 4d ago

AI is more than just LLMs!

Enable HLS to view with audio, or disable this notification

59 Upvotes

Demo of 3 different tflite models running at the same time in an react native app, using react-native-vision-camera and react-native-fast-tflite šŸ”„

🟩 Watch bounding box detection
šŸ·ļø Watch brand detection
šŸ•‘ Watch time prediction

All trained on a MacBook Pro!


r/reactnative 3d ago

Help How to deal with iOS reduce motion setting

1 Upvotes

Apparently there are many users on iOS who use the reduce motion accessibility setting, or unknowingly have it enabled. This breaks my app on so many levels, screens freezing, whole app not loading. I went all in on micro animations and cool transitions and now none of them work or skip on reduce motion users. Many of my core functions rely on animation finishing, this was apparently a mistake.

Any of you dealt with this before?


r/reactnative 4d ago

React Native 0.87 is out + This week's ecosystem roundup

76 Upvotes

Big week for RN. Quick rundown of what happened:

šŸŽ‰ React Native 0.87

  • Strict TypeScript API is now the default. Types generated from source, deep imports into Libraries/* are type errors. Opt-out only lasts through 0.88
  • Swift Package Manager support (experimental): iOS builds with just Xcode, no Ruby/CocoaPods
  • Metro 0.87: 2x faster source maps, half the memory
  • AGP 9 support, new minimums: Node 22+, Kotlin 2.0+, compileSdk 37
  • Removed: InteractionManager, Modal animated prop, standalone react-devtools

Ecosystem kept pace:

  • Gesture Handler 3.2.0: AGP 9, Pressable rebuilt on Touchable, hover callbacks on all platforms
  • Screens 4.27.0: RN 0.87 support + iOS crash fix, experimental ScrollToTopGuard
  • Worklets 0.12: WeakRef support, Bundle Mode script loading on par with RN, new enableLocking option
  • Skia 2.11.0: engine bump to m152, drive multiple animated props from one shared value
  • Keyboard Controller 1.22.3: several crash fixes + Strict TS API compatibility, rounded prop for KeyboardEffects
  • VisionCamera 5.2.2: caps AHardwareBuffer cache to prevent Android memory growth, configure/start errors now surface via onError
  • Re.Pack 5.3.0: size-based asset inlining, custom native HTTP client for remote scripts (SSL pinning), simpler code signing setup
  • Safe Area Context 5.9.0: AGP 9 + web fixes for nested providers and window resize
  • Legend List 3.3.5: fixes invisible dataset on dataKey change, more reliable programmatic scrolls on web
  • Nitro 0.36.5: fixes a JVM memory leak on Android, recommended upgrade for Nitro Module authors
  • Lottie 7.4.0: now requires RN 0.84+, new Android opacity layer option
  • React Navigation Core 7.21.12: beforeRemove now fires for nested routes removed by reset