@rotor-rbx/rotor
v2.2.1
Published
All-in-one Roblox toolchain: native roblox-ts compiler, Luau bundler, minifier, dev loop, and packer. This package downloads the prebuilt rotor binary from GitHub Releases.
Maintainers
Readme
rotor is an all-in-one Roblox toolchain, written in Go. At its core is a native rewrite of the roblox-ts compiler built on typescript-go — a drop-in rbxtsc replacement with byte-identical Luau output — plus a native Luau toolchain and Open Cloud asset + deployment pipelines, all in one binary.
bun add -d @rotor-rbx/rotor # or: npm i -D @rotor-rbx/rotor — see Install for more ways📖 Documentation · 🤝 Contributing · 🗺️ Roadmap
Features
Compile & check — the rbxtsc replacement:
rotor check ./my-game -w # native full-strictness typecheck: 222 files in 161 ms
rotor build ./my-game -w # byte-identical Luau, watch mode, incremental rebuilds
rotor doctor # diagnose tsconfig, @rbxts packages, plugins, Rojo, cloud setupSame tsconfig.json, same @rbxts/* packages, same transformer plugins (Flamework etc.), same CLI flags — plus built-in compile-time macros rbxtsc doesn't have (no plugins, no Node sidecar, fully typed):
| Macro | Inlines |
|-------|---------|
| $env("KEY", "fallback") · $env.KEY | env vars from .env / .env.<NODE_ENV> |
| $asset("logo.png") | a rbxassetid://… string (cached, auto-uploads on miss) |
| $keys<T>() | a type's string keys (checker-powered) |
| $nameof(expr) | the trailing identifier name as a string |
| $file("data.json") | a file's contents as a Luau value (JSON→table, text→string) |
| $git("sha"\|"branch"\|"tag"\|"dirty") · $buildTime() | build/VCS stamps |
| $getModuleTree("shared/systems") | a folder's module tree (no index.ts required) |
Luau toolchain — works on any Rojo project, no rbxts required:
rotor dev # watch + incremental compile + rojo serve to Studio
rotor bundle entry.luau -o bundle.luau --minify # inline a require graph, still runnable
rotor minify file.luau # strip comments/whitespace, keep --! directives
rotor pack --as luau # whole project -> one self-reconstructing script (or rbxm/rbxmx)
rotor sourcemap -o sourcemap.json # Rojo-compatible, for luau-lspCloud — assets and deployment from one typed config (see below):
rotor asset sync # upload new/changed assets, lockfile, typed codegen
rotor deploy plan -e prod # diff config vs live state (terraform-style, no network writes)
rotor deploy apply -e prod # publish places, settings, badges — only what driftedScaffolding — rotor init runs an interactive wizard (template, Biome/oxlint, starter packages, asset/deploy config) or scripts cleanly with --yes/--template.
Configuration — rotor.toml
One typed TOML config drives the cloud tools. rotor init writes it with a #:schema directive that points at the schema hosted in this repo (served via raw GitHub), so taplo / Even Better TOML give validation + autocomplete with no per-project rotor.schema.json to generate or commit. Need a local copy for offline editing? rotor schema > rotor.schema.json. (Upgrading from a 1.x rotor.config.ts? Run rotor migrate.)
#:schema https://raw.githubusercontent.com/uproot/rotor/master/rotor.schema.json
[assets]
mode = "macro" # "module" (assets.luau) | "macro" ($asset transformer)
paths = ["assets/**/*.png", "assets/**/*.ogg"]
[assets.creator]
type = "group"
id = 12345
[deploy.environments.prod]
universeId = 333
[deploy.environments.prod.places.start]
file = "build/game.rbxl"
placeId = 444
maxPlayers = 30
versionType = "published"
[deploy.environments.prod.experience]
name = "My Game"
playability = "public"
[deploy.environments.prod.gamepasses.vip]
name = "VIP"
price = 250
icon = "assets/vip.png"
[deploy.environments.prod.socials.discord]
title = "Join us"
url = "https://discord.gg/x"
type = "discord"rotor asset syncscans the globs, uploads new/changed files via Open Cloud (SHA-256 lockfilerotor-lock.json— unchanged files never re-upload, updates keep asset ids stable). Inmode = "module"it generatesassets.luau+assets.d.ts; inmode = "macro"you reference assets inline with$asset("assets/logo.png"), which resolves from the cache and auto-uploads any miss whenROBLOX_API_KEYis set.rotor deployis infrastructure-as-code: it diffs the config against per-environment state (.rotor/deploy/<env>.json), shows a plan, and applies only the drift — place file publishing + place settings, experience settings, badges and game passes (icons upload automatically first, shared icons dedupe), experience icon + thumbnails, developer products, and social links. Deletes require--allow-deletes.- Auth is an Open Cloud key in
ROBLOX_API_KEY(scopes: Assets R/W, Universe Places W, Universe R/W).rotor doctorchecks your config and key setup.
Full config shape, every command flag, and all the macros: docs.md.
Install
Grab a binary from GitHub Releases, or use a toolchain manager:
# mise
mise use -g github:uproot/[email protected]
# rokit
rokit add uproot/[email protected]# aftman.toml
[tools]
rotor = "uproot/[email protected]"
# foreman.toml
[tools]
rotor = { github = "uproot/rotor", version = "2.0.0" }Install via npm / bun
For rbxts projects that already live in the JS ecosystem, install @rotor-rbx/rotor as a dev dependency — a postinstall step downloads the prebuilt binary for your platform:
bun add -d @rotor-rbx/rotor
npm i -D @rotor-rbx/rotor
pnpm add -D @rotor-rbx/rotor
yarn add -D @rotor-rbx/rotorInstalling straight from GitHub works too: bun add -d github:uproot/rotor (npm/pnpm/yarn equivalents likewise).
bun note: bun skips postinstall scripts by default. Either add
"trustedDependencies": ["@rotor-rbx/rotor"]to your project'spackage.json(thenbun install), or do nothing — therotorshim downloads the binary on first run. pnpm similarly asks you to approve build scripts (pnpm approve-builds), with the same first-run fallback.
Or build from source (Go 1.25+):
git clone https://github.com/uproot/rotor && cd rotor
go build ./cmd/rotorBenchmarks
Measured on real production rbxts games, with output byte-identical to rbxtsc 3.0.0:
| Workload | rotor | |----------|------:| | Full strict typecheck — 222-file production game | 161 ms | | Full build — 95-file production game | 355 ms | | Incremental watch rebuild — same game | 180 ms |
The JS toolchain spends longer than this booting Node. The ~10× speedup is structural: rotor runs Microsoft's native, parallel TypeScript compiler (typescript-go) instead of the single-threaded JS one.
Contributors
Contributions welcome — see CONTRIBUTING.md.
License
MIT. rotor stands on roblox-ts (MIT) and typescript-go (Apache-2.0) — see credits.
