Velareference

API

Everything importable from `vela-rbxts`, the published packages, and the versions it is tested against.

Vela’s import surface is small. One package has a public entry point, that entry point exports three values and four types, and a second subpath exports the transformer you wire into tsconfig.json.

pnpm add vela-rbxts

From vela-rbxts

import {
defaultConfig,
defineConfig,
definePreset,
plugin,
createTransformer,
type TailwindConfig,
type TailwindConfigInput,
type VelaPreset,
type ThemeScreens,
type VariantDefinition,
type ClassValue,
type StylableProps,
} from "vela-rbxts";

The plugin and variant types are re-exports of @vela-rbxts/config, so nothing needs to be installed to reach them.

defineConfig

function defineConfig(input?: TailwindConfigInput): TailwindConfig;

Takes an input-shaped theme object and resolves it against the built-in defaults. The argument is optional, and defineConfig() returns a fresh object deep-equal to defaultConfig. It is injected into vela.config.ts’s scope automatically, which is why stripping the import still works.

defaultConfig

const defaultConfig: TailwindConfig;

The resolved built-in theme: 28 colour families, ten named radius keys plus a DEFAULT, and a single spacing key. This is what Vela uses when no vela.config.ts is found.

createTransformer

function createTransformer(
options?: RbxtscTransformerBridgeOptions,
): RbxtscTransformerBridge;
// the returned bridge:
// { name, getFileEligibility, shouldTransformFile, transformSource, transformFile }

The rbxtsc host bridge, returning an object whose name is "@vela-rbxts/rbxtsc-host" plus the eligibility predicates and the transform entry point. transformSource and transformFile are the same function under two names.

You do not need this to use Vela — it exists for tooling that drives the transform itself.

Types

PropTypeDescription
TailwindConfig{ theme: { colors: ThemeColors; radius: ThemeScale; spacing: ThemeScale } }A fully resolved config — every scale present. What defineConfig returns and what the compiler consumes.
TailwindConfigInput{ theme?: { colors?; radius?; spacing?; extend?: { colors?; radius?; spacing? } } }The authoring shape — everything optional, with the extend branch. What you pass to defineConfig.
VelaPresetTailwindConfigInputA shareable slice of configuration. Same shape as what you pass to defineConfig; definePreset() types one without resolving it, so it still merges as an input rather than as a finished config. Added in 0.13.0.
ClassValuestring | number | boolean | null | undefined | Record<string, boolean | null | undefined> | ClassValue[]The accepted type of the className prop. Covers conditional dictionary and nested array forms, not just strings.
StylablePropsStylableProps<P = unknown>Intersects your own props P with { className?: ClassValue }. Use it when a component of yours should forward className.

The global augmentation

Importing vela-rbxts has a side effect: it declares

declare global {
namespace React {
interface Attributes {
className?: ClassValue;
}
}
}

That augmentation is what makes className type-check on the host elements. It applies only once the module is imported somewhere your program includes, typically a one-line .d.ts:

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

Several helpers exist in @vela-rbxts/config but are not re-exported from the root. The functions are SHADES, PALETTE_DEFAULT_KEY, resolveThemeColors, mergeColorRegistry, normalizeColorRegistry and normalizeColorScale. The types are Shade, PaletteKey, PaletteDefaultKey, ThemeScale, ColorPalette, ColorValue, ColorScaleInput, ThemeColors, ColorInputMap, ThemeConfig and ThemeConfigInput. Reach into @vela-rbxts/config directly, and expect them to be less stable.

From vela-rbxts/transformer

A CommonJS module whose export is a callable program-transformer factory. It also carries .createTransformer, .createRbxtsTailwindProgramTransformer and .default, all pointing at itself, so every resolution style lands on the same function.

This is the value that goes in tsconfig.json:

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

The factory throws if roblox-ts does not hand it a TypeScript instance. Plugin options are in Configuration.

Published packages

PackageWhat it isInstall directly?
vela-rbxtsThe entry point: config helpers, types, the global augmentation, the transformer subpath, and — since 0.11.0 — the vela CLIYes — this is the only one an app installs
@vela-rbxts/compilerThe Rust compiler behind an N-API binding: transform, completions, hover, diagnostics, document colorsNo, pulled in transitively
@vela-rbxts/compiler-wasmThe same compiler built to WebAssembly, for hosts that cannot load the native addon — a browser, most usefullyOnly if you are lowering classes outside Node
@vela-rbxts/configThe theme schema, defineConfig, defaultConfig, and the color merge helpersOnly to reach a helper the root package does not re-export
@vela-rbxts/coreShared constants, including the supported host element tagsNo — and nothing depends on it, so it never arrives transitively either
@vela-rbxts/irThe intermediate style representation shared between the compiler and its consumersNo
@vela-rbxts/typesShared TypeScript typesNo
@vela-rbxts/rbxtsc-hostThe roblox-ts adapter: file eligibility, config discovery, diagnostic mappingNo
@rbxts/vela-runtime-coreThe target-neutral half of the runtime: resolution engine, theme normalization, rem math, rich text, margin and divide computationNo, pulled in by whichever host you emit for
@rbxts/vela-runtimeThe React runtime host every transformed module imports, as one ModuleScript the place sharesNo — it ships with vela-rbxts
@rbxts/vela-runtime-videThe same host for Vide, imported instead when the project sets framework: "vide"No — it ships with vela-rbxts
@vela-rbxts/lspThe language server binary and its platform packagesOnly if you wire up a non-VS Code editor yourself
vela-rbxts-lspThe VS Code extension, published as a VSIX rather than to npmInstall from the marketplace as astra-void.vela-rbxts-lsp

For almost every project: install vela-rbxts, add the transformer to tsconfig.json, install the VS Code extension. Everything else arrives as a dependency.

The three @rbxts/vela-runtime* packages are the exception to “nothing of Vela’s reaches your place”. They sit under the @rbxts scope because roblox-ts only resolves a package whose scope directory is one of the project’s typeRoots. That is the one every roblox-ts project lists and every Rojo template maps. So they need no tsconfig or Rojo change. But pnpm needs nodeLinker: hoisted for the directory to be real, covered in installation.

Each host declares its own UI library as an optional peer, which keeps a Vide project from installing React. The host you do not emit for is inert.

The root package also declares two bin entries, vela and vela-rbxts, pointing at the same CLI. It lowers a source tree ahead of rbxtsc for projects that cannot register the transformer — see the CLI reference.

All packages are versioned in lockstep at 0.13.0, the VS Code extension included. Never mix versions across the @vela-rbxts/* scope. What changed in each release is in the release notes.

Three subpaths beyond the roots are public. @vela-rbxts/rbxtsc-host/project-config exposes config discovery and loading, which the VS Code extension uses to evaluate the config files it watches. @vela-rbxts/compiler/native exposes the raw N-API binding. Both roots also declare "./package.json" in their exports maps. The root package ships a schema.json describing the config input shape — point a vela.config.json’s $schema at it.

Version requirements

No package declares an engines field except the VS Code extension, which requires VS Code ^1.90.0. No package declares any peerDependencies either. roblox-ts, TypeScript and React are ordinary dependencies throughout, so nothing is checked at install time. You find out from a build failure, and in the TypeScript case below, from one that does not mention versions.

What the project is developed and tested against:

ToolVersion
Node24 (what CI runs)
TypeScript5.9.3, pinned exactly — see below
roblox-ts^3.0.0
@rbxts/react^17.3.7-ts.1
@rbxts/services^1.6.0

@rbxts/services is a genuine runtime dependency: the runtime helper imports UserInputService and Workspace from it to evaluate variants.

Prebuilt compiler binaries

The compiler ships N-API binaries for these targets:

  • x86_64-unknown-linux-gnu
  • x86_64-unknown-linux-musl
  • aarch64-unknown-linux-gnu
  • aarch64-apple-darwin
  • x86_64-apple-darwin
  • x86_64-pc-windows-msvc

There is no aarch64-pc-windows-msvc build and no linux arm64 musl build, so those two targets need the compiler crate built from source.

Two things look like escape hatches and are not. The napi-rs loader ends with a WASI fallback reaching for @vela-rbxts/compiler-wasm32-wasi, which is not published. It always falls through to Cannot find native binding., whose advice to reinstall without a lockfile is misleading on a platform that has no binary. And @vela-rbxts/compiler-wasm is a separate package with its own API, not a drop-in fallback.

See also