Featured Packages

Curated official and community-contributed roblox-ts packages.

services by roblox-ts

Exports most commonly used Roblox services. This makes them really easy to use.

import { Players } from "@rbxts/services";
Players.PlayerAdded.Connect(player =>
  print("Player was added!", player.Name),

inspect by roblox-ts

A copy of kikito’s inspect.lua library with type definitions.

import inspect = require("@rbxts/inspect");
print(inspect([1, 2, 3]));

datastore2 by roblox-ts

A copy of Kampfkarren’s DataStore2 library with type definitions.

import { ReplicatedStorage, Players } from "@rbxts/services";
import DataStore2 = require("@rbxts/datastore2");

Players.PlayerAdded.Connect(player => {
  const coinsStore = DataStore2<number>("coins", player);

  const remote = ReplicatedStorage.CoinAmount as RemoteEvent;
  function callRemote(value: number) {
    remote.FireClient(player, value);

  // Fire a remote event to the player telling them how many coins they have.
  // If this is their first time playing the game, they'll start out with 100.

  // Everytime the coin store updates, we'll send the RemoteEvent again.

resources by evaera

rbx-resources lets you easily access game assets and create named instances in your game.

const event = getResource(RemoteEvent, "SomeRemoteEvent");
const sword = getResource<Model>("Weapon", "Darkheart");
const bindable = getLocalResource(BindableEvent, "FooBarBaz");

roact by roblox-ts

TypeScript and JSX support for Roact.

import * as Roact from "@rbxts/roact";

const LocalPlayer = game.GetService("Players")
  .LocalPlayer as Player;
const PlayerGui = LocalPlayer.FindFirstChildOfClass(

const tree = (
      Text="Hello, World!"
      Size={new UDim2(1, 0, 1, 0)}

Roact.mount(tree, PlayerGui, "HelloWorld");

t by osyrisrblx

t enables you to write complex type definitions and use them either at runtime or statically. Provides a robust set of tools to sanitize unknown data. Useful for making sure your remote events give the right data!

// complex type definition
const tPlayer = t.interface({
    name: t.string,
    score: t.number,
    data: t.interface({
        inventory: t.array(t.number),
        inventorySize: t.number,

// runtime usage
function bar(player: unknown) {
    if (tPlayer(player)) {

// static usage
type tPlayer = t.static<typeof tPlayer>;
function foo(player: tPlayer) {

net by Vorlias

Roblox Networking Library (rbx-net) is a useful library for abstracting Roblox networking. Not only does it make networking simpler, it also adds more functionality to remotes such as asynchronous function calls, result caching, invoking/calling groups of clients and much more.

import Net from "@rbxts/net";

// Create an Event
const myRemote = Net.CreateEvent("EventName");

// Create an event OOP style
const myRemote = new Net.ServerEvent("EventName");

// Connect events to listeners
function onMyRemoteEvent(player: Player) {
  print(player, "called me! :D");

// Fire an event to a client
myRemote.SendToPlayer(game.Players.Vorlias, "Hello, World!");

// Fire an event to multiple clients
myRemote.SendToPlayers([game.Players.Vorlias, game.Players.Osyris], "Hello, World!");

// Fire an event to all clients
myRemote.SendToAllPlayers("Hello, World!");
import Net from "@rbxts/net";

function onClientMyRemoteEvent() {
  print("The server called me!")

// await for client event, then connect
const myRemote = await Net.WaitForClientEventAsync("EventName");

// Get an event OOP style (Will error if doesn't exist, use Async methods!)
const myRemote = new Net.ClientEvent("EventName");

// wait for event (promise), then connect or if timeout - display message
Net.WaitForClientEventAsync("EventName").then(event => {
  // connect the event
}, failMsg => warn(failMsg));

// Send an event to the server!
myRemote.SendToServer("Hi server! :D");
import Net from "@rbxts/net";

// Create a function
const myFunction = Net.CreateFunction("FunctionName");

// Create a function OOP style
const myFunction = new Net.ServerFunction("FunctionName");

// Call a client (await)
const result = await myFunction.CallPlayerAsync("Hello?");

// Call a client (promise)
  result => print(result),
  errorMsg => warn(errorMsg)

// Create a callback for when clients call the server
myFunction.Callback = (player: Player) => {
  return player.Name:reverse(); // will return username reversed

// Set the amount of seconds the remote caches a return value when retrieved by client
myFunction.ClientCache = 10; // 10 seconds
import Net from "@rbxts/net";

// Get a function OOP style (Will error if doesn't exist, use Async methods!)
const myRemote = new Net.ClientFunction("EventName");

// Get function (await)
const myFunction = await Net.WaitForFunctionAsync("FunctionName");
myFunction.Callback = () => {
  return "Hi from the server!";

// Get function (promise)
const myFunction = Net.WaitForFunctionAsync("FunctionName").then(func => {
  // callback inside promise
  func.Callback = () => {
    return "Hi from the server!";
}, errorMsg => warn(errorMsg));

// Create a callback for when the server calls the client
myFunction.Callback = () => {
  return "hi I'm the client " + game.Players.LocalPlayer!.Name;

datastore-light by Dog2puppy

A simple data store wrapper with automatic retry and types support.

import { DataStore } from "@rbxts/datastore-light";

let MainStore = new DataStore<string>("Main", "MyScope", math.huge); // Creates a new DataStore object with the type 'string', the name 'main', the scope 'MyScope' and an infinite amount of retries

MainStore.set("hello", "hi");
MainStore.get("hello"); // hi

date by Validark

A reimplementation of the vanilla Lua function built atop the one exposed by Roblox Lua

// ISO 8601:
print(Date("%FT%T")); // 2020-01-01T01:03:05
print(Date("%Y-%m-%dT%H:%M:%S")); // 2020-01-01T01:03:05
print(Date("%FT%T%#z")); // 2020-01-01T01:03:05-05:00

// Time:
print(Date("%T")); // 08:37:43

// Date:
print(Date("%D")); // 01/12/20

// Also adds the ability to toggle padding by inserting a '#' like so:
print(Date("%#x", os.time()));

signal by Validark

Standard BindableEvent wrapper which passes values by reference instead of duplicating data

const signal = new Signal();
const strings = new Array<string>();

signal.Connect((a: unknown) => print(a))

print(strings) // table: 2BC04578
signal.Fire(strings) // table: 2BC04578

tween by Validark

A library for writing efficient, simple interpolation code

Here is the simplest form:

This will return a Tween object. x will be a number along the Standard curve [0, 1]. The interpolation will last 2 seconds. Standard is the EasingFunction, which is the curve along which this interpolation will animate.

Tween(2, Standard, x => print(x));

More examples here

extendable-resources by Validark

A library for defining resources so it can be easily imported by other modules.

import { ReplicatedStorage } from "@rbxts/services";
import makeFolderManager from "@rbxts/extendable-resources";

// creates/finds a folder named "RemoteEvents" in ReplicatedStorage
// if it can't find a particular object, it will instantiate a RemoteEvent with the proper name
const getRemoteEvent = makeFolderManager(ReplicatedStorage, "RemoteEvents", "RemoteEvent");

export const Chatted = getRemoteEvent("Chatted");
export const Cleanup = getRemoteEvent("Cleanup");

// or in another library

// Not necessary to specify "Model", but it will force returned values to be a Model type
const getMap = makeFolderManager<"Model">(ReplicatedStorage, "Maps");

export const SFOTH = getMap("SFOTH");
export const City = getMap("City");

// Then you can easily import the needed resources into another library
import { Chatted, Cleanup } from "ReplicatedStorage/RemoteEventDefinitions";