RBXMX output is currently experimental. StyleRule properties are emitted as XML comments rather than fully encoded RBXMX properties. The Luau format is recommended for production use.
Overview
The RBXMX output format generates a .rbxmx model file containing Roblox StyleSheet and StyleRule instances. This format can be imported directly into Roblox Studio or synced via Rojo.
When to use RBXMX output
- Studio import: Drag and drop
.rbxmx files directly into Studio
- Rojo projects: Integrate with Rojo’s file system sync
- Visual inspection: View StyleSheet hierarchy in Studio’s Explorer
- Prototyping: Quickly test styles without running code
Because RBXMX property encoding for StyleRule is complex and not fully implemented, properties are stored as XML comments. This means the generated RBXMX files are currently not functional and serve primarily as placeholders or documentation.
Generated structure
The generated RBXMX file follows Roblox’s XML model format:
<roblox version="4">
<Item class="StyleSheet" referent="RBX0001">
<Properties>
<string name="Name">StyleSheet</string>
</Properties>
<!-- Tokens -->
<!-- primary: #335fff -->
<!-- radius: UDim(0, 8) -->
<Item class="StyleRule" referent="RBX0002">
<Properties>
<string name="Selector">.card</string>
</Properties>
<!-- Properties:
BackgroundColor3 = Color3(51, 95, 255)
-->
</Item>
</Item>
</roblox>
XML structure
Root element
All RBXMX files start with the root <roblox> element:
<roblox version="4">
<!-- StyleSheet items -->
</roblox>
StyleSheet instance
The root StyleSheet is created as an Item with a unique referent ID:
<Item class="StyleSheet" referent="RBX0001">
<Properties>
<string name="Name">StyleSheet</string>
</Properties>
<!-- Child StyleRule instances -->
</Item>
Design tokens
Tokens from :root are listed as XML comments:
<!-- Tokens -->
<!-- primary: #335fff -->
<!-- radius-md: UDim(0, 8) -->
<!-- spacing: UDim(0, 16) -->
StyleRule instances
Each CSS rule becomes a StyleRule instance with its selector:
<Item class="StyleRule" referent="RBX0002">
<Properties>
<string name="Selector">.card</string>
</Properties>
<!-- Properties:
BackgroundColor3 = Color3(51, 95, 255)
Size = UDim2(1, 0, 0, 100)
-->
</Item>
Since full RBXMX property encoding is not implemented, properties are listed as comments:
<!-- Properties:
BackgroundColor3 = Color3(255, 255, 255)
TextSize = 16
FontFace = GothamSSm
-->
XML escaping
Special characters in selectors are properly escaped:
| Character | Escaped |
|---|
< | < |
> | > |
& | & |
" | " |
Example:
<string name="Selector">.card > .title</string>
<!-- .card > .title -->
Theme StyleSheets
When your CSS includes themes, additional StyleSheet instances are generated:
<Item class="StyleSheet" referent="RBX0001">
<Properties>
<string name="Name">StyleSheet</string>
</Properties>
<!-- Main rules -->
</Item>
<Item class="StyleSheet" referent="RBX0002">
<Properties>
<string name="Name">StyleSheet_dark</string>
</Properties>
<!-- Theme tokens -->
</Item>
Example output
Given this CSS input:
:root {
--primary: #335fff;
--radius: 8px;
}
.card {
background-color: var(--primary);
border-radius: var(--radius);
padding: 16px;
}
.card > span {
color: white;
font-size: 18px;
}
The RBXMX output:
/home/daytona/workspace/source/src/codegen/rbxmx.ts
<roblox version="4">
<Item class="StyleSheet" referent="RBX0001">
<Properties>
<string name="Name">StyleSheet</string>
</Properties>
<!-- Tokens -->
<!-- primary: #335fff -->
<!-- radius: UDim(0, 8) -->
<Item class="StyleRule" referent="RBX0002">
<Properties>
<string name="Selector">.card</string>
</Properties>
<!-- Properties:
BackgroundColor3 = Color3(51, 95, 255)
-->
</Item>
<Item class="StyleRule" referent="RBX0003">
<Properties>
<string name="Selector">.card::UICorner</string>
</Properties>
<!-- Properties:
CornerRadius = $radius
-->
</Item>
<Item class="StyleRule" referent="RBX0004">
<Properties>
<string name="Selector">.card::UIPadding</string>
</Properties>
<!-- Properties:
PaddingTop = UDim(0, 16)
PaddingBottom = UDim(0, 16)
PaddingLeft = UDim(0, 16)
PaddingRight = UDim(0, 16)
-->
</Item>
<Item class="StyleRule" referent="RBX0005">
<Properties>
<string name="Selector">.card > TextLabel</string>
</Properties>
<!-- Properties:
TextColor3 = Color3(255, 255, 255)
TextSize = 18
-->
</Item>
</Item>
</roblox>
Value serialization
Values in property comments use a readable format:
Color3
<!-- BackgroundColor3 = Color3(255, 0, 153) -->
Token hex colors (in :root) are shown as hex:
<!-- primary: #335fff -->
UDim and UDim2
<!-- CornerRadius = UDim(0, 8) -->
<!-- Size = UDim2(1, 0, 0, 100) -->
Numbers and booleans
<!-- TextSize = 16 -->
<!-- Visible = false -->
Enums
<!-- TextXAlignment = Enum.TextXAlignment.Center -->
<!-- FillDirection = Enum.FillDirection.Vertical -->
Fonts
<!-- FontFace = GothamSSm -->
<!-- FontFace = Roboto -->
Token references
<!-- BackgroundColor3 = $primary -->
<!-- CornerRadius = $radius-md -->
ColorSequence
<!-- Color = ColorSequence(...) -->
Referent IDs
Each instance receives a unique referent ID for internal Roblox references:
<Item class="StyleSheet" referent="RBX0001">
<Item class="StyleRule" referent="RBX0002">
<Item class="StyleRule" referent="RBX0003">
Referents are sequential and start from RBX0001.
CLI usage
Output to file
rbx-css compile styles.css -o StyleSheet.rbxmx
rbx-css compile styles.css -o output.xml --format rbxmx
Custom StyleSheet name
rbx-css compile styles.css -o StyleSheet.rbxmx --name "AppStyles"
Programmatic API
import { compile, generateRBXMX } from "rbx-css";
const result = compile(
[{ filename: "styles.css", content: cssContent }],
{ name: "MyStyleSheet", warnLevel: "all", strict: false }
);
const rbxmx = generateRBXMX(result.ir);
console.log(rbxmx);
Rojo integration
To use RBXMX files with Rojo, reference them in your default.project.json:
{
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"Styles": {
"$path": "out/styles"
}
}
}
}
Place your generated .rbxmx files in the out/styles directory:
out/
styles/
StyleSheet.rbxmx
DarkTheme.rbxmx
Rojo will sync these files into ReplicatedStorage.Styles as StyleSheet instances.
Studio import
To import an RBXMX file into Studio:
- Right-click in the Explorer window
- Select “Insert from File…”
- Choose your
.rbxmx file
- The StyleSheet will appear in the selected location
Because properties are stored as comments, the imported StyleSheet will have empty rules. This format is currently only useful for inspecting the rule structure.
Limitations
Property encoding not implemented
The main limitation is that StyleRule properties are not fully encoded in RBXMX format. They appear only as comments:
<!-- Properties:
BackgroundColor3 = Color3(255, 255, 255)
-->
This means:
- Not functional: Rules won’t have any properties when imported
- Documentation only: Useful for viewing structure but not for production
- Manual editing required: You’d need to manually add properties in Studio
Future improvements
Full RBXMX property encoding would require:
- Proper XML attribute serialization for each Roblox data type
- Binary data encoding for complex types
- Attribute dictionary encoding for token references
When to use Luau instead
For production use cases, the Luau format is recommended because:
- Fully functional: All properties are properly set
- Type safe: Luau’s type system catches errors
- Minification: Supports minified output
- Flexible: Can be required and called at runtime
- Debuggable: Easier to inspect and modify
Use RBXMX only when:
- You need to inspect StyleSheet structure visually
- You’re prototyping and don’t need working properties
- You want to manually complete the StyleSheet in Studio