The next evolution of interface programming on Roblox

Mess-Free Backend

No more dependency messes, difficult readability, or strict formatting. Don't get pulled back by individual design philosophies you are forced to agree with, and enter a world where YOUR code comes first.

Easy To Learn

Seam is built for beginners, inspired by the Fusion syntax, and powered by simplicity. Quickly learn Seam, and integrate it into to your projects without friction. It's stress-free onboarding and easy to use across a team of any size.

Animate Fluidly

Animate using tweens, springs, or computes to create bounce, squash, swing, or whatever you want, to your heart's content. Never be limited by vanilla interface animation again.

Light As Feathers

Your project deserves an interface framework that doesn't strain the rest of your code. Free up some space for what really matters in your codebase.

It's time to make UI better

It's open-source and free, so give it a spin and see what you think.

Getting Started

Jump straight into Studio and import the module from the release page on GitHub, or alternatively, copy over the source code yourself. Roblox toolbox model coming soon!

Then, learn how to use it! If you're new, take a look at the intro tutorial, or if you're more technical and ready, take a look at the Seam documentation.

Seam is an unfinished product and does not yet have a tutorial. For now, read the documentation!

Before You Begin

Make sure you take a look at the tutorial to see how you set up your project and use everything!

Navigate

Declarations

Make, hydrate, and modify instances.

States

Reactive states for animation, input, and value simplification.

Memory

Manual and automatic cleanup, preventing memory leaks.

Connections

Signal-based reactivity based on given input.

Preset Components

[NOT YET DOCUMENTED] Out-of-the-box components you can use with From().

And more coming soon!

Expect the following to release in the future:
- FollowProperty() and FollowAttribute(), which automatically updates value states based on property and attribute changes
- Attribute(), which sets an attribute in an instance using New()
- OnAttributeChanged(), which acts like OnChange() but for specific attributes
- ForValues() and ForKeys(), to add reactive tables
- ConnectToTick() for custom tick rates on heartbeats
- Render(), which acts like Computed(), except it force recalculates the value every frame
- Lifetime(), which is used as an index in New() to declare that an instance should be cleaned up after a certain time
- StageGui preset component
- BasicWindow preset component
- Bug fixes, polishes, and backend improvements

Spring

An animation state using the spring method

TypeSinceScoped
State0.0.1Yes

Constructor

Spring(Target : Value | any, Speed : number, Dampening : number)

Properties

Value : any

The position of the spring.

Velocity : any

The velocity of the spring.

Target : Value | any

The target value that the spring position should reach.

Dampening : number

A value between 0 and 1 describing the friction of the spring. Going over 1 applies overdamping.

Speed : number

The speed of the spring.

Events

Changed

Fired when the value of the spring changes.

Usage

Springs are animation objects that simulate hooke’s law in any Roblox type. There are four types of springs:- Undamped (dampening = 0)
- Underdamped (1 > dampening > 0)
- Critically damped (dampening = 1)
- Overdamped (dampening > 1)
Each of these provide different levels of simulated friction, with undampended being the least and overdamped being the most. Critically damped springs create just enough friction to have no “bounce”.Springs can be created on their own, like this:

Or as a property of a hydrated Seam object, like this:

Tween

An animation state using the tween method

TypeSinceScoped
State0.0.1Yes

Constructor

Tween(Target : Value | any, TweenInfo : TweenInfo)

Properties

Value : any

The position of the tween.

Target : Value | any

The target that the tween should reach.

TweenInfo : TweenInfo

The TweenInfo associated with the tween object.

Events

Changed

Fired when the value of the tween changes.

Usage

Or as a property of a hydrated Seam object, like this:

Computed

A reactive state that updates based on when other values update

TypeSinceScoped
State0.0.1Yes

Constructor

Computed(CalculationFunction : (Use : (Value : Value) -> Value.Value) -> nil)

Properties

Value : any

The current value of the compute.

Usage

Computed acts as a state that is updated every frame. For example, if you want the x-position of a frame instance to be based on a number value, then you can do:

Computeds can be created on their own, like this:

Or embedded like this:

Value

A core state representing a single value that can be set or read at any time

TypeSinceScoped
State0.0.1Yes

Constructor

Value(Value : any)

Properties

Value : any

The value of the value object. Can be either set or read.

Events

Changed

Fired when .Value changes

Usage

To create a value object, simply call Value(), passing in any value type. In this case, we will be doing a number.

Value objects can lead to a reaction in another state. For example, in either springs or tweens, you can pass a value object in the first parameter. If you do, updating the value updates the animation.

Values can also be used in computeds to update calculations, like so:

New

Constructs a Roblox instance, or hydrates an existing one with Seam states

TypeSinceScoped
Declaration0.0.1Yes

Constructor

New(Object : string | Instance, Properties : {[any] : any}, From : From?) -> Instance

Usage

New is the heart of Seam, giving everything the framework functionality. It’s a constructor to make new instances, or hydrate existing ones.To make a brand new instance, use New like this:

Or alternatively, hydrate an existing instance by replacing the string with the instance you want, like this:

There are three parameters: object (as a string or instance), properties (as a dictionary), and optionally a common component (read more about From() to learn about this third parameter).You can use states and other declarations with New. Read more about it in the rest of the documentation!

Children

Declares children of an instance when paired with New()

TypeSinceScoped
Declaration0.0.1Yes

Usage

Children is used as in index in the New constructor to declare the children of said instance. It’s used like this:

DeclareComponent

A simple constructor/callback to tell Seam that you made a component

TypeSinceScoped
Declaration0.0.1Yes

Constructor

DeclareComponent(ComponentName : string, Constructor : (HydratedInstance : Instance, ...any) -> Instance)

Usage

DeclareComponent is used to declare components that you can later use. Components declared with this function can be called back to by using From.Let’s assume we want to declare a component that turns a frame into a blue one. We can declare this component by typing:

To use this, we can later use From, like so:

From

Uses a preset or declared component

TypeSinceScoped
Declaration0.0.1Yes

Constructor

From(ComponentName : string)

Usage

From is a callback used in the New constructor to call back to an already-declared component. You can read about this in the documentation for DeclareComponent.

Scope

A core memory manager in Seam

TypeSinceScoped
Memory0.0.1Yes

Constructor

Scope {[ObjectName : string] = Object : SeamScopableObject}

Methods

InnerScope() -> Scope

Returns an inner scope, which a sub-scope derived from the main scope.

Destroy() -> nil

Destroys the scope and cleans up all descendants.

Usage

Scope is a janitor-like organization object that groups instances together. Anything created with a Scope-declared Seam object will be cleaned up when the scope itself is destroyed.To make a scope, you declare what Seam objects you want to include. Be weary that an object must be marked as scopable, otherwise you will get an error.

In this example, you can make an object with the scope by calling Scope:New:

Let’s continue this example. Let’s say we want to create a child group of frames. To do so, we can call InnerScope():

And we can use it the same way:

If we want to clean up the frames in this example, we can call FramesScope:Destroy(). Alternatively, or in addition, we can also call MyScope:Destroy().

OnChanged

Used to track changes in states or instances

TypeSinceScoped
Connection0.0.1Yes

Usage

OnChanged is an Seam index to be used in the New constructor. OnChanged detects when an instance changes, e.g. when it changes color or size.You can use it like so:

You can also track states, like so:

OnEvent

Used to track any events in a Roblox instance

TypeSinceScoped
Connection0.0.1Yes

Usage

OnEvent is an Seam index to be used in the New constructor. OnEvent detects a specified rbx event that could be fired.You can use it like so: