Pick a sync model
| Need | Use |
|---|---|
| Edit scripts in an external editor / git for code only; keep Studio as source of truth; Team Create | Studio Script Sync (built in: right-click a folder → Sync to…) |
| Whole project as files, file system is the source of truth, CI builds, packages | Rojo (rojo serve + Studio plugin) |
Script Sync syncs only Script/LocalScript/ModuleScript/Folder (≤ 10,000 scripts per synced
root, ≤ 128 roots); don't sync scripts that carry attributes/tags (they're not written to disk).
Pair either with the Luau Language Server VS Code extension + its Luau Language Server Companion
Studio plugin (sends the DataModel tree so requires and instance paths type-check).
Rokit: pinned toolchain
# rokit.toml (commit it; run `rokit install`)
[tools]
rojo = "rojo-rbx/rojo@7.7.0"
wally = "UpliftGames/wally@0.3.2"
lune = "lune-org/lune@0.10.5"
stylua = "JohnnyMorganz/StyLua@2.5.2"
selene = "Kampfkarren/selene@0.31.0"
luau-lsp = "JohnnyMorganz/luau-lsp@1.70.1"
darklua = "seaofvoices/darklua@0.19.0"
Install Rokit: curl -sSf https://raw.githubusercontent.com/rojo-rbx/rokit/main/scripts/install.sh | bash
(Windows: install.ps1). Add tools with rokit add owner/repo. Versions above are current as of
September 2026; bump deliberately. (Aftman and Foreman are older equivalents.)
Rojo project
{
"name": "my-game",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"Shared": { "$path": "src/shared" },
"Packages": { "$path": "Packages" }
},
"ServerScriptService": {
"Server": { "$path": "src/server" },
"ServerPackages": { "$path": "ServerPackages" }
},
"StarterPlayer": {
"StarterPlayerScripts": {
"Client": { "$path": "src/client" }
}
},
"Workspace": {
"$properties": { "StreamingEnabled": true }
}
}
}
File mapping: Foo.luau → ModuleScript, Foo.server.luau → Script, Foo.client.luau → LocalScript,
folder with init.luau/init.server.luau/init.client.luau → that script with children,
*.meta.json → properties/attributes, *.model.json/.rbxm/.rbxmx → instances, *.json/*.toml/*.txt
→ ModuleScript returning data / StringValue. Commands: rojo serve, rojo build -o game.rbxl,
rojo sourcemap default.project.json -o sourcemap.json (for luau-lsp), rojo upload / Open Cloud for
publishing. Keep maps/art in Studio (or .rbxm files) and code in Rojo — partially managed trees are fine.
Packages
- Wally (
wally.toml,wally install→Packages/,ServerPackages/forrealm = "server"):
Wally thunks lose types: run[dependencies] React = "jsdotlua/react@17.2.1" ReactRoblox = "jsdotlua/react-roblox@17.2.1" [server-dependencies] ProfileStore = "lm-loleris/profilestore@1.0.3"wally-package-types --sourcemap sourcemap.json Packages/after install. Check each package's page on wally.run for its exact name/version. - pesde (
pesde.toml): newer manager for Roblox/Lune/Luau that can also depend on Wally packages. - Commit
wally.lock/pesde.lock; don't commitPackages/.
Code quality
- luau-lsp (editor + CLI) — type checking against Roblox definitions. CLI:
luau-lsp analyze --definitions=@roblox=globalTypes.d.luau --sourcemap=sourcemap.json --base-luaurc=.luaurc src/(definitions:https://raw.githubusercontent.com/JohnnyMorganz/luau-lsp/main/scripts/globalTypes.d.luau). Enable the new solver in the editor (luau-lsp.fflags.enableNewSolver) to match Studio. - StyLua — formatter.
stylua.toml:indent_type = "Tabs",column_width = 120.stylua --check src. - selene — linter.
selene.toml:std = "roblox"(generate/refresh withselene generate-roblox-std). - darklua — code transforms (e.g. convert string requires, bundle) for publishing pipelines.
.luaurc— per-directory type-check mode and require aliases:
Roblox resolves string requires relative to the DataModel ({ "languageMode": "strict", "aliases": { "Shared": "src/shared", "Packages": "Packages" } }./,../,@self,@game); custom.luaurcaliases need tooling (luau-lsp/darklua) that understands your mapping.
Lune
Standalone Luau runtime for scripts outside Roblox: build steps, place file manipulation
(@lune/roblox reads/writes .rbxl/.rbxm), asset pipelines, running pure-Luau unit tests, calling
Open Cloud with @lune/net. lune run scripts/build.
roblox-ts
If the repo has tsconfig.json, package.json with roblox-ts and @rbxts/types, write TypeScript:
npx rbxtsc -w compiles src/*.ts to out/*.luau, and Rojo syncs out/. Use @rbxts/services,
@rbxts/* packages from npm. Don't hand-edit generated Luau.
Git and CI
.gitignore: *.rbxl.lock, *.rbxlx.lock, Packages/, ServerPackages/, sourcemap.json, build outputs.
A ready-to-use GitHub Actions workflow (install tools, format check, lint, type-check, build, publish via
Open Cloud): references/ci-workflow.md.
Related skills
roblox-testing (running tests in CI), roblox-open-cloud (publishing, Luau execution),
roblox-studio-mcp (driving Studio from an agent), roblox-luau.