Thanks for your interest in contributing! This document covers how to set up the project locally, run checks, and submit changes.
- Bug Reports: Open a GitHub Issue with a clear description and reproduction steps.
- Feature Requests: Open an issue with your idea and rationale.
- Code Contributions: Clone this repository, create a branch, and submit a PR (see below for PR guidelines).
The repository is a Wally workspace. Source code lives under modules/, with each package containing its own src/ directory and tests at src/__tests__/.
modules/
signals/ # Core reactive primitives
signals-scheduler/ # Batch/flush micro-scheduler
signals-experimental/ # Experimental utilities
resources/ # Lifetime and scoping primitives
Please only make modifications in the directories above. You may notice there are duplicate config files for some of our tooling (e.g. foreman.toml vs foreman-internal.toml, rotriever.toml vs wally.toml, default/test.project.json vs default.rbxp) as well as some internal specific files (e.g. .lestrc). Repo maintainers use these internal specific files to run the same tests on different tooling. The default.project.json describes the published Wally package layout; test.project.json is the development place used for local testing and CI. If you want to add or modify any of the repo tooling or packages (e.g. updating foreman.toml or wally.toml), please open an issue and reach out to the maintainers for assistance.
Note
You may notice that we depend on some packages (for example, Jest) which are still based on the legacy source-available mirroring process. We're in the process of upgrading our dependency graph so that we can more broadly accept Community Contributions throughout all of our dependencies.
All CLI tools are installed via Foreman (foreman install).
Contributions should follow existing code styling. In support of this, we use the following tools:
- All Luau code should be formatted with StyLua and pass Selene linting.
- Static analysis uses luau-lsp. The full type check can be run locally:
rojo sourcemap test.project.json -o sourcemap.json
curl -sO https://raw.githubusercontent.com/JohnnyMorganz/luau-lsp/master/scripts/globalTypes.d.luau
luau-lsp analyze --defs globalTypes.d.luau --sourcemap sourcemap.json modulesAdditionally:
- Every functionality change should come with tests that express the desired behavior of the code being added.
- Tests live in each module's
src/__tests__/directory and run in CI via rocale-cli. See the rocale-cli repository for instructions on setting up local test execution. - Small, incremental contributions are preferred over sweeping changes.
- Behavioral changes should be gated behind a FastFlag. Roblox ships this library to a large number of users internally, and as a safety guard, new behavior needs to be rolled out incrementally and be easy to roll back if issues arise. When your PR changes observable behavior, structure the code so both the old and new paths coexist, toggled by a feature flag. A maintainer can help you add the flag if you're unsure. All flag definitions are centralized in
modules/signals-flags/src/init.lua. To add a new flag, define it there following the existing pattern:
-- In modules/signals-flags/src/init.lua
local _, MyNewFeature = xpcall(function()
return game:DefineFastFlag("MyNewFeature", false)
end, function()
return true
end)
return {
MyNewFeature = MyNewFeature,
-- ...existing flags
}Then import the flag where it's needed:
local SignalsFlags = require(Packages.SignalsFlags)
-- Keep both paths until the flag is fully rolled out
return if SignalsFlags.MyNewFeature then newImpl else oldImplIf your change is a pure addition (new module, new export) with no impact on existing behavior, a flag is typically not needed.
Running tests locally example
wally install
export ROBLOX_API_KEY="your generated OCALE api key"
rocale-cli run \
--placeId $ROBLOX_PLACE_ID \
--universeId $ROBLOX_UNIVERSE_ID \
--load.project test.project.json \
--script scripts/test.lua \
--lua.globals __DEV__=true,__ROACT_17_INLINE_ACT__=true,__ROACT_17_MOCK_SCHEDULER__=true \
--verbose- Create a fork of the repository using the Github UI
- Generate an API key for OCALE (skip if you already have this)
- Create a new experience
- Go to your newly created experience, click on Places and get your universe and place ID
- Navigate to the API Keys tab
- Create a new API key with write access to your experience for
luau-execution-sessionsanduniverse-places
- On your fork, add these secrets
ROBLOX_API_KEYROBLOX_PLACE_IDROBLOX_UNIVERSE_ID
When submitting a pull request:
- Create a feature branch from
main. - Ensure lint, format, and type checks pass before opening a PR.
- Write a clear PR title that describes the change from a user's perspective.
- All pull requests must pass the
analyzeandtestCI workflows before merging.
By providing code in an issue or opening a pull request, you agree to license that code under the MIT License, and indicate that you have the legal right to do so.