Skip to main content

Overview

rbx-css integrates seamlessly with Rojo projects, allowing you to compile CSS to .rbxmx model files or .luau modules that sync directly into Roblox Studio.

Project structure

A typical Rojo project with rbx-css follows this structure:
my-project/
├── src/
│   ├── ui/
│   │   ├── styles/
│   │   │   ├── base.css
│   │   │   ├── theme-dark.css
│   │   │   └── components.css
│   │   └── components/
│   │       └── App.tsx
│   └── server/
├── out/
│   └── ui/
│       └── styles/
│           ├── StyleSheet.rbxmx
│           └── DarkTheme.rbxmx
├── default.project.json
└── package.json
Keep your source CSS files in src/ and compile output to out/ to keep your project organized.

Setup

1

Install rbx-css

Add rbx-css to your project:
npm install rbx-css
# or
bun add rbx-css
2

Configure output directory

Create an output directory for compiled stylesheets:
mkdir -p out/ui/styles
3

Update default.project.json

Add the compiled stylesheets to your Rojo configuration:
default.project.json
{
  "name": "my-project",
  "tree": {
    "$className": "DataModel",
    "ReplicatedStorage": {
      "UI": {
        "$path": "out/ui"
      },
      "Styles": {
        "$path": "out/ui/styles"
      }
    },
    "StarterGui": {
      "ScreenGui": {
        "$className": "ScreenGui",
        "$path": "src/ui/components"
      }
    }
  }
}
4

Add build scripts

Add compilation scripts to your package.json:
package.json
{
  "scripts": {
    "build:styles": "rbx-css compile src/ui/styles/*.css -o out/ui/styles/StyleSheet.rbxmx",
    "watch:styles": "rbx-css watch src/ui/styles -o out/ui/styles/StyleSheet.rbxmx",
    "dev": "npm run watch:styles"
  }
}

Output formats

Generating .rbxmx files allows Rojo to sync StyleSheet instances directly into Studio:
rbx-css compile styles.css -o StyleSheet.rbxmx
RBXMX output is experimental. While functional, StyleRule properties are encoded as XML comments. The Luau format is recommended for production use.

Luau modules

Generate .luau module files that return a factory function:
rbx-css compile styles.css -o StyleSheet.luau
The generated module exports a createStyleSheet() function:
local createStyleSheet = require(ReplicatedStorage.Styles.StyleSheet)
local sheet = createStyleSheet()
sheet.Parent = game:GetService("ReplicatedStorage")

Multiple stylesheets

Merging multiple CSS files

Compile multiple CSS files into a single StyleSheet:
rbx-css compile base.css theme.css components.css -o StyleSheet.rbxmx
All selectors and rules from the input files are merged in order.

Separate theme files

For projects with multiple themes, generate separate StyleSheet files:
# Base styles
rbx-css compile src/ui/styles/base.css -o out/ui/styles/Base.rbxmx

# Dark theme
rbx-css compile src/ui/styles/theme-dark.css -o out/ui/styles/DarkTheme.rbxmx --name "DarkTheme"

# Light theme  
rbx-css compile src/ui/styles/theme-light.css -o out/ui/styles/LightTheme.rbxmx --name "LightTheme"
Update your Rojo config:
default.project.json
{
  "tree": {
    "ReplicatedStorage": {
      "Styles": {
        "$path": "out/ui/styles"
      }
    }
  }
}

Hot reloading

Combine rbx-css watch mode with Rojo’s hot reloading for rapid development:
1

Start rbx-css watch mode

rbx-css watch src/ui/styles -o out/ui/styles/StyleSheet.rbxmx
2

Start Rojo serve

In a separate terminal:
rojo serve
3

Connect from Studio

Use the Rojo Studio plugin to connect to localhost:34872.
4

Edit CSS files

When you save a CSS file:
  1. rbx-css recompiles the stylesheet
  2. Rojo detects the .rbxmx change
  3. The StyleSheet updates in Studio automatically
Use a process manager like concurrently to run both watch modes together:
package.json
{
  "scripts": {
    "dev": "concurrently \"rbx-css watch src/ui/styles -o out/ui/styles/StyleSheet.rbxmx\" \"rojo serve\""
  }
}

Example configuration

Complete example for a Rojo + rbx-css project:
default.project.json
{
  "name": "my-game",
  "tree": {
    "$className": "DataModel",
    "ReplicatedStorage": {
      "Packages": {
        "$path": "node_modules/@rbxts"
      },
      "Styles": {
        "$path": "out/ui/styles"
      },
      "UI": {
        "$path": "out/ui/components"
      }
    },
    "ServerScriptService": {
      "$path": "src/server"
    },
    "StarterPlayer": {
      "StarterPlayerScripts": {
        "$path": "src/client"
      }
    }
  }
}
package.json
{
  "name": "my-game",
  "scripts": {
    "build:styles": "rbx-css compile src/ui/styles/*.css -o out/ui/styles/StyleSheet.rbxmx",
    "watch:styles": "rbx-css watch src/ui/styles -o out/ui/styles/StyleSheet.rbxmx",
    "serve": "rojo serve",
    "build": "rojo build -o game.rbxl",
    "dev": "concurrently \"npm run watch:styles\" \"npm run serve\""
  },
  "dependencies": {
    "rbx-css": "latest"
  },
  "devDependencies": {
    "concurrently": "^8.0.0"
  }
}

Troubleshooting

StyleSheet not appearing in Studio

  1. Check that the output file was generated in out/ui/styles/
  2. Verify your default.project.json path is correct
  3. Restart Rojo serve and reconnect from Studio
  4. Check the Rojo output window for sync errors

Changes not hot reloading

  1. Ensure both rbx-css watch and rojo serve are running
  2. Check that the CSS file path is being watched (watch mode logs changes)
  3. Verify the output path matches your Rojo configuration
  4. Try manually syncing in Studio using the Rojo plugin

Compilation errors

If rbx-css fails to compile:
  1. Check the terminal output for specific error messages
  2. Validate your CSS syntax
  3. Use --warn all to see detailed warnings
  4. Review unsupported properties in the CSS mapping reference

Build docs developers (and LLMs) love