Files
Eli White 60e3921f9c Initial Open Sourcing of React Native Compatibility Check (#49340)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49340

This tool enables checking the boundary between JavaScript and Native for
backwards incompatible changes to protect against crashes.

This is useful for:

- Local Development
- Over the Air updates on platforms that support it
- Theoretically: Server Components with React Native

Check out the Readme for more information

Changelog: [General][Added] Open Sourcing React Native's Compatibility Check

Reviewed By: panagosg7

Differential Revision: D69476742

fbshipit-source-id: 8af6039839c5475c1258fa82d9750a9320cf0751
2025-02-12 08:24:13 -08:00

1.8 KiB
Raw Permalink Blame History

This tool is essentially a type checker, and as such it can be difficult to understand the data flow. Luckily, there are fairly extensive tests which can aid in ramping up.

This tool is made up of 3 primary stages: TypeDiffing, VersionDiffing, and ErrorFormatting.

At a high level, the schemas are passed to TypeDiffing which is the pure typechecker. It returns all differences between the types. VersionDiffing then interprets these results and decides if some of those changes are actually safe in the context of React Natives JS/Native boundary.

For example, if you have a NativeModule method that returns a string union small | medium | large. Any changes to that union would be flagged by TypeDiffing as incompatible. However, adding a value to that union is safe because it ensures your JS code handles more cases than native returns. Removing a value from that union isnt safe though because it means your JS no longer handles something native might return which could cause an exception.

VersionDiffing encodes the logic of what is safe and what isnt; property/union/enum additions and removals, changing something from optional to required and vice versa, etc. VersionDiffing has knowledge of components and modules.

VersionDiffing returns a set of incompatible changes, which then gets passed to ErrorFormatting. ErrorFormatting does as youd expect, converting these deep objects into nicely formatted strings.

When contributing, some principles:

  • Keep TypeDiffing and ErrorFormatting pure. They should only know about JavaScript types, not React Native specific concepts
  • Add tests for every case you can think of. This codebase can be complex and hard to reason about when making changes. The only way to stay sane is to be able to rely on the tests to catch anything bad youve done. Do yourself and future contributors a favor.