Skip to content

Adding a Roact 17 Dependency

Roact 17 is available as a collection of packages hosted in the https://github.com/roblox/roact-alignment repository. Internal Roblox projects use a package manager called Rotriever to resolve and manage dependencies.

Info

Roact 17 is a "package workspace", meaning that it consists of multiple packages living in the same project. We recommend using Rotriever version 0.5.4 or newer to make sure it has the latest workspace feature support.

Refer to Rotriever's documentation for more information on how to install or upgrade your version.

New Projects

  1. Make sure you're using rotriever version 0.5.4 or newer. You can check this by running rotrieve -V.
  2. Add the following to your rotriever.toml manifest file:
    [dependencies]
    React = "github.com/roblox/roact-alignment@17.0.1"
    ReactRoblox = "github.com/roblox/roact-alignment@17.0.1"
    
  3. Run rotrieve install to install all dependencies
  4. React.lua and ReactRoblox.lua will be added to the Packages folder generated by rotriever in your project. Make sure this folder is included in your project when testing with roblox-cli or Roblox Studio.

Replacing Legacy Roact

The easiest way to adopt Roact 17 in an existing Roact project is to change your existing dependency on legacy Roact.

Make the following changes to your rotriever.toml manifest file:

[dependencies]
- Roact = "github.com/roblox/roact@1.4"
+ Roact = { target = "github.com/roblox/roact-alignment", version = "17.0.1", package = "RoactCompat" }

This creates a dependency on the RoactCompat package, which provides a compatibility layer for migrating from legacy APIs.

Since it's still named Roact in the above snippet, it will be aliased to Roact in your code. If your code meets the minimum requirements, this dependency change will upgrade your project to Roact 17 without requiring any further changes to your source code.

Accessing New Features

However, the RoactCompat API only covers enough to provide backwards compatibility. To access new features like hooks or suspense, you will need to add dependencies on React and ReactRoblox as well:

[dependencies]
Roact = { target = "github.com/roblox/roact-alignment", version = "17.0.1", package = "RoactCompat" }
React = "github.com/roblox/roact-alignment@17.0.1"
ReactRoblox = "github.com/roblox/roact-alignment@17.0.1"

The RoactCompat package can be safely mixed and matched with the new React and ReactRoblox packages; it's nothing more than a thin wrapper around them that aligns with the legacy Roact API and semantics.

Info

Since we're not using an alias for the React and ReactRoblox packages, we can define our dependencies using the shorthand format. Read up on specifying Rotriever dependencies for more information.

Patching Other Dependencies

You may need to additionally account for other dependencies in your project that use Roact. If you depend on a package that has its own dependency on legacy Roact, you may need to use rotriever's patch feature to replace the legacy version throughout the tree.

You might encounter this if you have existing dependencies on any of the following:

  • InfiniteScroller (compatible with Roact 17 from version 0.8.0 onwards)
  • RoactFitComponents (compatible with Roact 17 from version 2.0.0 onwards)
  • RoactRodux (compatible with Roact 17 from version 0.4.1 onwards)
  • UIBlox (compatible with Roact 17 on the latest master)
  • Numerous other projects that depend on legacy Roact, especially if they're older than the latest version

To resolve this, you can patch over any dependencies on legacy Roact and align them with your newly-added version. Add this additional section to your rotriever.toml manifest file:

[config.patch."github.com/roblox/roact"]
Roact = { target = "github.com/roblox/roact-alignment", version = "17.0.1", package = "RoactCompat" }

To learn more about patching dependencies, check out the Rotriever documentation.

Caution

When you're patching over Roact, make sure your other dependencies are compatible with Roact 17. You may need to upgrade them to more recent versions so that they comply with the Roact 17 requirements.

Testing with Both

In some cases, you may not yet be equipped to safely adopt Roact 17, but you want to begin adopting it in tests or storybooks so your project can enforce compatibility.

One reasonable way to accomplish this is to depend on both projects, but to conditionally swap in Roact 17 at runtime. To do this, make sure your rotriever.toml manifest file contains the following:

[dependencies]
Roact = "github.com/roblox/roact@1.4"

[dev_dependencies]
RoactCompat = "github.com/roblox/roact-alignment@17.0.1"

This declares a dependency on legacy Roact as well as a dev dependency on Roact 17.

In your test runner script or other equivalent entry point, check the value of a global (or flag, or any other preferred configuration method), and overwrite the Roact API with that of RoactCompat when enabled. It may look something like this:

if _G.__NEW_ROACT__ then
    local Roact = require(Packages.Roact)
    local RoactCompat = require(Packages.Dev.RoactCompat)

    -- Overwrite the contents of the `Roact` package with that of the
    -- RoactCompat package
    for api, _ in Roact do
        Roact[api] = RoactCompat[api]
    end
end

-- Proceed with test setup...

In the above example, an additional test suite can be created for use with lest or via a robloxdev-cli command line invocation that sets the __NEW_ROACT__ global to true.

To see this technique in action, you can find a comprehensive example in this PR to the UIBlox library.