Vela getting started

Installation

Add the Vela transformer to a roblox-ts project — packages, tsconfig plugin, config file, and the ambient declaration.

Vela is a compile-time utility-class system for roblox-ts React. You write Tailwind-shaped class names on Roblox host elements and on your own components, and a TypeScript transformer rewrites them into real Roblox properties and helper instances before roblox-ts emits Luau.

Nothing about Vela is a runtime library you render. It is a transformer you register in tsconfig.json, plus a config file it reads from disk. This page gets both in place.

Install the package

pnpm add vela-rbxts

vela-rbxts expects the ordinary roblox-ts React stack alongside it. Install those yourself if the project does not already have them.

Runtime dependencies
pnpm add @rbxts/react @rbxts/react-roblox @rbxts/services

@rbxts/react and @rbxts/services matter beyond your own imports: when Vela takes its runtime path it inlines a helper module into your output that imports React from @rbxts/react and { UserInputService, Workspace } from @rbxts/services. Both must resolve in the built place even if you never import them by hand. @rbxts/react-roblox is what you need to mount a tree at all.

Dev dependencies
pnpm add -D roblox-ts typescript @rbxts/compiler-types @rbxts/types

Register the transformer

Vela runs as a roblox-ts transformer plugin. Add one entry to compilerOptions.plugins in your existing tsconfig.json:

tsconfig.json
{
"compilerOptions": {
"plugins": [{ "transform": "vela-rbxts/transformer" }]
}
}

That is the entire tsconfig change. Everything else in the file stays as your roblox-ts project already has it — Vela requires no compiler option of its own, and if the project builds today it will keep building. If you do not have a project yet, start from roblox-ts’s quick start and come back here.

vela-rbxts/transformer is a separate export from the package root. The root export (vela-rbxts) gives you defineConfig and types; the /transformer subpath is the callable roblox-ts consumes. Do not swap one for the other.

The plugin entry object is also where transformer options go — file-filter toggles, a diagnostic code base, a project root. The defaults are what you want to start with; the configuration reference covers the rest.

Add vela.config.ts

Vela looks for exactly one filename, vela.config.ts, walking up from the directory of each source file until it finds one or hits the filesystem root. There are no .js, .mjs or .cjs variants and no package.json key. If nothing is found, Vela uses its built-in default theme, which already contains 28 color families, ten radius keys, and the spacing fallback.

The minimum useful file accepts the defaults wholesale:

vela.config.ts
import { defineConfig } from "vela-rbxts";
export default defineConfig();

When you do want your own values, put them under theme.extend. Every value is an expression string written in the roblox-ts dialect, not a color object or a number:

vela.config.ts
import { defineConfig } from "vela-rbxts";
export default defineConfig({
theme: {
extend: {
colors: {
brand: {
500: "Color3.fromRGB(59, 130, 246)",
700: "Color3.fromRGB(29, 78, 216)",
},
},
radius: {
panel: "new UDim(0, 10)",
},
},
},
});

Full details on merge behavior and the shipped defaults are in the theming guide.

Declare the className prop

Roblox host elements have no className prop in @rbxts/types. Vela adds one by augmenting React.Attributes globally, and that augmentation only takes effect if the package is imported for its side effect somewhere in your program. Create a declaration file to do that once:

src/vela-env.d.ts
import "vela-rbxts";

That single import pulls in declare global { namespace React { interface Attributes { className?: ClassValue } } }. Without it, every className you write is a type error, even though the transformer would still have processed it.

Keep the file inside rootDir so TypeScript picks it up with the rest of your sources.

Build and serve

There is no Vela-specific build step. Compile with roblox-ts as usual:

Build
npx rbxtsc

Then sync out/ into Studio with Rojo the same way you already do:

Serve
rojo serve

You do not need a Rojo mapping for Vela, and there is no Vela runtime package to place in the DataModel. Everything Vela produces is either an ordinary Roblox property, a helper instance emitted as a JSX child, or — on the runtime path — a helper module inlined directly into the same output file. The only things that must exist in your place tree are @rbxts/react and @rbxts/services, which your existing node_modulesReplicatedStorage mapping already covers.

Next step

Write something and watch it lower in Your first component.