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

@thigasdevelopment/luam

v1.1.0

Published

The Luam compiler for Multi Theft Auto resources.

Readme

Write .luam files with types, classes, enums and template strings. The compiler checks them and emits readable Lua 5.1 plus a generated meta.xml — a resource your MTA server can start as-is.

It is typed Lua, not TypeScript. Blocks still end with end, inequality is still ~=, and comments use # and #* ... *#.

enum Target { LUA_51, MTA }

class Luam {
    version: string
    target: Target = Target.LUA_51
    files: number = 0

    constructor = function (version: string)
        self.version = version
    end

    compile = function (source: string): string
        self.files += 1

        return `Luam ${self.version} compiled ${source} to plain Lua 5.1`
    end
}

local luam = new Luam('0.18.0')

outputServerLog(luam:compile('src/server/main.luam'))

Annotations are erased at build time. dxDrawText in a server file, a typo in an MTA function name, a string where a number belongs — all build errors, before the server starts. A build with any error writes nothing.


Install

Needs Node.js 20+ and an MTA:SA 1.5+ server. No Lua toolchain.

npm install --global @thigasdevelopment/luam
luam --version

Then install the VS Code extension — it runs the same checker as the CLI:

luam setup      # detects your editors and asks before installing
luam doctor     # verifies CLI, editors and extension

Installation · InstalaçãoPATH troubleshooting, npx, install from source, manual .vsix.


Quick start

1. Scaffold. init writes exactly one file, .luam.manifest.

mkdir my-resource && cd my-resource
luam init

2. Write some Luam. Create the source tree yourself — the folder decides the environment: src/server, src/client, src/shared.

my-resource/
├── .luam.manifest
└── src/
    ├── shared/config.luam
    ├── server/main.luam
    └── client/hud.luam

3. Build.

luam check   # diagnostics only, writes nothing
luam build   # writes build/my-resource

An error names the file, the line and the rule:

src/client/hud.luam:4:5 error check-environment-api: API "outputChatBox" is server-only and is not available in a "client" file.

4. Run it. Copy build/my-resource into <MTA Server>/mods/deathmatch/resources/, then refresh and start my-resource in the server console.

5. Iterate. Name your MTA server once in a .luam.server beside the resource and let dev build, sync, restart and stream logs on every save:

serverPath = 'C:/MTA Server'
luam dev
luam dev --start-server # also starts and owns the local MTA process

Quick start · Início rápido


Commands

| Command | What it does | | --- | --- | | luam init | Scaffolds .luam.manifest and stops | | luam check | Compiles and prints diagnostics. Writes nothing — this is the CI command | | luam build | Writes the bundled resource into <build.output>/<folder>, plus a source map | | luam dev | Build, sync, restart and watch, while following the server log | | luam ensure | Build, sync and restart on every save | | luam server | Run an existing local MTA server in the foreground | | luam trace | Resolves a production error position back to the authored file | | luam setup | Installs the editor extension | | luam doctor | Reports CLI, Node.js, detected editors and extension status |

Exit codes: 0 success, 1 build errors, 2 invalid command line or configuration. Progress goes to stderr and the report to stdout.

CLI commands · Comandos da CLI — every option and exit-code details.


The language

| Feature | Notes | | --- | --- | | Type annotations | Optionals, unions, arrays, aliases, generics, fun(string): void — all erased | | Classes | extends, implements, constructor, super(...), new | | Decorators | @Getter and @Setter generate typed accessors | | Interfaces | Verified by the checker, never reach the generated Lua | | Enums | Zero-based, checked members, erased when unused | | Template strings | `Hi ${name:Guest}` — scope-checked, with defaults | | Operators | +=, -=, *=, /=, ..=, and score++ / score-- as statements | | Comments | # line and #* block *#; length without a space is #items | | Object extensions | items.count, name.trim, ratio.clamp(a, b) | | Multi-return | local x, y, z = getElementPosition(el) — typed from the MTA catalog | | export | Erased from the Lua, written into meta.xml | | Native libraries | sleep plus Threads, Async and Dotenv, injected only when named | | MTA OOP classes | Player.getRandom(), File.exists(path), callable constructors | | Deployment values | .env keys typed as env.SERVER_NAME, server-only | | Strictness | #!strict (default), #!nonstrict, #!nocheck per file |

class, constructor, declare, enum, export, extends, implements, interface, new and type are reserved on top of the Lua 5.1 keywords. Property names still work (config.type), and type(value) keeps working. Porting existing Lua? Rename to .luam, add #!nocheck, and annotate module by module.

Environments

Every file is server, client or shared — from its folder, or from a #! directive. That decides which MTA APIs resolve: dxDrawText in a client file is fine, outputChatBox in the same file is a build error.

server and client may use shared declarations; shared may use only shared; server and client never see each other. A name the catalog does not know stays any, so a missing API never blocks a build.

The language · A linguagem — every feature, with the emitted Lua and the errors it catches.


Output

build/
├── my-resource.luam-map.json
└── my-resource/
    ├── meta.xml
    ├── config.lua
    ├── .env
    ├── assets/
    └── src/
        ├── shared.lua
        ├── server.lua
        └── client.lua

build ships at most one bundle per non-empty environment; config.lua, .env and assets stay at their own paths, and the map stays outside the resource. ensure defaults to a mirrored tree and dev always uses one.

Output layouts and source maps


Configuration

.luam.manifest is one table of five sections, and the folder that holds it names the resource.

{
    info = {
        version = '1.0.0',
    },

    scripts = {
        { path = 'src/shared/**/*.luam', type = 'shared' },

        { path = 'src/server/**/*.luam', type = 'server' },
        { path = 'src/client/**/*.luam', type = 'client' },
    },

    files = {
        'assets/**/*.png',
    },

    build = { output = 'build' },
}

info carries the author, the version, the description and the dependencies; environment carries oop, strict, the MTA version and the libraries; build carries the output directory and the bundle, minify, map and obfuscate switches. Order is position, and a blank line between two entries reaches meta.xml.

.luam.manifest and Configuration fields · .luam.manifest


Editor support

The Luam VS Code extension runs a language server built on the same frontend as the CLI, so the editor and the build never disagree: syntax highlighting, diagnostics on every keystroke, scoped completion, hover types, go to definition, find references and rename. It ships the Luam Dark and Luam Light themes — pick one under File → Preferences → Theme → Color Theme:

Supported and auto-installed by luam setup: VS Code, VS Code Insiders, Cursor, VSCodium and Windsurf. The language server itself is editor-agnostic and speaks --stdio to any LSP client.

Editors · Editores — compatibility matrix, manual .vsix install, commands and settings.


Known limitations

  • Narrowing follows a path, not an alias. if self.value ~= nil then refines the field inside the block; storing the test in a variable does not carry it.
  • A class is a type everywhere, a value from its declarationextends may name a parent written further down, a top-level new may not.
  • The MTA catalog can lag a release — a newer function stays any.
  • Three metamethods stay blocked__index, __newindex and __call. Generic classes are supported.
  • A method the receiver does not declare is not reportedcounter:missing() keeps returning any; annotate the receiver to have the call checked.
  • The editor re-checks by declaration — a declaration change re-analyzes every file that can see it, an edit inside a function body only its own file.
  • An export is named, never verified against the side that calls it.
  • Type annotations are erased, so validate anything a client can send.

Limitations · Limitações — each one labelled planned, design boundary, upstream or platform constraint, with the workaround. The decisions behind the boundaries are recorded in docs/adr.


Contributing

The repo is a pnpm workspace: compiler, cli, lsp, vscode, runtime, mta-types and template.

pnpm install
pnpm typecheck
pnpm test
pnpm build

Fork, open the pull request against develop, add a fixture and a snapshot for new language behaviour, and run pnpm typecheck && pnpm test before sending it. House style: TypeScript only, strict, no any, no comments inside code, 4-space indentation, single quotes, kebab-case file names, path aliases instead of ../ imports, no barrel files, everything in English.

CONTRIBUTING.md is the full contract — the Node and Lua 5.1 requirements, the command that reproduces each required check, and what happens to a pull request from a fork. Conduct is in CODE_OF_CONDUCT.md. A vulnerability is reported privately through SECURITY.md, never as an issue.

The manual lives in docs/pnpm docs:dev to preview, pnpm docs:verify before pushing. English is the source locale and pt-BR is translated from it; CI fails when a page is missing from one.

Per-package docs: cli, lsp, mta-types, vscode, template. Releases are in the changelog.


Acknowledgments

Multi Theft Auto — the execution platform. Luau — the annotation syntax that keeps Lua looking like Lua. lua-class and mta-threads — the runtimes behind class.lua and threads.lua.

License

MIT © Thigas