Skip to main content
Rebind code ships in two tiers, and one file decides which you’re in:
  • Script tier: a bare .lua/.luau file, no rebind.toml anywhere above it. The modeline comment at the top of the file owns all configuration.
  • Package tier: a directory (or any ancestor of the script) containing rebind.toml. The toml is package truth: it owns identity and can set every runtime option, overriding the entry’s modeline.
Promotion is additive: start with a single script, and when it outgrows one file, rebind new a package and move it in. Nothing about the code changes.

Layout

The entry defaults to main.luau, then main.lua. requires resolve inside the package root: <mod>.luau, <mod>.lua, <mod>/init.luau, <mod>/init.lua.

rebind.toml

The toml key is permissions (a list). In a modeline, permission= and permissions= behave identically: either takes one value or a comma-separated list, and every line adds to the set. An empty set means “declared, needs nothing”: permissions = [] in the toml, or permissions=none (or a bare permissions=) in a modeline. Omitting the key entirely is the opposite, and grants every permission. See Permissions. A package you intend to publish must declare the key. The registry refuses a version that leaves it undeclared, since “undeclared” reads as every permission, and rebind check fails it offline once [marketplace] is present. Declaring the empty set is always available for a script that needs nothing. Publishing adds a third section, [marketplace]. It is only read by rebind check and rebind publish, never by the runtime: see the marketplace listing.

Precedence: toml over modeline

Inside a package, the entry’s modeline still works (an entry can run standalone during development), but any key also set in rebind.toml wins, and the collision is surfaced as a warning on the script’s log channel. A bare script outside any package declares min_sdk in its modeline.

Scripts inside a package

Any script under a package root (for example scripts/wiggle.luau) runs in that package’s context, with deliberate limits: So a one-shot helper needs zero boilerplate:
exit() (alias for Script.Exit()) ends the script cleanly when it’s done.

The .rbp artifact

rebind package produces the registry artifact: a gzipped tarball of the package (plaintext source and assets, with VCS/build junk and any .rbp excluded).

The marketplace listing

The script marketplace has not been released yet. This section is documented for authors preparing packages ahead of launch.
[marketplace] is publish-time configuration. A package without it is a valid dev package; rebind publish refuses without it. rebind new scaffolds the block commented out.
Prices are USD with at most two decimals. Subscription prices are locked in at subscribe time: an approved price change applies to new subscribers only. Existing subscribers keep their price until they cancel. rebind check validates the whole block offline: category, the price table, and every media path. rebind preview renders the listing as a local HTML page before anything is uploaded. Everything here is also re-validated server side at publish. summary is limited to 140 characters. Details belong in README.md.

Listing media

Both icon and media are file paths inside the package. You never supply a URL; publish uploads the files and the marketplace stores its own keys. The first screenshot png in media becomes the cover used by the grid and product page. Publish removes it from the remaining gallery so it does not appear twice. At least one screenshot png is required, even when icon is set. The optional icon is a separate 128x128 listing asset and never becomes a gallery slide. Remaining media entries keep their declaration order.

README.md

A README.md at the package root is the listing’s long description. It ships inside the .rbp as well, so an installed copy reads offline.
  • Rendered as markdown in the product page overview card.
  • 64 KiB cap. Over it is an error, not a truncation.
  • Packages only. A bare script never picks one up.
  • Without one, the product page falls back to summary.

Packages are always plaintext

drm = true on a package is rejected at publish. DRM is a single-file feature: the runtime resolves require() off disk, so a DRM package would decrypt straight back onto the buyer’s disk. Publish a single-file script for DRM. Paid is independent of DRM. Entitlement gates on price, so a paid package with drm = false is still gated at download.