
Product
Introducing Reports: An Extensible Reporting Framework for Socket Data
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.
@trembus/ss-fusion
Advanced tools
A modern, reactive UI component library for Roblox built with TypeScript and Fusion
A modern, reactive UI component library for Roblox built with TypeScript and Fusion
SS-Fusion is a comprehensive UI component library designed specifically for Roblox games, built with modern development practices and following the Atomic Design methodology. It provides a set of reusable, themeable, and type-safe components that make building consistent game UIs effortless.
See also: Component Status Tracker — docs/COMPONENT_STATUS.md And the companion Component TODO Tracker — docs/COMPONENT_TODOS.md Versions index — VERSIONS.md
npm install @trembus/ss-fusion
# or
pnpm add @trembus/ss-fusion
# or
yarn add @trembus/ss-fusion
import { Button, Label, ProgressBar } from "@trembus/ss-fusion";
import Fusion, { Value } from "@rbxts/fusion";
// Create reactive state
const playerHealth = Value(75);
const maxHealth = Value(100);
// Create components
const healthBar = ProgressBar({
currentValue: playerHealth,
maxValue: maxHealth,
fillColor: Color3.fromRGB(255, 100, 100),
showLabel: true
});
const healButton = Button({
text: "Heal",
variant: "primary",
onClick: () => {
playerHealth.set(math.min(playerHealth.get() + 25, maxHealth.get()));
}
});
const title = Label({
text: "Player Stats",
variant: "heading"
});
SS-Fusion follows the Atomic Design methodology, providing components at different levels of complexity:
Avatar - User profile images, player thumbnails, and fallback displaysButton - Unified text/icon button with multiple variantsLabel - Typography component with consistent themingTextBox - Input component with validation and focus statesProgressBar - Progress visualization for health, mana, XP, etc.SlicedImage - 9-slice scalable images for panels and bordersDragHandle - Title-bar style drag area that emits movement deltas (UIDragDetector)CooldownButton - Button with integrated cooldown timer and progress barTitleBar - Window header with title and optional closeDraggable - Wrap any UI with a UIDragDetector for simple drag behaviorDropZone - Declarative drop target with accept rules and feedbackPanelWindow - Window-like panel: TitleBar + content area, optional closeUser profile images (Roblox thumbnails) with customizable shape and border. Defaults to the local player's UserId when none is provided.
import { Avatar } from "@trembus/ss-fusion";
import { Value } from "@rbxts/fusion";
// Local player, 64x64, circular
const me = Avatar({ size: "medium", shape: "circle" });
// Specific user, square, bordered, explicit size
const other = Avatar({
userId: 123456,
shape: "square",
showBorder: true,
borderColor: Color3.fromRGB(200, 200, 200),
Size: UDim2.fromOffset(64, 64)
});
// Reactive user switching
const current = Value(123456);
const dynamicAvatar = Avatar({ userId: current, size: "large", shape: "rounded" });
current.set(789012); // updates the image
// Custom placeholder while loading/failure
const withPlaceholder = Avatar({ placeholderImage: ImageConstants.DefaultUnassigned });
Props summary:
userId?: number | Value<number> (defaults to LocalPlayer.UserId)size?: "small" | "medium" | "large" (maps to 48/100/180)shape?: "circle" | "rounded" | "square"showBorder?: boolean; borderColor?: Color3thumbnailType?: Enum.ThumbnailType (default HeadShot)placeholderImage?: string; backgroundColor?: Color3Versatile button component supporting text, icons, and multiple visual variants.
// Text button
const saveButton = Button({
text: "Save Game",
variant: "primary",
onClick: () => savePlayerData()
});
// Icon button
const settingsButton = Button({
icon: "rbxassetid://123456789",
variant: "icon",
size: "large",
onClick: () => openSettings()
});
// Styled button with background
const epicButton = Button({
text: "Epic Action!",
backgroundImage: "rbxassetid://987654321",
variant: "accent"
});
Available Variants: primary | secondary | accent | danger | ghost | icon
Available Sizes: small | medium | large
Typography component with semantic variants and full theming support.
const title = Label({
text: "Game Title",
variant: "heading",
textColor: Color3.fromRGB(255, 255, 255)
});
const description = Label({
text: "Your adventure begins here...",
variant: "body",
textStroke: true
});
Available Variants: heading | body | caption | small
Feature-rich input component with validation, focus states, and theming.
const usernameInput = TextBox({
placeholder: "Enter username...",
validate: (text) => text.length >= 3,
onChanged: (text) => setUsername(text),
maxLength: 20
});
const messageBox = TextBox({
placeholder: "Type your message...",
multiline: true,
maxLength: 500,
size: "large"
});
Flexible progress visualization supporting both percentage and absolute values.
// Health bar with absolute values
const healthBar = ProgressBar({
currentValue: currentHealth,
maxValue: maxHealth,
fillColor: Color3.fromRGB(255, 100, 100),
showLabel: true,
direction: "horizontal"
});
// XP bar with percentage
const xpBar = ProgressBar({
currentValue: expPercentage, // 0.0 to 1.0
fillColor: Color3.fromRGB(100, 255, 100),
showLabel: true,
labelText: customExpText
});
Advanced button with integrated cooldown functionality - perfect for abilities and actions.
const abilityButton = CooldownButton({
icon: "rbxassetid://ability-icon",
cooldown: 10, // 10 seconds
onClick: () => {
castAbility();
// Cooldown automatically starts
}
});
// Show a label on the cooldown bar
const labeledAbilityButton = CooldownButton({
icon: "rbxassetid://ability-icon",
cooldown: 10,
showCooldownLabel: true,
// Optional
// cooldownLabelText: Value("Ready in..."),
// cooldownLabelColor: Color3.fromRGB(255,255,255),
});
SS-Fusion includes simple layout helpers to compose UIs quickly and consistently.
Horizontal/vertical stacks built on UIListLayout with gap, padding, alignment, and justification.
import { HStack, VStack, Spacer } from "@trembus/ss-fusion";
// Row: avatar, name, flexible spacer, action button
const header = HStack({
gap: 8,
align: "center",
children: [
Avatar({ size: "small", shape: "circle" }),
Label({ text: "Player123", variant: "heading" }),
Spacer({ direction: "row" }), // pushes the button to the far end
Button({ text: "Invite", variant: "primary" }),
],
});
// Column: title, description, actions
const column = VStack({
gap: 12,
padding: 8,
align: "start",
children: [
Label({ text: "Quest", variant: "heading" }),
Label({ text: "Defeat 10 skeletons", variant: "body" }),
HStack({ gap: 8, children: [Button({ text: "Track" }), Button({ text: "Abandon", variant: "danger" })] }),
],
});
Props (Stack):
direction: "row" | "column" (use HStack/VStack helpers)gap?: number spacing between childrenpadding?: number for all sidesalign?: "start" | "center" | "end" (cross-axis)justify?: "start" | "center" | "end" | "spaceBetween" (main-axis)Flexible (or fixed) gap used inside stacks to push or separate content.
// Fixed 16px spacer in a vertical stack
VStack({ gap: 8, children: [Label({ text: "Top" }), Spacer({ direction: "column", size: 16 }), Label({ text: "Bottom" })] });
Uniform grid layout using UIGridLayout. AutoGrid picks a cell size based on container width.
import { Grid, AutoGrid } from "@trembus/ss-fusion";
// Fixed-size cells
const inventory = Grid({
cellSize: UDim2.fromOffset(64, 64),
cellPadding: UDim2.fromOffset(8, 8),
children: items.map((it) => renderSlot(it)),
});
// Responsive cells (min/max), recomputes on container resize
const responsive = AutoGrid({
cellPadding: UDim2.fromOffset(8, 8),
minCellPx: 72,
maxCellPx: 128,
children: items.map((it) => renderSlot(it)),
});
Notes:
Size if you need fixed dimensions.AbsoluteSize.SS-Fusion comes with a comprehensive theming system that ensures visual consistency.
export const defaultColorScheme = {
Primary: Color3.fromRGB(59, 130, 246), // Blue-500
Secondary: Color3.fromRGB(107, 114, 128), // Gray-500
Accent: Color3.fromRGB(168, 85, 247), // Purple-500
Background: Color3.fromRGB(255, 255, 255), // White
Surface: Color3.fromRGB(249, 250, 251), // Gray-50
Error: Color3.fromRGB(239, 68, 68), // Red-500
Success: Color3.fromRGB(34, 197, 94), // Green-500
Warning: Color3.fromRGB(245, 158, 11), // Amber-500
};
// Spacing (4px grid system)
export const spacing = {
xs: 4, sm: 8, md: 16, lg: 24, xl: 32, xxl: 48, xxxl: 64
};
// Typography
export const fontSizes = {
xs: 12, sm: 14, md: 16, lg: 18, xl: 20, xxl: 24, xxxl: 32
};
// Border radius
export const borderRadiusValues = {
none: 0, small: 4, medium: 8, large: 16, full: 9999
};
SS-Fusion is designed with game development in mind, providing common patterns for RPG and action games:
import { ProgressBar, Label } from "@trembus/ss-fusion";
const createPlayerStatsUI = (player: Player) => {
const stats = player.stats;
return [
Label({ text: `${player.name} - Level ${stats.level.get()}` }),
ProgressBar({
currentValue: stats.health,
maxValue: stats.maxHealth,
fillColor: Color3.fromRGB(255, 100, 100),
showLabel: true
}),
ProgressBar({
currentValue: stats.mana,
maxValue: stats.maxMana,
fillColor: Color3.fromRGB(100, 100, 255),
showLabel: true
})
];
};
Roblox’s UIDragDetector enables cursor/touch-driven manipulation of 2D UI. SS‑Fusion exposes a few small primitives to make this ergonomic.
Important: UIDragDetector is currently a Studio beta feature — enable it via File > Beta Features > UIDragDetectors to test locally.
Components:
Simple examples:
import { PanelWindow } from "@trembus/ss-fusion/organisms";
import { DragHandle } from "@trembus/ss-fusion/atoms";
import { Draggable, DropZone } from "@trembus/ss-fusion/molecules";
import * as Drag from "@trembus/ss-fusion/utils/drag";
// Make a window and move it by dragging the title area
const win = PanelWindow({ titleLabel: "Inventory", closeButton: true });
DragHandle({
Size: UDim2.fromOffset(300, 32),
onDelta: (d) => (win.Position = new UDim2(
win.Position.X.Scale + d.X.Scale,
win.Position.X.Offset + d.X.Offset,
win.Position.Y.Scale + d.Y.Scale,
win.Position.Y.Offset + d.Y.Offset
)),
Parent: win,
});
// A draggable item that publishes a payload
const item = Draggable({
responseStyle: Enum.UIDragDetectorResponseStyle.Offset,
onDragStart: (pos) => Drag.startDrag({ type: "item", data: { id: "red-gem" } }, pos),
onDrag: Drag.update,
onDragEnd: Drag.endDrag,
});
// A drop zone that accepts items
const zone = DropZone({ accepts: ["item"], onDrop: (p) => print("Dropped", p.data) });
See a complete working example in src/examples/drag-demo.ts.
import { CooldownButton } from "@trembus/ss-fusion";
const createAbilityHotbar = (abilities: Ability[]) => {
return abilities.map((ability, index) =>
CooldownButton({
icon: ability.icon,
cooldown: ability.cooldownTime,
onClick: () => ability.cast(),
Size: new UDim2(0, 60, 0, 60)
})
);
};
For detailed API documentation, see:
# Install dependencies
pnpm install
# Build the library
pnpm run build
# Watch for changes during development
pnpm run watch
ss-fusion/
├── src/
│ ├── atoms/ # Basic UI components
│ ├── molecules/ # Composite components
│ ├── organisms/ # Complex UI sections (planned)
│ ├── templates/ # Layout structures (planned)
│ ├── types/ # TypeScript definitions
│ ├── utils/ # Theming and utilities
│ └── examples/ # Usage examples
├── out/ # Compiled Lua output
└── package.json
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the ISC License - see the LICENSE file for details.
SS-Fusion - Building better game UIs, one component at a time 🚀
FAQs
A modern, reactive UI component library for Roblox built with TypeScript and Fusion
The npm package @trembus/ss-fusion receives a total of 23 weekly downloads. As such, @trembus/ss-fusion popularity was classified as not popular.
We found that @trembus/ss-fusion demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.