npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rbxts-transform-luau

v1.0.1

Published

roblox-ts transformer: idiomatic Luau output — preamble organization, comment cleanup, const promotion, and directive injection

Readme

rbxts-transform-luau

A roblox-ts / rotor TypeScript transformer that makes compiled Luau output idiomatic — cleaning up noise, organizing the preamble, injecting Luau directives, annotating types, and converting JSDoc comments.

What it does

Luau directives

Injects --!strict and/or --!optimize N at the top of every file.

--!native
--!optimize 2
--!strict

Preamble organization

Sorts the top of every file into labeled sections: directives → services → runtime → imports. Makes the compiled output readable at a glance.

--!optimize 2
--!strict

-- Compiled with roblox-ts v3.0.0

-- Services
const _ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Runtime
const TS = require(_ReplicatedStorage:WaitForChild("include"):WaitForChild("RuntimeLib"))

-- Imports
const fns; if false then fns = require(...) else fns = TS.import(...) :: any end

const promotion

Locals and imports that are never reassigned anywhere in the file are promoted to const, allowing the Luau native compiler to make stronger assumptions.

-- Before
local N = 100000
local function compute()
    local scale = 0.5
    local result = scale * N
local base; if false then base = require(...) else base = TS.import(...) :: any end

-- After
const N = 100000
local function compute()
    const scale = 0.5
    const result = scale * N
local base; if false then base = require(...) else base = TS.import(...) :: any end

Only variables initialized inline (local name = value) are eligible. Imports use a deferred-assignment workaround (local name; ... name = ...) that requires local in Luau, so they are left alone. Variables that are mutated anywhere in the file (i += 1, reassignment, etc.) are also correctly left as local.

Luau type annotations

Uses the TypeScript type checker to inject Luau type annotations into every function signature — covering inferred types that have no explicit annotation in source.

// Input — types inferred by TypeScript, not explicitly written
export function dot(a: Vector3, b: Vector3) {
    return a.X * b.X + a.Y * b.Y + a.Z * b.Z
}
export function lerp(a: number, b: number, t: number) {
    return a + (b - a) * t
}
-- Output — type checker resolved them; luau-lsp now sees them too
local function dot(a: Vector3, b: Vector3): number
local function lerp(a: number, b: number, t: number): number

Supports: primitives (number, string, boolean), Roblox value types (Vector3, CFrame, UDim2, etc.), arrays ({T}), and LuaTuple<[T, U]> → multi-return (T, U).

Set annotate: false to disable.

TS.import type hints

Wraps TS.import calls with a dead-code require branch so luau-lsp can infer the module's return type — zero runtime cost.

-- luau-lsp gets full autocomplete and types through the require branch
const fns; if false then fns = require(_ReplicatedStorage.shared.fns) else fns = TS.import(script, _ReplicatedStorage, "shared", "fns") :: any end

JSDoc → Luau doc comments

TypeScript JSDoc (@param, @returns, @deprecated) is converted to luau-lsp doc comment format with inferred Luau types. Works with both roblox-ts and rotor.

/**
 * Computes the dot product of two vectors.
 * @param a First vector.
 * @param b Second vector.
 * @returns Scalar result.
 */
export function dot(a: Vector3, b: Vector3): number { ... }

/** @deprecated Use dot() instead. */
export function oldDot(a: Vector3, b: Vector3): number { ... }
--- Computes the dot product of two vectors.
--- @param a Vector3 First vector.
--- @param b Vector3 Second vector.
--- @return number Scalar result.
local function dot(a: Vector3, b: Vector3): number

--- @deprecated Use dot() instead.
local function oldDot(a: Vector3, b: Vector3): number

Comment cleanup

Strips useless block comments (--[[ ]]) that compilers emit for non-function declarations where no useful information can be extracted.

Installation

npm install --save-dev rbxts-transform-luau

Setup

{
  "compilerOptions": {
    "plugins": [
      {
        "transform": "rbxts-transform-luau",
        "strict": true,
        "optimize": 2,
        "annotate": true
      }
    ]
  }
}

Options

| Option | Type | Default | Description | |---|---|---|---| | strict | boolean | true | Inject --!strict at the top of every file | | optimize | false \| 0 \| 1 \| 2 | false | Inject --!optimize N (false disables, 0/1/2 set the level) | | annotate | boolean | true | Inject Luau type annotations using the TypeScript type checker | | verbose | boolean | false | Log per-file processing info to the console |