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.

Sync rules are the mechanism Rojo uses to decide which Roblox instance class a file becomes. Every time Rojo encounters a file, it walks a list of rules and applies the first one whose glob pattern matches the file’s name. The result is a Roblox instance created by a named middleware. Rojo ships with sensible defaults for the most common file types. When those defaults are not enough — for example, you want .data.json files to become ModuleScript values or you need to exclude certain generated files — you add custom rules to the syncRules array in your project file.

Default sync rules

These rules are applied when no custom rule matches. Rules higher in the table take priority.
PatternMiddlewareNotes
*.server.lua, *.server.luauserverScriptCreates a Script (or RunContext script)
*.client.lua, *.client.luauclientScriptCreates a LocalScript (or RunContext script)
*.plugin.lua, *.plugin.luaupluginScriptCreates a Script with RunContext = Plugin
*.lua, *.luaumoduleScriptCreates a ModuleScript
*.project.json, *.project.jsoncprojectLoads a nested Rojo project
*.model.json, *.model.jsoncjsonModelLoads a JSON-encoded Roblox model
*.json (excluding *.meta.json)jsonCreates a ModuleScript containing the JSON as a Lua table
*.jsonc (excluding *.meta.jsonc)jsonSame as above with JSONC comment support
*.tomltomlCreates a ModuleScript with TOML parsed to a Lua table
*.csvcsvCreates a LocalizationTable
*.txttextCreates a StringValue
*.rbxmxrbxmxLoads a Roblox XML model file
*.rbxmrbxmLoads a Roblox binary model file
*.yml, *.yamlyamlCreates a ModuleScript with YAML parsed to a Lua table
Meta files (*.meta.json, *.meta.jsonc, init.meta.json, init.meta.jsonc) are read by Rojo for property overrides and are never turned into instances themselves. See Meta files for details.

Defining custom sync rules

Add a syncRules array to your project file. Each entry in the array is evaluated before the built-in defaults, so a custom rule can override any default behavior.
default.project.json
{
  "name": "MyGame",
  "tree": { "$className": "DataModel" },
  "syncRules": [
    {
      "pattern": "*.data.json",
      "use": "json",
      "suffix": ".data.json"
    }
  ]
}

SyncRule fields

pattern
string
required
A glob pattern matched against the file name (relative to the project root). The first rule whose pattern matches wins.
"pattern": "*.data.json"
See Glob pattern syntax below for supported wildcards.
use
string
required
The middleware to apply when the pattern matches. Must be one of the middleware names listed in Available middleware.
"use": "moduleScript"
exclude
string
A secondary glob pattern. Files that match pattern but also match exclude are skipped by this rule and continue to the next matching rule (or the built-in defaults).Use this to create exceptions inside broad patterns:
{
  "pattern": "*.json",
  "use": "json",
  "exclude": "*.meta.json"
}
suffix
string
A suffix to strip from the file name to produce the instance name. Includes the file extension.Without suffix, Rojo uses the file stem (everything before the last .). With suffix, Rojo removes the exact string from the end of the full file name.For example, with "suffix": ".data.json", a file named PlayerData.data.json becomes an instance named PlayerData.

Available middleware

moduleScript
middleware
Creates a ModuleScript whose Source is the file content.
serverScript
middleware
Creates a Script. If emitLegacyScripts is false, uses RunContext = Server instead.
clientScript
middleware
Creates a LocalScript. If emitLegacyScripts is false, uses RunContext = Client instead.
pluginScript
middleware
Creates a Script with RunContext = Plugin.
json
middleware
Parses the file as JSON (or JSONC) and creates a ModuleScript that returns the parsed data as a Lua table. Useful for data files you want to require() from scripts.
jsonModel
middleware
Loads a JSON-encoded Roblox model (.model.json format) and inserts the resulting instance tree.
toml
middleware
Parses the file as TOML and creates a ModuleScript that returns the data as a Lua table.
yaml
middleware
Parses the file as YAML and creates a ModuleScript that returns the data as a Lua table.
csv
middleware
Parses the file as a CSV spreadsheet and creates a LocalizationTable.
text
middleware
Creates a StringValue whose Value is the raw file content.
rbxm
middleware
Loads a Roblox binary model file and inserts the resulting instance tree.
rbxmx
middleware
Loads a Roblox XML model file and inserts the resulting instance tree.
project
middleware
Loads a nested .project.json or .project.jsonc file as a sub-project.
ignore
middleware
Suppresses instance creation entirely. Files matched by this middleware are silently skipped.

Glob pattern syntax

Rojo’s glob patterns support the following wildcards:
SyntaxMatches
*Any sequence of characters that does not include a path separator
**Any sequence of characters including path separators (matches across directory boundaries)
?Any single character except a path separator
{a,b}Either a or b (alternation)
[abc]Any single character in the set
[!abc]Any single character not in the set
Patterns in syncRules are matched relative to the folder containing the project file, not the filesystem root.

Examples

Ignore all spec files

{
  "pattern": "**/*.spec.luau",
  "use": "ignore"
}

Treat .data.json files as JSON modules

By default, *.json produces a ModuleScript but keeps .json in the instance name stem. Adding a custom rule with suffix strips the double extension cleanly.
{
  "pattern": "*.data.json",
  "use": "json",
  "suffix": ".data.json"
}
A file named Config.data.json becomes a ModuleScript named Config.

Force all .lua files to be plain module scripts

Override the default .server.lua / .client.lua convention for a specific directory by placing a more specific rule first:
{
  "pattern": "src/vendor/**/*.lua",
  "use": "moduleScript"
}
Custom rules are checked before the built-in defaults, so a more specific pattern always wins as long as it appears in syncRules.

Exclude generated files by extension

{
  "pattern": "**/*.g.lua",
  "use": "ignore"
}

Build docs developers (and LLMs) love