Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/rojo-rbx/rojo/llms.txt

Use this file to discover all available pages before exploring further.

This page answers questions that come up frequently when working with Rojo. If you can’t find what you’re looking for here, check the GitHub repository or open a discussion.
Rojo is a CLI tool that enables Roblox developers to use professional software engineering tools. It syncs a project on your filesystem to Roblox Studio, allowing you to edit scripts and assets in any editor and version-control your project with Git.Rojo is designed for developers who want to use tools like Visual Studio Code, Git, and automated pipelines to build Roblox games, libraries, and plugins.
It depends on what you want to do.
  • rojo serve — requires Roblox Studio. The Studio plugin connects to the Rojo server to apply changes in real time.
  • rojo build — does not require Studio. You can build an .rbxl or .rbxlx file from the command line without opening Studio.
  • rojo upload — does not require Studio. You can upload a place directly to Roblox using an auth cookie or Open Cloud API key.
For automated CI/CD workflows, rojo build and rojo upload are the relevant commands and do not require Studio to be installed.
Rojo maps filesystem files to Roblox instances based on their extensions. The default sync rules are:
ExtensionInstance type
*.server.lua, *.server.luauScript (server)
*.client.lua, *.client.luauLocalScript
*.plugin.lua, *.plugin.luauScript (Plugin RunContext)
*.lua, *.luauModuleScript
*.project.json, *.project.jsoncNested Rojo project
*.model.json, *.model.jsoncRoblox model (JSON format)
*.json, *.jsoncModuleScript (JSON parsed to Lua table)
*.tomlModuleScript (TOML parsed to Lua table)
*.csvLocalizationTable
*.txtStringValue
*.rbxmxRoblox model (XML format)
*.rbxmRoblox model (binary format)
*.yml, *.yamlModuleScript (YAML parsed to Lua table)
You can define custom sync rules in your project file using the syncRules field to treat files as a different type.
The default port is 34872.You can override it in two ways:With the --port flag:
rojo serve --port 8080
With servePort in your project file:
{
    "name": "my-project",
    "servePort": 8080,
    "tree": {
        "$path": "src"
    }
}
The --port flag takes precedence over servePort in the project file.
Use the globIgnorePaths field in your project file. It accepts a list of glob patterns relative to the project file’s directory:
{
    "name": "my-project",
    "globIgnorePaths": [
        "**/*.spec.lua",
        "**/*.test.luau",
        "src/dev-only/**"
    ],
    "tree": {
        "$path": "src"
    }
}
Files matching any of the patterns will be ignored by Rojo entirely, as if they didn’t exist.
Both formats represent a Roblox place file, but they use different encodings:
FormatEncodingNotes
.rbxlBinarySmaller file size, not human-readable
.rbxlxXMLLarger file size, human-readable and diffable
Similarly, .rbxm (binary) and .rbxmx (XML) are the model equivalents.
For version control, .rbxlx and .rbxmx are easier to diff, but they produce larger files. For production builds, .rbxl is preferred.
Syncback is the reverse of Rojo’s normal workflow. Instead of pushing filesystem changes to Studio, syncback pulls instances from a Roblox file back into your filesystem project.
rojo syncback <path/to/project> --input <path/to/file.rbxl>
This is useful for converting an existing Roblox project to a Rojo-managed filesystem layout. Syncback behavior is controlled by the syncbackRules field in your project file.
Syncback was introduced in v7.7.0-rc.1 and is currently in release candidate status.
The recommended approach is to use Rojo with Git:
  1. Store your Lua/Luau source files and project file in Git.
  2. Add your built output (.rbxl, .rbxlx) to .gitignore — these are generated artifacts.
  3. Add sourcemap.json to .gitignore as well (added by default in v7.6.1).
A typical .gitignore for a Rojo project:
*.rbxl
*.rbxlx
*.rbxm
*.rbxmx
sourcemap.json
Your teammates can then clone the repository, run rojo serve, and connect from Studio to get a fully synced environment.
Yes. Use rojo syncback to convert an existing .rbxl file into a Rojo-managed filesystem layout:
rojo syncback default.project.json --input my-game.rbxl
Syncback reads the instances from the Roblox file and writes them to the locations described by your project file. You’ll need to have a project file set up first that describes where each service should map to on the filesystem.
Init files let a directory itself represent an instance, rather than just acting as a container for child instances.When Rojo encounters a directory with a file named init.lua, init.luau, init.server.lua, init.server.luau, init.client.lua, or init.client.luau, it treats that file as the source of the directory’s instance.For example, a directory named MyModule with an init.lua file becomes a single ModuleScript named MyModule whose source is the contents of init.lua. Any other files inside MyModule/ become children of that ModuleScript.init.meta.json files serve the same purpose for attaching properties to a directory-level instance.
A typical team setup:
  1. One project file (default.project.json) in the repository root, committed to Git.
  2. Each developer runs rojo serve locally and connects from their own Studio instance.
  3. Changes to Lua files are committed to Git and pulled by teammates.
For a shared studio workflow, use Roblox Team Create alongside Rojo — each developer serves their own project and syncs their own changes.
Only one Rojo server can hold the sync lock at a time in Team Create. Rojo displays a sync reminder notification if another session is already syncing.
Use servePlaceIds in your project file to ensure teammates don’t accidentally sync to the wrong place:
{
    "name": "my-game",
    "servePlaceIds": [123456789],
    "tree": {
        "$path": "src"
    }
}
Meta files (.meta.json or .meta.jsonc) attach additional Roblox instance properties to files or directories that don’t natively support them.For example, to set properties on a ModuleScript defined by MyModule.lua, create MyModule.meta.json alongside it:
{
    "properties": {
        "Archivable": false
    }
}
For a directory, create init.meta.json inside it to set properties on the directory’s instance.
Yes, as of v7.6.1 (and fully supported in v7.7.0-rc.1). Rojo accepts JSONC syntax — comments and trailing commas — in all JSON-related files:
  • .project.json.project.jsonc
  • .meta.json.meta.jsonc
  • .model.json.model.jsonc
  • Plain .json data files → .jsonc
{
    // This is a comment
    "name": "my-project",
    "tree": {
        "$path": "src", // trailing comma is fine
    }
}
Use rojo upload with an API key obtained from create.roblox.com/credentials:
rojo upload \
  --api_key <your-api-key> \
  --universe_id <your-universe-id> \
  --asset_id <your-place-id>
Both --api_key and --universe_id are required when using Open Cloud. The --asset_id is the place ID to upload to.
Open Cloud uploads only support places (not models). For automating releases in CI, store your API key as a secret environment variable and pass it via --api_key.
emitLegacyScripts is a project file field that controls how Rojo emits script instances. It defaults to true, preserving the classic Roblox class types:
Value*.server.lua produces*.client.lua produces
true (default)ScriptLocalScript
falseScript with RunContext = ServerScript with RunContext = Client
Set it to false to use the newer RunContext-based model:
{
    "emitLegacyScripts": false,
    "name": "my-project",
    "tree": {
        "$path": "src"
    }
}
Most projects should leave this at true unless they specifically need the RunContext API.

Build docs developers (and LLMs) love