Split up ts files in reanimated to .ts and .native.ts#9815
Conversation
a965607 to
39ffe1e
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors Reanimated’s platform-specific TypeScript sources to rely on file extensions (.ts vs .native.ts) rather than runtime SHOULD_BE_USE_WEB branching, and consolidates shared logic into new *Base.ts modules. This aligns module resolution with React Native’s platform file picking and reduces conditional logic inside single files.
Changes:
- Split multiple previously mixed platform implementations into
.ts(web/default) and.native.ts(native) pairs, often extracting shared code into*Base.ts. - Adjust platform-specific exports for core modules (events, props updates, layout animations, module instance creation, platform functions, hooks).
- Restructure web layout-reanimation animation/transition sources (rename from
*.web.tspatterns to plain.tswithin the web subtree).
Reviewed changes
Copilot reviewed 103 out of 119 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-reanimated/src/WorkletEventHandlerBase.ts | New shared/web WorkletEventHandler implementation extracted into base file. |
| packages/react-native-reanimated/src/WorkletEventHandler.ts | Web/default export now directly uses WorkletEventHandlerWeb. |
| packages/react-native-reanimated/src/WorkletEventHandler.native.ts | New native implementation with Jest fallback to web handler. |
| packages/react-native-reanimated/src/updateProps/updatePropsBase.ts | New shared types/helpers for updateProps + Jest wrapper and error proxy logic. |
| packages/react-native-reanimated/src/updateProps/updateProps.ts | Web/default updateProps implementation and global proxy setup. |
| packages/react-native-reanimated/src/updateProps/updateProps.native.ts | New native updateProps implementation with Jest/web fallback behavior. |
| packages/react-native-reanimated/src/UpdateLayoutAnimations.ts | Web/default no-op updateLayoutAnimations. |
| packages/react-native-reanimated/src/UpdateLayoutAnimations.native.ts | New native layout animation batching implementation (Jest no-op). |
| packages/react-native-reanimated/src/ReducedMotionBase.ts | New shared ReducedMotionManager factory. |
| packages/react-native-reanimated/src/ReducedMotion.ts | Web/default reduced-motion detection via matchMedia. |
| packages/react-native-reanimated/src/ReducedMotion.native.ts | New native reduced-motion detection via global flag. |
| packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.web.ts | Removed (previous web-only instance file). |
| packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.ts | Web/default now always creates JS module instance. |
| packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleInstance.native.ts | New native module instance with Jest fallback to JS module. |
| packages/react-native-reanimated/src/ReanimatedModule/NativeReanimated.ts | Replace SHOULD_BE_USE_WEB check with IS_JEST gating for dev-only error. |
| packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/webUtils.web.ts | Removed (web-only utils moved into shared default). |
| packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/webUtils.ts | Web/default now contains optional RN Web requires. |
| packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/webUtils.native.ts | New native stub exports for web-only utilities. |
| packages/react-native-reanimated/src/ReanimatedModule/index.web.ts | Removed (web-only index). |
| packages/react-native-reanimated/src/ReanimatedModule/index.ts | Web/default index creates JS module directly. |
| packages/react-native-reanimated/src/ReanimatedModule/index.native.ts | New native index re-exporting platform instance. |
| packages/react-native-reanimated/src/platformFunctions/setNativeProps.web.ts | Removed (web-only setNativeProps). |
| packages/react-native-reanimated/src/platformFunctions/setNativeProps.ts | Web/default setNativeProps uses _updatePropsJS. |
| packages/react-native-reanimated/src/platformFunctions/setNativeProps.native.ts | New native setNativeProps implementation with Jest warning. |
| packages/react-native-reanimated/src/platformFunctions/setGestureState.web.ts | Removed (web-only setGestureState). |
| packages/react-native-reanimated/src/platformFunctions/setGestureState.ts | Web/default setGestureState warns as unavailable. |
| packages/react-native-reanimated/src/platformFunctions/setGestureState.native.ts | New native setGestureState implementation with Jest warning. |
| packages/react-native-reanimated/src/platformFunctions/scrollTo.web.ts | Removed (web-only scrollTo). |
| packages/react-native-reanimated/src/platformFunctions/scrollTo.ts | Web/default scrollTo calls component scrollTo with safety checks. |
| packages/react-native-reanimated/src/platformFunctions/scrollTo.native.ts | New native scrollTo dispatches native command with Jest warning. |
| packages/react-native-reanimated/src/platformFunctions/measure.web.ts | Removed (web-only measure). |
| packages/react-native-reanimated/src/platformFunctions/measure.ts | Web/default measure based on DOM geometry. |
| packages/react-native-reanimated/src/platformFunctions/measure.native.ts | New native measure implementation with Jest warning. |
| packages/react-native-reanimated/src/platformFunctions/findNodeHandle.web.ts | Removed (web-only findNodeHandle shim). |
| packages/react-native-reanimated/src/platformFunctions/findNodeHandle.ts | Web/default shim returns the handle unchanged. |
| packages/react-native-reanimated/src/platformFunctions/findNodeHandle.native.ts | New native re-export from react-native. |
| packages/react-native-reanimated/src/platformFunctions/dispatchCommand.web.ts | Removed (web-only dispatchCommand warning impl). |
| packages/react-native-reanimated/src/platformFunctions/dispatchCommand.ts | Web/default dispatchCommand warns as unsupported. |
| packages/react-native-reanimated/src/platformFunctions/dispatchCommand.native.ts | New native dispatchCommand implementation with Jest warning. |
| packages/react-native-reanimated/src/platform-specific/findHostInstance.web.ts | Removed (web-only findHostInstance stub). |
| packages/react-native-reanimated/src/platform-specific/findHostInstance.ts | Web/default stub returning null!. |
| packages/react-native-reanimated/src/platform-specific/findHostInstance.native.ts | New native findHostInstance implementation resolving ReactFabric. |
| packages/react-native-reanimated/src/mutablesBase.ts | New shared mutable logic (web and shared helpers). |
| packages/react-native-reanimated/src/mutables.native.ts | New native mutable implementation using shareables/synchronizables. |
| packages/react-native-reanimated/src/mappersBase.ts | New shared mapper start/stop factory logic. |
| packages/react-native-reanimated/src/mappers.ts | Web/default mapper registry using RAF scheduling. |
| packages/react-native-reanimated/src/mappers.native.ts | New native mapper registry using requestAnimationFrameFinalizer + queueMicrotask. |
| packages/react-native-reanimated/src/layoutReanimation/web/transition/Sequenced.ts | New web transition generator (Sequenced). |
| packages/react-native-reanimated/src/layoutReanimation/web/transition/Linear.ts | New web transition generator (Linear). |
| packages/react-native-reanimated/src/layoutReanimation/web/transition/Jumping.ts | New web transition generator (Jumping). |
| packages/react-native-reanimated/src/layoutReanimation/web/transition/Fading.ts | New web transition generator (Fading). |
| packages/react-native-reanimated/src/layoutReanimation/web/transition/EntryExit.ts | New web transition generator (Entry/Exit). |
| packages/react-native-reanimated/src/layoutReanimation/web/transition/Curved.ts | Update imports for web Easing module rename. |
| packages/react-native-reanimated/src/layoutReanimation/web/Easing.ts | New web easing utilities and Bezier extraction helpers. |
| packages/react-native-reanimated/src/layoutReanimation/web/createAnimation.ts | Update transition imports to new file names. |
| packages/react-native-reanimated/src/layoutReanimation/web/config.ts | Update animation imports to new file names. |
| packages/react-native-reanimated/src/layoutReanimation/web/componentUtils.ts | Update easing + curved transition imports to new file names. |
| packages/react-native-reanimated/src/layoutReanimation/web/animationParser.ts | Update easing imports to new file names. |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Zoom.ts | New web keyframe animations (Zoom). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Stretch.ts | New web keyframe animations (Stretch). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Slide.ts | New web keyframe animations (Slide). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Rotate.ts | New web keyframe animations (Rotate). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Roll.ts | New web keyframe animations (Roll). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Pinwheel.ts | New web keyframe animations (Pinwheel). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Lightspeed.ts | New web keyframe animations (Lightspeed). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Flip.ts | New web keyframe animations (Flip). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Fade.ts | New web keyframe animations (Fade). |
| packages/react-native-reanimated/src/layoutReanimation/web/animation/Bounce.ts | New web keyframe animations (Bounce). |
| packages/react-native-reanimated/src/layoutReanimation/animationsManager.ts | Web/default no longer installs native global manager; exports type only. |
| packages/react-native-reanimated/src/layoutReanimation/animationsManager.native.ts | New native global LayoutAnimationsManager installer. |
| packages/react-native-reanimated/src/jestUtils/index.web.ts | Removed (web stub jestUtils). |
| packages/react-native-reanimated/src/initializers.ts | Web/default initializer simplified (native init moved out). |
| packages/react-native-reanimated/src/initializers.native.ts | New native initializer with global setup and toggle handler. |
| packages/react-native-reanimated/src/hook/useScrollOffset.ts | Web/default hook now exported directly. |
| packages/react-native-reanimated/src/hook/useScrollOffset.native.ts | New native hook implementation using events manager. |
| packages/react-native-reanimated/src/hook/useHandlerBase.ts | New shared helper utilities for handler equality and worklet validation. |
| packages/react-native-reanimated/src/hook/useHandler.ts | Web/default now imports shared helpers; removes web/native branching inside file. |
| packages/react-native-reanimated/src/hook/useHandler.native.ts | New native hook implementation with always-enabled plugin assumption. |
| packages/react-native-reanimated/src/hook/useDerivedValue.ts | Web/default removes runtime SHOULD_BE_USE_WEB check; always uses deps fallback. |
| packages/react-native-reanimated/src/hook/useDerivedValue.native.ts | New native hook implementation (Jest-only deps fallback). |
| packages/react-native-reanimated/src/hook/useAnimatedStyle.native.ts | New native useAnimatedStyle implementation split from web/default. |
| packages/react-native-reanimated/src/hook/useAnimatedRefBase.ts | New shared animated ref base + web implementation. |
| packages/react-native-reanimated/src/hook/useAnimatedRef.ts | Web/default now re-exports web implementation directly. |
| packages/react-native-reanimated/src/hook/useAnimatedRef.native.ts | New native useAnimatedRef with Jest fallback to web. |
| packages/react-native-reanimated/src/hook/useAnimatedReaction.ts | Web/default removes runtime SHOULD_BE_USE_WEB check; always uses deps fallback. |
| packages/react-native-reanimated/src/hook/useAnimatedReaction.native.ts | New native hook implementation (Jest-only deps fallback). |
| packages/react-native-reanimated/src/fabricUtils.web.ts | Removed (web-only fabric utils). |
| packages/react-native-reanimated/src/fabricUtils.ts | Web/default now throws on use; native impl moved to .native.ts. |
| packages/react-native-reanimated/src/fabricUtils.native.ts | New native fabric utils implementation using findHostInstance. |
| packages/react-native-reanimated/src/css/svg/init.web.ts | Removed (web-only SVG CSS init). |
| packages/react-native-reanimated/src/css/svg/init.ts | Web/default SVG CSS init moved here. |
| packages/react-native-reanimated/src/css/svg/init.native.ts | New native SVG props builder registration. |
| packages/react-native-reanimated/src/css/platform.web.ts | Removed (web-only platform export). |
| packages/react-native-reanimated/src/css/platform.ts | Web/default platform exports now point to ./web. |
| packages/react-native-reanimated/src/css/platform.native.ts | New native platform exports remain ./native. |
| packages/react-native-reanimated/src/css/component/AnimatedComponent.tsx | Web/default CSS AnimatedComponent now web-oriented (native moved to .native.tsx). |
| packages/react-native-reanimated/src/css/component/AnimatedComponent.native.tsx | New native CSS AnimatedComponent with Jest fallback behavior. |
| packages/react-native-reanimated/src/createAnimatedComponent/JSPropsUpdaterBase.ts | New shared web JSPropsUpdater class extracted. |
| packages/react-native-reanimated/src/createAnimatedComponent/JSPropsUpdater.ts | Web/default updater is a web no-op implementation. |
| packages/react-native-reanimated/src/createAnimatedComponent/JSPropsUpdater.native.ts | New native JS props updater wiring + Jest fallback to web no-op. |
| packages/react-native-reanimated/src/createAnimatedComponent/AnimatedComponent.tsx | Web/default AnimatedComponent variant (native behavior moved out). |
| packages/react-native-reanimated/src/ConfigHelperBase.ts | New shared deprecated whitelist no-op helpers. |
| packages/react-native-reanimated/src/ConfigHelper.ts | Web/default config helper no longer syncs to UI runtime here. |
| packages/react-native-reanimated/src/ConfigHelper.native.ts | New native config helper syncing logger config to UI runtime (except Jest). |
| packages/react-native-reanimated/src/commonTypes.ts | Add exported LayoutAnimationsManager type. |
| packages/react-native-reanimated/src/common/style/propsBuilder.ts | Mark stylePropsBuilder as tree-shakable-suppress. |
| packages/react-native-reanimated/src/common/constants/platform.ts | Add tree-shakable-suppress annotation and adjust knip ignore placement. |
| packages/react-native-reanimated/src/animation/util.native.ts | New native-specific animation util implementation split out. |
| packages/react-native-reanimated/src/animation/decay/utilsBase.ts | New shared decay config/types/utilities extracted. |
| packages/react-native-reanimated/src/animation/decay/utils.ts | Web/default decay utils now re-export base and set web VELOCITY_EPS. |
| packages/react-native-reanimated/src/animation/decay/utils.native.ts | New native decay utils now re-export base and set native VELOCITY_EPS. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| listeners: | ||
| | Record<string, (event: ReanimatedEvent<ReanimatedEvent<Event>>) => void> | ||
| | Record<string, (event: JSEvent<Event>) => void>; |
MatiPl01
left a comment
There was a problem hiding this comment.
Left a few comments, will add more later on
| @@ -0,0 +1,82 @@ | |||
| 'use strict'; | |||
There was a problem hiding this comment.
nit: Maybe rename this file to commonUtils? To match our naming convention used for type-related files (commonTypes).
There was a problem hiding this comment.
The same applies to other utilBase files. I don't want to leave comments separately everywhere so I leave just this one.
| export function cancelAnimationWeb<TValue>( | ||
| sharedValue: SharedValue<TValue> | ||
| ): void { | ||
| // setting the current value cancels the animation if one is currently running | ||
| sharedValue.value = sharedValue.value; // eslint-disable-line no-self-assign | ||
| } |
There was a problem hiding this comment.
I'd prefer to move this out of this common file
| export const cancelAnimation = IS_JEST | ||
| ? cancelAnimationWeb | ||
| : cancelAnimationNative; |
There was a problem hiding this comment.
Is that possible to move the web implementation to the web-related file from the common utilBase file or we can't do this because of this IS_JEST check?
I know that we have different jest configuration that run for different platforms, thus jest may read native files instead of web ones, thus we might not be able to simplify this easily. I still feel that we should not reference the web-specific code in the .native file.
| function cancelAnimationNative<TValue>(sharedValue: SharedValue<TValue>): void { | ||
| 'worklet'; | ||
| // setting the current value cancels the animation if one is currently running | ||
| if (globalThis.__RUNTIME_KIND !== RuntimeKind.ReactNative) { |
There was a problem hiding this comment.
Can we maybe add IS_JEST to this if statement to ensure this function works the same as the cancelAnimationWeb used for jest environment? I think we could get rid of cancelAnimationWeb then (see this comment).
| function filterOutAnimatedStyles( | ||
| style: NestedArray<StyleProps | AnimatedStyleHandle | null | undefined> | ||
| ): NestedArray<StyleProps | null | undefined> { | ||
| if (!style) { | ||
| return style; | ||
| } | ||
| if (!Array.isArray(style)) { | ||
| return style?.viewDescriptors ? {} : style; | ||
| } | ||
| return style | ||
| .filter( | ||
| (styleElement) => !(styleElement && 'viewDescriptors' in styleElement) | ||
| ) | ||
| .map((styleElement) => { | ||
| if (Array.isArray(styleElement)) { | ||
| return filterOutAnimatedStyles(styleElement); | ||
| } | ||
| return styleElement; | ||
| }); | ||
| } |
There was a problem hiding this comment.
Can this be deduplicated? It seems to be the same in both files.
| JSPropsUpdater = JSPropsUpdaterWeb; | ||
| } else { | ||
| JSPropsUpdater = JSPropsUpdaterNative; | ||
| } |
There was a problem hiding this comment.
Can't this be simplified with a one-liner?
const JSPropsUpdater: JSPropsUpdaterOptions = IS_JEST ? JSPropsUpdaterWeb : JSPropsUpdaterNative;| @@ -0,0 +1,74 @@ | |||
| 'use strict'; | |||
There was a problem hiding this comment.
Not sure if we won't prefer to extract the common part of this hook and reuse or if we prefer a duplication of the same logic. Ask @tjzel once he is back what he prefers. I don't like duplication but I understand that it is simpler than addition of a common abstraction.
| export const useAnimatedRef = IS_JEST | ||
| ? useAnimatedRefWeb | ||
| : useAnimatedRefNative; |
There was a problem hiding this comment.
I again don't like this. Maybe we should think whether we really need to use a web-specific implementation in jest, since we run jest tests not only for web platform but also with ios/android-specific configs. Let's wait for @tjzel to discuss about this.
| animatedRef: AnimatedRefOnJS | AnimatedRefOnUI, | ||
| commandName: string, | ||
| args: Array<unknown> = [] | ||
| function dispatchCommandWeb( |
There was a problem hiding this comment.
| function dispatchCommandWeb( | |
| export function dispatchCommand( |
Can't we do just this? If needed, you can cast to as DispatchCommand as well by using this syntax:
export const dispatchCommand: DispatchCommand = ((
_animatedRef: AnimatedRefOnJS | AnimatedRefOnUI,
_commandName: string,
_args: Array<unknown> = []
) => {
logger.warn('dispatchCommand() is not supported on web.');
}) as DispatchCommand;| export const findNodeHandle: typeof findNodeHandleRN = | ||
| findNodeHandleWeb as typeof findNodeHandleRN; |
39ffe1e to
47c1f5d
Compare
47c1f5d to
d5927ea
Compare
Summary
Also, for existing .web.ts files changed them back to .ts, and adjusted their native counterparts accordingly
Test plan
Stuff works, correct files are loaded on each platform