react-strict-dom icon indicating copy to clipboard operation
react-strict-dom copied to clipboard

add react-strict-animated library

Open vincentriemer opened this issue 3 months ago • 10 comments

This introduces a new package to the RSD repo that provides a subset of React Native's API that works on both web and native, and built with integration of react-strict-dom in mind. The native implementation is largely a thin passthrough to the proper Animated API and some settings pre-configured (such as useAnimatedDriver always being enabled).

The web side is a new Animated implementation that ends up being driven by the Web Animations API.

vincentriemer avatar Sep 30 '25 20:09 vincentriemer

workflow: benchmarks/size

Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.

Results Base Patch Ratio
react-strict-dom/dist/web/index.js
· compressed 3,251 3,251 1.00
· minified 10,375 10,375 1.00
react-strict-dom/dist/web/runtime.js
· compressed 1,645 1,645 1.00
· minified 4,131 4,131 1.00
react-strict-dom/dist/native/index.js
· compressed 16,232 16,232 1.00
· minified 62,962 62,962 1.00
react-strict-animated/dist/web/index.js
· compressed 6,896
· minified 23,698
react-strict-animated/dist/native/index.js
· compressed 586
· minified 1,801

github-actions[bot] avatar Sep 30 '25 20:09 github-actions[bot]

workflow: benchmarks/perf (native)

Comparison of performance test results, measured in operations per second. Larger is better.

Results Base Patch Ratio
css.create
· small 1,142,268 1,146,256 1.00 +
· small with units 492,431 494,718 1.00 +
· small with variables 668,880 672,392 1.01 +
· several small 352,288 354,471 1.01 +
· large 202,182 200,826 0.99 -
· large with polyfills 148,034 149,301 1.01 +
· complex 102,183 103,124 1.01 +
· unsupported 211,894 213,841 1.01 +
css.createTheme
· simple theme 228,835 226,694 0.99 -
· polyfill theme 216,403 214,832 0.99 -
css.props
· small 231,931 230,923 1.00 -
· small with units 187,373 189,235 1.01 +
· small with variables 112,861 112,824 1.00 -
· small with variables of units 82,309 82,446 1.00 +
· large 96,865 96,936 1.00 +
· large with polyfills 37,959 38,365 1.01 +
· complex 21,932 22,025 1.00 +
· unsupported 139,215 140,146 1.01 +
· simple merge 160,013 160,071 1.00 +
· wide merge 16,885 16,890 1.00 +
· deep merge 16,605 16,646 1.00 +
· themed merge 32,372 32,301 1.00 -

github-actions[bot] avatar Sep 30 '25 20:09 github-actions[bot]

Thanks for bringing the animation library you've made to the OSS project! Want a hand with the build and package parts?

necolas avatar Oct 01 '25 03:10 necolas

Thanks for bringing the animation library you've made to the OSS project! Want a hand with the build and package parts?

So I recreated the build system that's basically exactly like how RSD is built but I'm running into some issues related to the generate-types utility:

  • As you can tell from the checks the generate-types output contains flow errors
  • I had to update my implementation to stop using the hook syntax as that broke the generate-types script.
  • Upon inspection of the typescript output of generate-types it looks like its outputting a bunch of anys because it says that features like React.PropsOf and React.RefOf is unsupported.

vincentriemer avatar Oct 02 '25 20:10 vincentriemer

I've tried digging into how to resolve the type generation issues but haven't had any luck yet :/

vincentriemer avatar Oct 06 '25 16:10 vincentriemer

We can try upgrading the translator package. And if that doesn't work, report the issues to the flow team

necolas avatar Oct 06 '25 17:10 necolas

Okay I updated the flow-api-translator which didn't seem to do much but I did find a way to reorganize the exports so that there were no more flow errors after building.

vincentriemer avatar Oct 06 '25 20:10 vincentriemer

Hey @vincentriemer, what's the plan here? Did you make any progress on incorporating the viewport scaling polyfill into the animated values?

necolas avatar Nov 05 '25 22:11 necolas

@necolas @vincentriemer great to see progress on cross-platform animations.

Was wondering and trying to understand better how this relates to: https://github.com/facebook/react-strict-dom/issues/3

having a polyfill for css.keyframes seems more in line with the overall "web first" API of react-strict-dom? Would it eventually be possible to build polyfill similar to the one for CSS transitions by internally using react-strict-animated?

Also curious about what was touched on this comment: https://github.com/facebook/react-strict-dom/issues/3#issuecomment-2585212069 I assume the Animated vs reanimated topic can be controversial, but finding a way to make the animation library opt-in may help in quicker adoption (I'm guessing here that in the long term Animated on react-native will want to address the issues that reanimated tries to fix?)

The whole JS thread vs UI thread topic is also quite interesting in relation to react-strict-dom: in a way having something like a UI thread is in sync with what happens on web where css animations runs on the gpu.

Probably some of those comments have already been discussed in depth in the RN community, and for sure I lack some context, but I'm trying to gauge the position and vision of RSD on this.

axyz avatar Nov 12 '25 12:11 axyz

This animation library enables different things to CSS keyframes

The plan is for Animated and Reanimated to share the same C++ backend. We use the C++ Animated internally; no need to switch out for Reanimated. That will make its way to OSS eventually

necolas avatar Nov 12 '25 17:11 necolas

Updated PR with:

  • viewport scaling hook exposed from the react-strict-dom package
  • viewport scaling of the translateX/Y transform properties
  • baseline unit testing coverage

vincentriemer avatar Nov 26 '25 06:11 vincentriemer

viewport scaling hook exposed from the react-strict-dom package

Having to expose this part of the implementation details is unfortunate. Was this the best of a bunch of bad options? Is the internal version of this library just not handling viewport scaling at all yet?

Would also like to understand a bit more the role of normalizeColor

necolas avatar Dec 05 '25 19:12 necolas

I mean the other option to support it would be to have the package track viewport scaling all on its own, and yeah the internal version isn't taking viewport scaling into account yet I've been focusing on this version first.

normalizeColor is something we technically aren't using as currently I haven't enabled any color-based properties to be animatable but if we do ever add any color-based properties normalizeColor is important because interpolation is fundamentally done on numeric values, but that's not really how we represent colors in RN/web, so if you want to consistently interpolate between different colors its easier to first normalize them to consistent representation, in this case an rgba array of numbers.

FWIW if I could I would just have this implementation point to the normalizeColor that lives in RN but that's an internal file I can't reference so the one that's in this codebase is more or less a duplicate of it.

vincentriemer avatar Dec 05 '25 21:12 vincentriemer

if I could I would just have this implementation point to the normalizeColor that lives in RN

We have a separate package for it these days I believe: https://www.npmjs.com/package/@react-native/normalize-colors


For the current approach we could export useViewportScale prefixed with unstable_ or DO_NOT_USE_ to avoid it looking like "blessed" public API. Don't want to hold this up on figuring out something "ideal".

I don't have any great ideas for a clean relationship between packages. This is my understanding of the options and tradeoffs. Sharing in case anyone has suggestions.

Part of RSD package

  • Difficulty importing from react-strict-dom rather than relative imports
  • Exported as subpath: react-strict-dom/animated
  • Can share RN imports and other internals with RSD package
  • No need to export internals / "temporary" workarounds like useViewportScale

New package

  • Built only on public API of RSD
  • Exported as separate new package: react-strict-animated with RSD dependency
  • Can share imports or internals with RSD
  • Needs to modify RSD exports to include internals
  • Can't potentially be incorporated into RSD babel transform

necolas avatar Dec 06 '25 00:12 necolas