React Lua

September 27, 2024 ยท View on GitHub

React Lua

A comprehensive, but not exhaustive, translation of upstream ReactJS 17.x into Lua.

Coverage Status Docs


About the Project

React Lua is a comprehensive translation of upstream ReactJS from JavaScript into Lua, and is highly-turned for both performance and correctness.

When possible, upstream flowtype and definitely-typed types have been translated into Luau type annotations. The major and minor version of React Lua is aligned to the upstream used for the translation, except where noted. Due to the close nature of the two implementations, most article, video, or blog posts that gives React JS advice can be applied to React Lua -- modulo language differences, of course.

About this Fork

This repository is a fork of roblox/react-lua with the intention of being the Roblox and global Lua community go-to for React in Lua. Roblox's repository is a read-only mirror of their internal project, and as such cannot be contributed to by the community. They have not published React to any public package registry and have not made alterations for easier use by the community.

Original Project Authors

Roblox has removed commit author history in their public mirror, which removes credit for the original project authors. Below is a non-exhaustive list of those who originally worked on the project, in no particular order:

Status

The react repo is a monorepo with a number of member projects in its packages folder, managed by a Yarn workspace. Below is a description of each of those package, its status in React Lua, and how it likely fits into our future plans.

๐Ÿ“Œ Considered part of react's core functionality or testing capabilities; some or all of this package is necessary to build and validate an MVP.

ProjectDescriptionStatusPlanNotes
create-subscriptionUsed for subscribing to external dataโŒ Not portedโ” Not yet assessed
dom-event-testing-libraryDom event simulation for testsโŒ Not portedโ” Not yet assessed
eslint-plugin-react-hooksLinting plugin for hooks rulesโŒ Not portedโ” Not yet assessedDepends on future linting tools
jest-mock-schedulerReexports scheduler testing utilitiesโŒ Not portedโ” Not yet assessed
๐Ÿ“Œjest-reactJest matchers and utilitiesโœ”๏ธ PortedUsed for testing React component implementations.
๐Ÿ“ŒreactBase react interfaceโœ”๏ธ PortedDefines basic shape of internals like Components and Elements. We added Roblox-specifics like Bindings, but otherwise comply with upstream ReactJS.
react-artFor drawing vector graphicsโŒ Not portedโž– Unlikely to be ported
react-cacheBasic cache for use with experimental React featuresโœ”๏ธ Portedโ”API is flagged as unstable, is stable in React 18, used in advanced Suspense cases
react-clientExperimental package for consuming React streaming modelsโŒ Not portedโ” Not yet assessedAPI considered unstable. Might be worth investigating if it stabilizes
react-debug-toolsExperimental debugger packageโœ”๏ธ PortedUsed by DevTools and (the Roblox internal) Roblox Studio Inspector
react-devtoolsTop-level app for react devtoolsโŒ Not portedโž• Likely to be portedDevtools needs to be addressed as a whole to see where/how it translates
react-devtools-coreStandalone devtools implโŒ Not portedโž• Likely to be portedDevtools needs to be addressed as a whole to see where/how it translates
react-devtools-extensionsDevtools browser extensionโŒ Not portedโž– Unlikely to be ported
react-devtools-inlineImpl for embedding in browser-based IDEsโŒ Not portedโž• Likely to be portedDevtools needs to be addressed as a whole to see where/how it translates
react-devtools-scheduling-profilerExperimental concurrent mode profilerโŒ Not portedโ” Not yet assessed
react-devtools-sharedPrivate shared utilities for devtoolsโœ”๏ธ PortedUsed by Roblox Studio Inspector
react-devtools-shellHarness for testing other devtools packagesโŒ Not portedโ” Not yet assessedDevtools needs to be addressed as a whole to see where/how it translates
react-domEntrypoint for DOM and server renderersโŒ Not portedโž– Unlikely to be portedHeavily inspired the top-level interface of the React-Roblox Renderer
react-fetchFor use with experimental React featuresโŒ Not portedโ” Not yet assessedAPI considered unstable
react-interactionsFor use with experimental React featuresโŒ Not portedโ” Not yet assessed
๐Ÿ“Œreact-isRuntime type checks for React elementsโœ”๏ธ Ported
react-native-rendererRenderer interface for react-nativeโŒ Not portedโ” Not yet assessedThis package has no readme, so it's hard to understand its scope
๐Ÿ“Œreact-noop-rendererRenderer used for debugging Fiberโœ”๏ธ PortedUsed heavily for internal framework testing
๐Ÿ“Œreact-reconcilerReconciler implementation used with various renderersโœ”๏ธ PortedBulk of React's complicated logic lives here
react-refreshWiring for Fast RefreshโŒ Not portedโ” Not yet assessed, depend on applicabilityOfficially supported successor to "hot reloading"
react-serverExperimental package for creating React streaming server renderersโŒ Not portedโ” Not yet assessed
react-test-rendererTest renderer helpful utilities and snapshot supportโœ”๏ธ PortedUsed for testing much of React's internals, can be used by external developers
react-transport-dom-delayInternal package, likely for testingโŒ Not portedโž– Unlikely to be portedNo readme in package
react-transport-dom-webpackRelated to aboveโŒ Not portedโž– Unlikely to be portedAppears to be webpack-specific
๐Ÿ“ŒschedulerCooperative scheduling implementationโœ”๏ธ PortedIncludes Tracing and Profiling features, which are enabled through ReactFeatureFlags
๐Ÿ“ŒsharedLoose collection of shared utilities and definitionsโœ”๏ธ PortedWe pushed many things into this leaf node module to fix circular dependencies. Working with upstream to clean this up.
use-subscriptionHook for managing subscriptions in concurrent modeโŒ Not portedโ” Not yet assessedNot sure if/how this will apply to Roblox and Lua

Projects not in the upstream React repo:

ProjectDescriptionNotes
๐Ÿ“Œreact-shallow-rendererShallow renderer used in tests for some older React features. Re-exported alongside react-test-renderer, source of truth here.โœ”๏ธ Ported - with tests that are helping us exercise functionality in the react package
react-robloxBased on react-dom renderer, shares much of its code and public interface.Also exports act() functionality, which is required for testing components that are asynchronously rendered (the default).
roact-compatA comaptibility layer that emulates some deprecated behaviors of legacy RoactMeant to ease initial adoption of Roact Lua, using React APIs directly is encouraged and necessary for newer functonality (eg Hooks)

Deviations from Roact

This repo is meant to supplant the Roact project, which is an open-source project that currently powers many Roblox projects. Our goal is to be as compatible as possible with Roact.

With that in mind, however, there will still be a small number of behavioral deviations that make the transition from existing Roact smoother, or account for nuances of the Roblox ecosystem:

  • Stable Keys: Aligned Roact will allow table keys to be used as stable keys for child elements, equivalent to the behavior relied upon in Roact today
  • Context: Roact's deprecated _context feature will not be present in React Lua; users will have to switch to the createContext feature, which is present in both Roact and React Lua and is semantically equivalent
  • Class Component Refs: React Lua will allow refs provided to class components (referred to in Roact documentation as "stateful components") to point to the actual component instance. This is not supported in Roact, and there may be changes around the Roact.Ref prop key to support this with minimal disruption
  • Bindings: We intend to keep createBindings and joinBindings, a feature unique to Roact and documented here

See this document for details about any deviations and the design and refactoring efforts being proposed to address them.

Contribution Guidelines

  • Try to keep the directory structure, file name/location, and code symbol names aligned with React upstream. At the top of the mirrored files, put a comment in this format that includes the specific hash of the version of the file you're mirroring:
-- ROBLOX upstream https://github.com/facebook/react/blob/9abc2785cb070148d64fae81e523246b90b92016/packages/scheduler/src/Scheduler.js
  • If you have a deviation from upstream code logic for Lua-specific reasons (1-based array indices, etc) put a comment above the deviated line:
-- ROBLOX deviation: use explicit nil check instead of falsey
  • For deviations due to Lua language differences (no spread operator) that don't involve changing the logic, don't put a deviation comment. Just use the appropriate equivalent from LuauPolyfill and other utility libraries.

  • For files that are new and Roblox-specific, use the file name: Timeout.roblox.lua

  • and for Roblox-specific tests, use the file name format: Timeout.roblox.spec.lua