references/installation-and-cli.md
---
read_when: "Install Rojo or choose CLI commands and flags"
last_reviewed: 2026-07-09
---
# Installation and CLI
Official docs:
- https://rojo.space/docs/v7/getting-started/installation/
- https://rojo.space/docs/v7/getting-started/new-game/
- https://github.com/rojo-rbx/rojo/releases
Rojo has two installable pieces: the **server/CLI** and the **Roblox Studio plugin**. The optional **VS Code extension** can drive menu actions but does **not** put `rojo` on your PATH. Install the CLI separately for terminal use.
## Install the CLI
### Rokit (recommended for projects)
[Rokit](https://github.com/rojo-rbx/rokit) is Rojo's toolchain manager. After installing Rokit:
```bash
rokit add rojo-rbx/rojo
rokit install
```
Or pin in `rokit.toml` (example from the v7.7.0 release notes):
```toml
[tools]
rojo = "rojo-rbx/rojo@7.7.0"
```
Always verify the current version on the [GitHub Releases](https://github.com/rojo-rbx/rojo/releases) page before pinning.
### GitHub Releases
Pre-built binaries for Windows, macOS, and Linux: https://github.com/rojo-rbx/rojo/releases
Put the binary on your system `PATH`.
### crates.io (compile from source)
Requires a current Rust toolchain (Rojo's README states the MSRV; for 7.7.x this is Rust **1.88+**):
```bash
cargo install rojo --version ^7
# or a exact pin, e.g. cargo install rojo --version 7.7.0
```
## Install the Studio plugin
Match the plugin major to the CLI major (Rojo 7 plugin for Rojo 7 CLI).
1. **CLI (preferred):** `rojo plugin install` (also `rojo plugin uninstall`).
2. **GitHub:** download the release `rbxm` into Studio's plugins folder (Plugins toolbar → **Plugins Folder**).
3. **Roblox.com:** [Rojo 7 plugin](https://www.roblox.com/library/13916111004/Rojo) (Install on the plugin page).
## VS Code extension
Marketplace: [evaera.vscode-rojo](https://marketplace.visualstudio.com/items?itemName=evaera.vscode-rojo)
Provides UI for init/build/serve. Still install the CLI for PATH/`rojo` terminal commands. Command palette: **Rojo: Open Menu**.
## CLI surface (Rojo 7)
Global flags (from CLI): `--verbose` / `-v` (repeatable), `--color auto|always|never`.
| Subcommand | Purpose |
| --- | --- |
| `rojo init [path]` | Scaffold project. `--kind place\|model\|plugin` (default `place`). `--skip-git`. |
| `rojo serve [project]` | Live-sync server. `--address`, `--port`, `--allowed-hosts` (repeat/comma-separated). Defaults: address `127.0.0.1`, port `34872` (or project `servePort` / `serveAddress`). |
| `rojo build [project]` | Build place/model. Requires `--output` / `-o` **or** `--plugin`. Output extensions: `.rbxl`, `.rbxlx`, `.rbxm`, `.rbxmx`. `--watch`. `--plugin` writes under the local Studio plugins folder (relative path only). |
| `rojo upload [project]` | Build and upload. `--asset_id` required. Legacy: `--cookie` (optional on Windows if Studio cookie found). Open Cloud: `--api_key` + `--universe_id` (place upload). |
| `rojo sourcemap [project]` | Emit sourcemap JSON for tooling. `--output`, `--include-non-scripts`, `--watch`, `--absolute`. |
| `rojo syncback [project]` | Pull instances from a place/model file into the project tree. `--input` required (`.rbxl`/`.rbxlx`/`.rbxm`/`.rbxmx`). `--list`, `--dry-run`, `-y` / `--non-interactive`. |
| `rojo fmt-project` | Format project JSON. |
| `rojo doc` | Open documentation in the browser. |
| `rojo plugin install\|uninstall` | Manage the Studio plugin from the CLI. |
### Init kinds
- `place`: baseplate-style game project (default).
- `model`: library/model layout.
- `plugin`: plugin-oriented template (`rojo init --kind plugin`).
Example:
```bash
rojo init my-new-game
cd my-new-game
rojo serve
```
### Build examples
```bash
rojo build -o build.rbxlx # XML place
rojo build -o build.rbxl # binary place
rojo build -o model.rbxmx # XML model
rojo build --plugin CoolPlugin.rbxm
rojo build -o build.rbxlx --watch
```
### Serve security notes (7.7+)
- Default bind is loopback.
- Host/Origin validation protects against DNS rebinding; `/api/open` is gated to local clients.
- Non-local binds warn. Extend accepted hosts with `--allowed-hosts` or project `serveAllowedHosts`.
### Upload security
Official docs recommend a **dedicated deploy account**, not a personal account, if using a security cookie. Prefer Open Cloud API keys with least privilege when using `--api_key`. Never commit cookies or keys.
On Windows with Studio installed, `--cookie` may be omitted for legacy upload and pulled from the Studio session.
### New game flow (docs)
1. `rojo init` (or VS Code menu).
2. Optional: `rojo build -o build.rbxlx` and open in Studio.
3. `rojo serve` → Studio plugin **Connect**.
4. Edit files; live sync applies supported changes.
Visit the URL printed by `rojo serve` (e.g. `http://localhost:34872/`) for session info in the browser UI.
## Versioning discipline
- Track https://github.com/rojo-rbx/rojo/releases for breaking changes.
- After upgrading the CLI, reinstall the plugin (`rojo plugin install`).
- Explicit project property syntax changed between Rojo 6 and 7; prefer implicit properties (see upgrade docs).
references/project-format.md
---
read_when: "Write project trees, properties, paths, or nested projects"
last_reviewed: 2026-07-09
---
# Project format
Official docs:
- https://rojo.space/docs/v7/project-format/
- https://rojo.space/docs/v7/properties/
- https://rojo.space/docs/v7/upgrade/
Rojo projects are JSON (or JSONC) files ending in `.project.json` or `.project.jsonc`. Comments and trailing commas are accepted in recent 7.x releases. Optional `"$schema"` is supported on project/meta/model JSON files.
## Top-level fields
| Field | Required | Default / notes |
| --- | --- | --- |
| `name` | No* | Display/root name. Optional for `default.project.json` / `default.project.jsonc` (folder name used). Other files should set `name` or rely on documented naming behavior. |
| `tree` | **Yes** | Root [Instance Description](#instance-description). |
| `servePort` | No | Default live-sync port **34872**. Overridden by `rojo serve --port`. |
| `serveAddress` | No | Default bind when CLI `--address` omitted. |
| `servePlaceIds` | No | If set, live-sync only to these place IDs. |
| `blockedPlaceIds` | No | Place IDs that must not be live-synced (added in 7.5). |
| `placeId` | No | Applied in Studio on connect (`SetPlaceId`-equivalent). |
| `gameId` | No | Applied in Studio on connect (`SetUniverseId`-equivalent). |
| `serveAllowedHosts` | No | Extra Host/Origin values for `rojo serve` (7.7+). CLI `--allowed-hosts` overrides when provided. |
| `globIgnorePaths` | No | `[]`. Globs relative to the project folder. Gitignore-style **negation** supported in recent releases. |
| `emitLegacyScripts` | No | **`true`**. See [emitLegacyScripts](#emitlegacyscripts). |
| `syncRules` | No | `[]`. Custom file middleware rules (reset per nested project). |
| `syncbackRules` | No | Controls `rojo syncback` (see workflows reference). |
\*Docs historically called `name` required; releases since 7.4.1 allow omitting it for `default.project.json`. Prefer setting `name` for non-default project filenames.
Unknown keys are rejected (`deny_unknown_fields` in the implementation).
## Instance description
Each node maps to one Instance:
| Key | Meaning |
| --- | --- |
| `$className` | Class name. Optional if `$path` is set **or** the node is a known Roblox service (or Terrain under Workspace). |
| `$path` | Filesystem path relative to the project file's folder. Optional if `$className` is set. |
| `$properties` | Map of properties (implicit or explicit values). |
| `$attributes` | Attributes map (project format support for `$attributes`). |
| `$ignoreUnknownInstances` | If true, leave unknown Studio children alone. Default: **`false` if `$path` is set, else `true`**. |
| `$id` / `id` | Instance id for manual Ref linking (advanced; see release notes for `Rojo_Target_*` attributes). |
| other keys | Child instances (name = key); values are nested instance descriptions. |
### emitLegacyScripts
| Value | `*.server.lua(u)` | `*.client.lua(u)` |
| --- | --- | --- |
| `true` (default) | `Script` (legacy RunContext) | `LocalScript` |
| `false` | `Script` + `RunContext = Server` | `Script` + `RunContext = Client` |
```json
{
"name": "MyCoolRunContextProject",
"emitLegacyScripts": false,
"tree": {
"$path": "src"
}
}
```
## Property values
**Prefer implicit syntax** (Rojo validates against the reflection DB):
```json
{
"$className": "Part",
"$properties": {
"Anchored": true,
"Size": [2, 0.5, 6],
"Material": "Wood"
}
}
```
**Explicit syntax (Rojo 7)**. Type name is the key (not Rojo 6's `{ "Type", "Value" }`):
```json
{
"$properties": {
"Anchored": { "Bool": true },
"Size": { "Vector3": [2, 0.5, 6] },
"Material": { "Enum": 512 }
}
}
```
Use explicit form for new/unknown properties or intentional type overrides. Full per-type formats: https://rojo.space/docs/v7/properties/
Not all types are writable from project files (e.g. some Ref/Region3 cases). Attributes support a documented subset of value types.
## syncRules
Override how files become instances (from 7.5+ changelog; each nested project resets rules):
```json
{
"name": "SyncRulesAreCool",
"syncRules": [
{
"pattern": "*.foo",
"use": "text",
"exclude": "*.exclude.foo"
},
{
"pattern": "*.bar.baz",
"use": "json",
"suffix": ".bar.baz"
}
],
"tree": {
"$path": "src"
}
}
```
| `use` value | Behaves like |
| --- | --- |
| `serverScript` | `.server.lua` |
| `clientScript` | `.client.lua` |
| `moduleScript` | `.lua` |
| `pluginScript` | `.plugin.lua` |
| `legacyServerScript` | Script + Legacy RunContext |
| `legacyClientScript` | LocalScript |
| `runContextServerScript` | Script + Server RunContext |
| `runContextClientScript` | Script + Client RunContext |
| `json` / `toml` / `csv` / `text` / `jsonModel` / `rbxm` / `rbxmx` / `project` | matching extensions |
| `ignore` | skip |
## Example: model package
```json
{
"name": "AwesomeLibrary",
"tree": {
"$path": "src"
}
}
```
## Example: place layout
```json
{
"name": "Sisyphus Simulator",
"globIgnorePaths": ["**/*.spec.lua"],
"tree": {
"$className": "DataModel",
"HttpService": {
"$className": "HttpService",
"$properties": {
"HttpEnabled": true
}
},
"ReplicatedStorage": {
"$path": "src/ReplicatedStorage"
},
"StarterPlayer": {
"StarterPlayerScripts": {
"$path": "src/StarterPlayerScripts"
}
},
"Workspace": {
"$properties": {
"Gravity": 67.3
},
"Terrain": {
"$path": "Terrain.rbxm"
}
}
}
}
```
Note: `HttpService.HttpEnabled` is listed among properties that often **cannot live-sync** and may require a built place file.
## Nested projects
A directory containing `default.project.json` or `default.project.jsonc` is replaced by that project's tree (Rojo 6+). Nested projects should usually describe **models**, not full places. Sync rules do not inherit. Redeclare them per project file.
references/sync-details.md
---
read_when: "Map files to instances or diagnose changes that live sync cannot apply"
last_reviewed: 2026-07-09
---
# Sync details
Official docs:
- https://rojo.space/docs/v7/sync-details/
- https://rojo.space/docs/v7/properties/
- rbx-dom coverage: https://github.com/rojo-rbx/rbx-dom#property-type-coverage
How Rojo turns filesystem entries into Roblox Instances under a `$path` (and default project roots).
## Default file rules
Supported by current Rojo 7 (docs + source `default_sync_rules`):
| Concept | Patterns |
| --- | --- |
| Folders | any directory → `Folder` (unless usurped) |
| Server scripts | `*.server.lua`, `*.server.luau` |
| Client scripts | `*.client.lua`, `*.client.luau` |
| Plugin scripts | `*.plugin.lua`, `*.plugin.luau` → `Script` + `RunContext = Plugin` |
| Module scripts | other `*.lua` / `*.luau` |
| Nested projects | `*.project.json`, `*.project.jsonc` |
| JSON models | `*.model.json`, `*.model.jsonc` |
| JSON modules | other `*.json` / `*.jsonc` (not meta/model/project) → ModuleScript returning a table |
| TOML modules | `*.toml` |
| YAML modules | `*.yml`, `*.yaml` (synced similarly to JSON/TOML modules; 7.6+) |
| Localization | `*.csv` → `LocalizationTable` |
| Plain text | `*.txt` → `StringValue` |
| Models | `*.rbxm`, `*.rbxmx` |
| Meta | `*.meta.json`, `*.meta.jsonc` (adjacent metadata; not Instances themselves) |
JSONC is accepted anywhere JSON is for project/meta/model/module inputs (7.7+ / 7.6.1 comments+commas).
### Script class behavior and `emitLegacyScripts`
See [project-format.md](project-format.md#emitlegacyscripts). Summary:
- Default (`emitLegacyScripts: true`): server files → `Script`; client files → `LocalScript`.
- Modern RunContext mode (`emitLegacyScripts: false`): server/client files → `Script` with `RunContext` Server/Client.
`*.plugin.lua(u)` always targets Plugin RunContext.
### Init files (directory usurpers)
If a folder would become a `Folder`, these files turn the **folder** into a script (children become children of the script):
| File | Script kind |
| --- | --- |
| `init.server.lua(u)` | server (per emitLegacyScripts) |
| `init.client.lua(u)` | client (per emitLegacyScripts) |
| `init.plugin.lua(u)` | plugin |
| `init.lua(u)` | module |
| `init.csv` | localization table init |
Also: `default.project.json` / `default.project.jsonc` inside a directory uses the **project** middleware instead of scanning as a plain folder.
Only one init script style should be present. Init scripts require the directory middleware to produce a Folder first (conflicts if something else already changed the class).
### Meta files (`*.meta.json`)
Attach Rojo data next to non-project instances:
```json
{
"className": "Tool",
"properties": {
"Grip": [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]
},
"ignoreUnknownInstances": true
}
```
| Field | Use |
| --- | --- |
| `className` | Only in `init.meta.json`; change the folder's class (e.g. to `Tool`). |
| `properties` | Set properties on the adjacent instance (not for `.rbxm`/`.rbxmx`/`.model.json`, which already define properties). |
| `ignoreUnknownInstances` | Same meaning as `$ignoreUnknownInstances`. |
Example: disable a script with `foo.meta.json` beside `foo.server.luau`:
```json
{
"properties": {
"Disabled": true
}
}
```
## JSON models (`.model.json`)
Hand-written instance trees (Remotes, simple hierarchies). File name supplies the instance name; top-level `Name` is optional/discouraged when it disagrees with the file name.
```json
{
"className": "Folder",
"children": [
{
"name": "RootPart",
"className": "Part",
"properties": {
"Size": [4, 4, 4]
}
},
{
"name": "SendMoney",
"className": "RemoteEvent"
}
]
}
```
Recent Rojo accepts camelCase keys (`className`, `children`, `properties`, `name`) for JSON models; older PascalCase still appears in docs samples. Prefer the format your Rojo version emits/accepts and validate with `rojo build` / serve.
## JSON / TOML / YAML modules
Non-model JSON becomes a `ModuleScript` whose source is `return { ... }` matching the document. TOML/YAML behave analogously. TOML `DateTime` values become **strings**, not Roblox DateTime values.
## Live-sync limitations
Documented cases that often fail or need a full build:
- Binary data (Terrain, CSG parts)
- `MeshPart.MeshId`
- `HttpService.HttpEnabled`
Type support differs for **build** vs **live sync** (see Properties page tables). When live sync cannot apply a change, generate a place with `rojo build` and open it.
Fallback recreation for difficult instances (e.g. some MeshParts/Unions) may delete/recreate instances and can break unknown references. Be careful on large places.
## Line endings
Rojo normalizes Lua sources to LF when syncing (avoids spurious Windows CRLF diffs).
## What Rojo is not
- Not Roblox **Script Sync** (Studio's built-in disk mapping; different naming rules; see roblox-mcp).
- Not a full round-trip Studio editor: two-way sync is experimental; use **syncback** for place → files.
references/workflows-and-syncback.md
---
read_when: "Port an existing place, export Studio changes, or build in CI"
last_reviewed: 2026-07-09
---
# Workflows and syncback
Official docs:
- https://rojo.space/docs/v7/getting-started/existing-game/
- https://rojo.space/docs/v7/workflows/
- https://github.com/rojo-rbx/rojo/releases (syncback details; docs may lag new features)
## Collaboration models (docs status)
The official "Recommended Workflows" page distinguishes:
- **Partially managed Rojo**: Rojo owns scripts (and maybe some instances); world/building may stay in Team Create.
- **Fully managed Rojo**: entire place comes from the filesystem/build pipeline (CI-friendly, hermetic builds).
Those pages are still marked **TODO** in places on rojo.space. Practical guidance from Getting Started + release notes:
- Prefer **per-developer places** for live sync rather than many people connecting Rojo into one Team Create session when possible.
- Use `servePlaceIds` / `blockedPlaceIds` so a project cannot overwrite the wrong place.
- Use Git (or another VCS) on the filesystem tree as the source of truth for managed instances.
- For production deploy automation, `rojo build` / `rojo upload` (cookie or Open Cloud) from CI; see the Desert Bus 2077 sample linked from the docs: https://github.com/Roblox/desert-bus-2077
## Porting an existing game
### Prepare in Studio first
Filesystem layout works best when code is not scattered inside arbitrary GUI/parts/tools duplicates:
- Move logic into `ReplicatedStorage`, `ServerScriptService`, `StarterPlayer`, etc.
- Replace copy-pasted scripts with modules + `CollectionService` tags where appropriate.
### `rojo syncback` (Rojo 7.7+)
Converts instances from a place/model file **into** paths defined by an existing project:
```bash
rojo syncback path/to/project --input path/to/file.rbxl
rojo syncback . --input place.rbxlx --dry-run --list
rojo syncback . --input place.rbxl -y
```
Rules:
- Only instances that are **referenced in the project tree or descendants of those nodes** are written. If you want Workspace children, `Workspace` (or a `$path` under it) must appear in the project.
- Many teams keep a **separate project file** used only for syncback so the serve/build project stays lean.
- Flags: `--list` (plan to stdout), `--dry-run` (no writes), `-y` / `--non-interactive` (skip confirm).
#### `syncbackRules` on the project
```json
{
"name": "MyGame",
"tree": {
"$className": "DataModel",
"ServerScriptService": { "$path": "src/ServerScriptService" },
"ReplicatedStorage": { "$path": "src/ReplicatedStorage" }
},
"syncbackRules": {
"ignoreTrees": [
"ServerStorage/ImportantSecrets"
],
"ignorePaths": [
"src/ServerStorage/Secrets/*"
],
"ignoreProperties": {
"BasePart": ["Color"]
},
"syncCurrentCamera": false,
"syncUnscriptable": true,
"ignoreReferents": false
}
}
```
| Field | Meaning |
| --- | --- |
| `ignoreTrees` | Paths in the **Roblox file** to skip. |
| `ignorePaths` | Paths on the **filesystem** to skip (gitignore-style negation supported in recent releases). |
| `ignoreProperties` | Per-class property names not written back. |
| `syncCurrentCamera` | Include Workspace CurrentCamera; default **false**. |
| `syncUnscriptable` | Include properties the Studio plugin cannot set; default **true**. |
| `ignoreReferents` | If true, skip referent properties (e.g. `Model.PrimaryPart`); default **false** (include them). |
Actors and bindable/remote event/function variants may sync back as JSON files (7.7+). Rojo 7.7.0 fixed a bug involving referent properties that pointed outside the syncback set. Include those targets in the tree when you need their references.
### Other porting tools (official docs)
- [rbxlx-to-rojo](https://github.com/rojo-rbx/rbxlx-to-rojo): automated porting helper.
- [Lune](https://github.com/lune-org/lune): scriptable pipelines for large/complex conversions.
### Leaving Rojo
Edit the built place in Studio and stop using the filesystem tree. Rojo produces normal place and model files.
## Plugin settings (behavioral)
From release notes / plugin UX (verify in your plugin version):
- **Open Scripts Externally**: open script edits in the system editor.
- **Two-Way Sync**: experimental; not reliable for source control.
- **Patch confirmation** modes (Initial / Always / Large Changes / Unlisted PlaceId).
- **Sync reminder** when reconnecting to a previously synced place (Forget option in recent plugin).
- **Auto Connect** / playtest-related options: experimental; may break when Studio changes.
## CI / hermetic builds
Typical pipeline:
1. Install pinned Rojo (Rokit or binary).
2. `rojo build -o place.rbxlx` (or `.rbxl`).
3. Upload via Open Cloud (`rojo upload --api_key ... --universe_id ... --asset_id ...`) or your own uploader.
4. Keep secrets in the CI secret store, never in the repo.
## Combining with other Studio tools
| Tool | Role vs Rojo |
| --- | --- |
| **Rojo** | Project file + filesystem middleware → build/serve/syncback. |
| **Script Sync** | Studio-native folder mapping with its own suffixes (`.server.luau`, `.local.luau`, etc.). Different convention; do not mix naming blindly. |
| **Studio MCP** | Agent control plane (inspect, execute Luau, playtest). Complements Rojo; does not replace project format. |
See [roblox-mcp/SKILL.md](../../roblox-mcp/SKILL.md) for MCP + Script Sync.
## Common failure modes
| Symptom | Check |
| --- | --- |
| Plugin won't connect | CLI major matches plugin; `rojo serve` running; host/port; firewall; Host allowlist if non-local. |
| Wrong place overwritten | Set `servePlaceIds` / `blockedPlaceIds`. |
| Scripts wrong class | `emitLegacyScripts` and file suffix (`.server` / `.client` / `.plugin`). |
| Properties missing after sync | Live-sync type limits; rebuild place. |
| Syncback wrote nothing | Target services missing from project `tree`; path ignore rules too broad. |
| Nested project ignored syncRules | Sync rules reset per project file; redeclare. |
SKILL.md
---
name: roblox-rojo
description: "Set up or troubleshoot Rojo projects. Use for CLI and plugin installation, project files, live sync, builds, uploads, sourcemaps, and exporting existing places with syncback."
last_reviewed: 2026-07-09
---
# roblox-rojo
**Official sources:**
- https://rojo.space/docs/v7/ (docs index; current major is v7)
- https://rojo.space/docs/v7/getting-started/installation/
- https://rojo.space/docs/v7/getting-started/new-game/
- https://rojo.space/docs/v7/getting-started/existing-game/
- https://rojo.space/docs/v7/project-format/
- https://rojo.space/docs/v7/properties/
- https://rojo.space/docs/v7/sync-details/
- https://rojo.space/docs/v7/upgrade/
- https://github.com/rojo-rbx/rojo/releases (latest CLI/plugin releases; verify version before recommending install pins)
- https://github.com/rojo-rbx/rojo (source of truth for CLI flags and changelog when docs lag)
Rojo maps a filesystem project to Roblox instances so you can edit with external tools (VS Code, Git, linters, formatters) and live-sync or build into Studio/place files. This skill covers **Rojo 7** as documented at rojo.space and implemented in the current `rojo-rbx/rojo` release line.
## Mental model
| Piece | Role |
| --- | --- |
| **Rojo CLI** | Reads the project file + filesystem; serves live sync, builds place/model files, uploads, sourcemaps, syncback. |
| **Studio plugin** | Connects to the local serve session and applies patches into the open place. |
| **Project file** | `*.project.json` / `*.project.jsonc` describing the instance tree and options. |
| **Filesystem tree** | Scripts, models, JSON/TOML/YAML/CSV/text under `$path` nodes become Instances. |
Rojo is **filesystem → Studio** for live sync (one primary direction). Optional **two-way sync** in the plugin is experimental and incomplete. Do not design production workflows around it. For place → files, use **`rojo syncback`** (Rojo 7.7+) or external porting tools.
## Quick start
1. Install the **CLI** (Rokit recommended for projects; GitHub binaries or `cargo install rojo --version ^7` also supported).
2. Install the **Studio plugin** with `rojo plugin install` (or GitHub `rbxm` / Roblox.com plugin for the matching major).
3. `rojo init my-game` (or open folder + VS Code "Rojo: Open Menu").
4. `rojo serve` in the project folder.
5. In Studio: open the Rojo plugin panel → **Connect**.
6. Edit files on disk; watch them sync. Use `rojo build -o build.rbxlx` for a one-shot place file.
Full install matrix and CLI flags: [references/installation-and-cli.md](references/installation-and-cli.md).
## Script file → Instance mapping (defaults)
Both `.lua` and `.luau` are supported. Default rules (from Rojo source / sync docs):
| File pattern | Instance (when `emitLegacyScripts` is **true**, the default) | Instance (when `emitLegacyScripts` is **false**) |
| --- | --- | --- |
| `*.server.lua(u)` | `Script` (legacy RunContext) | `Script` with `RunContext = Server` |
| `*.client.lua(u)` | `LocalScript` | `Script` with `RunContext = Client` |
| `*.plugin.lua(u)` | `Script` with `RunContext = Plugin` | same |
| other `*.lua(u)` | `ModuleScript` | same |
**Init usurpers** (replace the parent folder with a script): `init.server.lua(u)`, `init.client.lua(u)`, `init.plugin.lua(u)`, `init.lua(u)`. Only one init script type per folder. A directory with `default.project.json` / `default.project.jsonc` is treated as a nested project instead of a plain folder.
Other defaults: `.rbxm`/`.rbxmx` models, `.model.json(c)`, plain `.json(c)` → ModuleScript returning a table, `.toml` / `.yml`/`.yaml` similarly, `.csv` → `LocalizationTable`, `.txt` → `StringValue`.
Details, meta files, limitations: [references/sync-details.md](references/sync-details.md).
## Project file essentials
Minimal place-shaped tree (services inferred without `$className` for known services):
```json
{
"name": "MyGame",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$path": "src/ReplicatedStorage"
},
"ServerScriptService": {
"$path": "src/ServerScriptService"
},
"StarterPlayer": {
"StarterPlayerScripts": {
"$path": "src/StarterPlayerScripts"
}
}
}
}
```
Important top-level fields (docs + current CLI):
| Field | Purpose |
| --- | --- |
| `name` | Project/instance name (optional for `default.project.json`; folder name used). |
| `tree` | Root instance description (required). |
| `servePort` | Default port for `rojo serve` (default **34872**). |
| `serveAddress` | Default bind address when CLI `--address` omitted. |
| `servePlaceIds` / `blockedPlaceIds` | Allow/deny live-sync targets by place ID. |
| `placeId` / `gameId` | Set Studio place/universe IDs on connect. |
| `serveAllowedHosts` | Extra Host/Origin values for serve (hostname access); CLI `--allowed-hosts` overrides. |
| `globIgnorePaths` | Globs to ignore (gitignore-style negation supported in recent releases). |
| `emitLegacyScripts` | Default **true** = Script/LocalScript; **false** = RunContext Scripts for server/client files. |
| `syncRules` | Custom file→middleware patterns. |
| `syncbackRules` | Controls `rojo syncback` behavior. |
Instance nodes use `$className`, `$path`, `$properties`, `$attributes`, `$ignoreUnknownInstances`, plus child keys. Prefer **implicit** property syntax. Full format: [references/project-format.md](references/project-format.md).
## Daily commands
```bash
# New project (place | model | plugin)
rojo init my-game
rojo init --kind model
rojo init --kind plugin --skip-git
# Live sync (default localhost:34872)
rojo serve
rojo serve --port 34872 --address 127.0.0.1
# Build place/model
rojo build -o build.rbxlx
rojo build -o build.rbxl
rojo build --plugin MyPlugin.rbxm
rojo build -o out.rbxlx --watch
# Sourcemap for editor tooling
rojo sourcemap --output sourcemap.json
rojo sourcemap --watch --absolute
# Upload (prefer dedicated deploy account; never commit cookies/keys)
rojo upload --asset_id PLACE_ID --cookie "..."
rojo upload --asset_id PLACE_ID --api_key "..." --universe_id UNIVERSE_ID
# Place file → filesystem into an existing project tree
rojo syncback . --input place.rbxl
rojo syncback . --input place.rbxlx --dry-run --list
# Plugin management / docs / format
rojo plugin install
rojo plugin uninstall
rojo doc
rojo fmt-project
```
## Live-sync limitations
Not all property types apply in real time (Studio plugin API limits). Common cases that may need a full **build + open** instead of live sync:
- Binary data (Terrain, CSG)
- `MeshPart.MeshId`
- `HttpService.HttpEnabled`
Property type coverage for build vs live sync is documented on the Properties page and rbx-dom's coverage chart. When live sync fails for a class/property, rebuild with `rojo build` and open the place.
`rojo serve` binds to loopback by default. Binding to a network-reachable address exposes the session: recent Rojo versions validate Host/Origin, gate some APIs to local clients, and warn on non-local binds. Prefer localhost; if you must expose, use `serveAllowedHosts` / `--allowed-hosts` deliberately.
## Porting existing games
1. Refactor Studio code into fewer service-rooted locations (`ReplicatedStorage`, `ServerScriptService`, `StarterPlayer`, tags via `CollectionService`) before porting.
2. Prefer **`rojo syncback`** with a project that already lists the services/paths you want filled (`rojo syncback path/to/project --input place.rbxl`). Only descendants of nodes present in the project tree are written.
3. Alternatives called out in official docs: [rbxlx-to-rojo](https://github.com/rojo-rbx/rbxlx-to-rojo), [Lune](https://github.com/lune-org/lune) for custom pipelines.
4. Leaving Rojo is always possible: Rojo builds normal place/model files; you can stop using the filesystem tree and edit in Studio only.
Workflows and syncback rules: [references/workflows-and-syncback.md](references/workflows-and-syncback.md).
## Agent checklist
- **Do** pin CLI + plugin to the **same major** (Rojo 7 plugin with Rojo 7 CLI).
- **Do** run `rojo plugin install` after upgrading the CLI.
- **Do** put shared modules under `ReplicatedStorage` paths and server authority under `ServerScriptService`.
- **Do** use `.luau` (Rojo's `init` templates use `.luau` since 7.4).
- **Do** set `emitLegacyScripts: false` only when the team understands modern `RunContext` scripts (and that client files become `Script`+Client, not `LocalScript`).
- **Do not** invent CLI flags or project keys. If unsure, run `rojo --help` / `rojo <cmd> --help` or re-check docs/changelog.
- **Do not** commit `.ROBLOSECURITY` cookies or Open Cloud API keys used with `rojo upload`.
- **Do not** treat experimental two-way sync as reliable source control.
- **Do not** confuse Rojo with Roblox **Script Sync** or **Studio MCP**. Different tools; they can coexist (see roblox-mcp).
## Verification
- [ ] `rojo --version` reports a 7.x release matching the intended pin.
- [ ] Studio shows the Rojo 7 plugin; connect succeeds against `rojo serve`.
- [ ] Editing a `.server.luau` under a mapped `$path` updates the correct service in Studio.
- [ ] `rojo build -o build.rbxlx` opens cleanly in Studio.
- [ ] `sourcemap.json` is gitignored if generated (Rojo's default gitignore template includes it in recent releases).
## How to proceed
1. Confirm install path: [references/installation-and-cli.md](references/installation-and-cli.md).
2. Shape the tree: [references/project-format.md](references/project-format.md).
3. Name files correctly: [references/sync-details.md](references/sync-details.md).
4. For teams / porting / deploy: [references/workflows-and-syncback.md](references/workflows-and-syncback.md).
<!-- catalog:references:start -->
## Reference index
- [installation-and-cli.md](references/installation-and-cli.md): Install Rojo or choose CLI commands and flags.
- [project-format.md](references/project-format.md): Write project trees, properties, paths, or nested projects.
- [sync-details.md](references/sync-details.md): Map files to instances or diagnose changes that live sync cannot apply.
- [workflows-and-syncback.md](references/workflows-and-syncback.md): Port an existing place, export Studio changes, or build in CI.
<!-- catalog:references:end -->