Skip to content

fix!: upgrade nitro-modules to 0.35.0#172

Merged
mfazekas merged 3 commits intomainfrom
chore/nitro-compat
Mar 13, 2026
Merged

fix!: upgrade nitro-modules to 0.35.0#172
mfazekas merged 3 commits intomainfrom
chore/nitro-compat

Conversation

@mfazekas
Copy link
Collaborator

@mfazekas mfazekas commented Mar 5, 2026

Upgrades nitrogen CLI and nitro-modules runtime to 0.35.0. Fixes ArrayBufferHolderArrayBuffer rename and regenerates all nitrogen bindings.

Nitro 0.35 made generated ViewManagers final (nitro#1181), which broke our RiveViewManager.onDropViewInstance() override needed for proper view lifecycle cleanup (#46). Added a nitrogen postprocess script that patches HybridRiveViewManager back to open so we can subclass it again.

Without onDropViewInstance, onDetachedFromWindow disposes Rive resources on every navigation (not just permanent removal), causing state loss. GC-based cleanup was tested and confirmed unreliable — neither Hermes GC nor JVM GC triggers dispose.

Added test for navigation lifecycle on onDetachedFromWindow:

Verified that it's broken without the workaround

   override fun onDetachedFromWindow() {
-    if (willDispose) {
+    if (true || willDispose) {
       riveAnimationView?.dispose()
       removeEventListeners()
     }
image
Reproducer: NavigationLifecycle.tsx

Uses counter.riv with a tap counter. Navigate to QuickStart and back; without the fix the counter resets to 0.

import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { useRouter } from 'expo-router';
import { Fit, useRiveFile, RiveView } from '@rive-app/react-native';
import { type Metadata } from '../../shared/metadata';

function RiveGraphic() {
  const { riveFile, isLoading, error } = useRiveFile(
    require('../../../assets/rive/counter.riv')
  );

  if (isLoading) {
    return (
      <View style={styles.loadingContainer}>
        <Text>Loading...</Text>
      </View>
    );
  }

  if (error || !riveFile) {
    return (
      <View style={styles.errorContainer}>
        <Text>Error: {error ?? 'No file loaded'}</Text>
      </View>
    );
  }

  return <RiveView file={riveFile} fit={Fit.Contain} style={styles.rive} />;
}

export default function NavigationLifecycle() {
  const router = useRouter();

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Navigation Lifecycle Test</Text>
      <Text style={styles.description}>
        This screen has a Rive view. Navigate to another Rive screen and back to
        test lifecycle handling.
      </Text>
      <Text style={styles.steps}>
        1. This screen shows Rive graphics{'\n'}
        2. Tap button to go to QuickStart (another Rive screen){'\n'}
        3. Press Back to return here{'\n'}
        {'\n'}
        If the fix works, no crash should occur.
      </Text>

      <RiveGraphic />

      <TouchableOpacity
        style={styles.button}
        onPress={() => router.push('/QuickStart' as any)}
      >
        <Text style={styles.buttonText}>Go to QuickStart (has Rive)</Text>
      </TouchableOpacity>
    </View>
  );
}

NavigationLifecycle.metadata = {
  name: 'Navigation Lifecycle',
  description: 'Tests Android lifecycle handling during navigation (PR #46)',
} satisfies Metadata;

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#fff', padding: 16 },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 16, textAlign: 'center' },
  description: { fontSize: 16, color: '#666', marginBottom: 12 },
  steps: { fontSize: 14, color: '#333', backgroundColor: '#f5f5f5', padding: 16, borderRadius: 8, marginBottom: 16, lineHeight: 22 },
  button: { backgroundColor: '#6c5ce7', padding: 16, borderRadius: 8, alignItems: 'center', marginTop: 16 },
  buttonText: { color: '#fff', fontSize: 16, fontWeight: 'bold' },
  rive: { width: '100%', height: 200, backgroundColor: '#f0f0f0' },
  loadingContainer: { width: '100%', height: 200, justifyContent: 'center', alignItems: 'center', backgroundColor: '#f0f0f0' },
  errorContainer: { width: '100%', height: 200, justifyContent: 'center', alignItems: 'center', backgroundColor: '#ffebee' },
});

BREAKING CHANGE: minimum nitro-modules version is now 0.35.0

Closes: #169

@mfazekas mfazekas changed the title chore: upgrade nitrogen to 0.35.0, widen nitro-modules peer dep fix: widen nitro-modules compatibility to support 0.33–0.35 Mar 5, 2026
@mfazekas mfazekas force-pushed the chore/nitro-compat branch 2 times, most recently from 01df5d8 to 9e29643 Compare March 5, 2026 13:48
@mfazekas mfazekas changed the title fix: widen nitro-modules compatibility to support 0.33–0.35 fix!: upgrade nitro-modules to 0.35.0 Mar 5, 2026
@r-variichuk
Copy link

is it possible to have it merged and released some time soon ? 🙏

@mfazekas mfazekas requested a review from HayesGordon March 13, 2026 07:32
@mfazekas mfazekas force-pushed the chore/nitro-compat branch from 9e29643 to 37f7ff5 Compare March 13, 2026 07:40
@mfazekas mfazekas force-pushed the chore/nitro-compat branch 2 times, most recently from cc332b0 to 789cabd Compare March 13, 2026 12:39
@mfazekas mfazekas requested a review from HayesGordon March 13, 2026 12:51
BREAKING CHANGE: minimum nitro-modules version is now 0.35.0
Nitro 0.35 generates final ViewManager classes, preventing
onDropViewInstance override needed for view lifecycle cleanup.
Added a postprocess script to patch the generated class as open.
@mfazekas mfazekas force-pushed the chore/nitro-compat branch from 789cabd to a4edac3 Compare March 13, 2026 12:53
HayesGordon
HayesGordon previously approved these changes Mar 13, 2026
Copy link
Contributor

@HayesGordon HayesGordon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@mfazekas mfazekas force-pushed the chore/nitro-compat branch 2 times, most recently from dd11130 to 5108456 Compare March 13, 2026 14:40
Verifies RiveView preserves state after screen detach/reattach using
react-native-screens ScreenContainer.
@mfazekas mfazekas force-pushed the chore/nitro-compat branch from 5108456 to 866a079 Compare March 13, 2026 15:10
@mfazekas mfazekas requested a review from HayesGordon March 13, 2026 15:13
@mfazekas mfazekas enabled auto-merge (squash) March 13, 2026 15:32
@mfazekas mfazekas merged commit c989fa5 into main Mar 13, 2026
9 checks passed
@mfazekas mfazekas deleted the chore/nitro-compat branch March 13, 2026 15:40
mfazekas pushed a commit that referenced this pull request Mar 13, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.3.0](v0.2.8...v0.3.0)
(2026-03-13)


### ⚠ BREAKING CHANGES

* minimum nitro-modules version is now 0.35.0

### Bug Fixes

* upgrade nitro-modules to 0.35.0
([#172](#172))
([c989fa5](c989fa5)),
closes
[#169](#169)

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants