{"id":26062681,"url":"https://github.com/latte-soft/wax","last_synced_at":"2025-04-11T11:11:58.223Z","repository":{"id":196428169,"uuid":"695644804","full_name":"latte-soft/wax","owner":"latte-soft","description":"A Lua 5.1x+/Luau Project Bundler Runtime, Using Roblox Models and Module-Require Semantics","archived":false,"fork":false,"pushed_at":"2024-10-23T00:22:32.000Z","size":2092,"stargazers_count":34,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T07:36:11.877Z","etag":null,"topics":["bundler","lua","luau","roblox"],"latest_commit_sha":null,"homepage":"https://latte.to","language":"Luau","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/latte-soft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-23T19:38:35.000Z","updated_at":"2025-02-20T03:16:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"e42adda4-6573-4b05-98de-7d557914fc9a","html_url":"https://github.com/latte-soft/wax","commit_stats":null,"previous_names":["latte-soft/wax"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/latte-soft%2Fwax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/latte-soft%2Fwax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/latte-soft%2Fwax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/latte-soft%2Fwax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/latte-soft","download_url":"https://codeload.github.com/latte-soft/wax/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248381791,"owners_count":21094528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundler","lua","luau","roblox"],"created_at":"2025-03-08T16:00:46.624Z","updated_at":"2025-04-11T11:11:58.181Z","avatar_url":"https://github.com/latte-soft.png","language":"Luau","readme":"\u003c!-- Links --\u003e\n[stars]: https://github.com/latte-soft/wax/stargazers\n\u003c!--[fork]: https://github.com/latte-soft/wax/fork--\u003e\n[license]: https://github.com/latte-soft/wax/blob/master/LICENSE\n[latest-release]: https://github.com/latte-soft/wax/releases/latest\n[commits]: https://github.com/latte-soft/wax/commits\n[discord]: https://latte.to/discord\n\n\u003c!-- Badges --\u003e\n[badges/stars]: https://img.shields.io/github/stars/latte-soft/wax?label=Stars\u0026logo=GitHub\n\u003c!--[badges/fork]: https://img.shields.io/github/forks/latte-soft/wax?label=Forks\u0026logo=GitHub--\u003e\n[badges/license]: https://img.shields.io/github/license/latte-soft/wax?label=License\n[badges/latest-release]: https://img.shields.io/github/v/release/latte-soft/wax?label=Latest%20Release\n[badges/last-modified]: https://img.shields.io/github/last-commit/latte-soft/wax?label=Last%20Modifed\n[badges/discord]: https://img.shields.io/discord/892211155303538748?label=Latte%20Softworks%20Discord\u0026color=5865F2\n\n# Wax\n\n[![Stars][badges/stars]][stars] [![License][badges/license]][license] [![Latest Release][badges/latest-release]][latest-release] [![Last Modified][badges/last-modified]][commits] [![Discord Server][badges/discord]][discord]\n\nA Fast Runtime-Based Lua 5.1x+/Luau Project Bundler, Using Roblox Models and Module-Require Semantics\n\n*Powered by [Lune](https://github.com/lune-org/lune), a standalone Luau script runtime*\n\n## 🎉 About\n\nWax is an all-in-one bundler for projects in Lua 5.1x+ and [Luau](https://luau-lang.org), supporting and enforcing Roblox-like module require semantics (like using `require()` with a relative `script` global), and also normal `string` file paths like in generic Lua.\n\nThis is more of a successor to [Maui](https://github.com/latte-soft/maui), a similar, but much more limited and inherently flawed project for bundling Roblox projects, but **only** for running in Roblox. Wax, on the other hand, *bundles* completely outside of the Roblox engine, and generates code that can *run* outside it aswell. **Wax can 'bridge the gap' between traditional Lua projects and modern Roblox/Luau workflows, or anything in-between.**\n\n### Features\n\n*See [Usage](#🚀-usage) for more details on utilizing various features*\n\n* Bundle directly from a [Rojo project](https://rojo.space/docs/v7/project-format) file (`*.project.json`), or just a generic Roblox model file. (`*.rbxm` or `*.rbxmx`) *For working directly with Rojo project files, you **must** have the `rojo` command in your $PATH*\n* Created with **debugging in mind** from the start. *With output minification disabled*, even proper line info (matching to the original source files) can be shown in errors; for example, `[WaxRuntime].Script.OtherScript:1: intentional error`\n* Built-in support for minifying bundled output directly with [Darklua](https://darklua.com) and either our default configuration (no extra steps), or your project's own `.darklua.json/json5` file for making personal tweaks.\n* Localized/flattened modified globals in closures, meaning `getfenv`/`setfenv` aren't used to modify the script's environment - This also means that in Luau, `safeenv` runtime optimizations are maintained, and closures run 'natively' with no user modification!\n* Automated CI/deployment pipeline usage in mind, with the `ci-mode` flag; no user confirmation prompts, and exits with a `1` status code upon any errors\n* A 'virtual' Roblox-like DOM for scripts that can run completely outside of Roblox, while also allowing module imports (`require()`) with a simulated relative `script` global, or traditional filesystem path strings like in [Lune](https://github.com/lune-org/lune) or the Lua/Luau CLI REPLs.\n\nAdditionally, you can check out some example \"projects\" in our [tests](tests) directory if you don't really know what all of this is about, or how to get started..\n\n## ⚙️ Installation\n\nFor your project, you **must** have at least [Lune](https://github.com/lune-org/lune) installed, most easily done and managed with [Aftman](https://github.com/LPGhatguy/aftman):\n\n1. Goto Aftman's GitHub repository (linked above), and follow its installation instructions for your platform\n2. Open the root directory of your project in your system's terminal, and run the following:\n\n```\naftman init\naftman add lune-org/lune\n```\n\n3. If you've setup Aftman properly, you can now try running `lune --help`, and if all is well you should see something similar to the following in your terminal:\n\n```\n$ lune --help\nA standalone Luau runtime\n\nUsage: lune [COMMAND]\n...\n```\n\n### Add Wax to Your Lune Scripts\n\nIf you already have a \"`lune`\", \"`.lune`\", or similar directory in your project for these scripts, feel free to use it - for the sake of this example guide, I'm going to use \"`lune`\" as the example directory for Lune script(s).\n\n1. If you haven't already, create a directory named \"`lune`\" in the root of your project\n2. Inside of this newly created directory, create a file named \"wax.luau\", and paste in the following (or directly download `wax.luau` from the latest release on the [releases page](https://github.com/latte-soft/wax/releases))\n\n*(DO NOTE: if you're using the 'remote' loader below, you won't be able to use Wax offline, and request times per running the script could be impractical for both speed and efficiency depending on your internet connection; consider manually installing `wax.luau` from the latest release on the releases page, linked above)*\n\n```lua\n--[[\n    Wax - A Fast Runtime-Based Lua 5.1x+/Luau Project Bundler, Using Roblox Models and Module-Require Semantics\n    MIT License | Copyright (c) 2023-2024 Latte Softworks \u003chttps://latte.to\u003e\n]]\n\n-- You set the following string to \"latest\" (case insensitive), or any version tag\n-- on Wax's releases page (e.g. \"0.4.1\")\nlocal WaxVersion = \"latest\"\n\n-------------------------------------------------------------------------------\n\nlocal net = require(\"@lune/net\")\nlocal luau = require(\"@lune/luau\")\n\nlocal FileLink = if string.lower(WaxVersion) == \"latest\" then\n    \"https://github.com/latte-soft/wax/releases/latest/download/wax.luau\"\nelse `https://github.com/latte-soft/wax/releases/download/{WaxVersion}/wax.luau`\n\nluau.load(net.request(FileLink).body, {\n    debugName = \"Wax\",\n})()\n\n```\n\n3. Now, when running `lune run wax`, you should see something similar to what's in the next section ([Usage](#🚀-usage)) in your terminal. Voilà!\n\n## 🚀 Usage\n\nFrom your terminal in the root directory of your project, run `lune run wax`, or just `lune run \u003cpath/to/wax.luau\u003e`\n\n```\nWax 0.4.1\nA Fast Runtime-Based Lua 5.1x+/Luau Project Bundler, Using Roblox Models and Module-Require Semantics\n\nUSAGE:\n    lune run wax [subcommand] [options]\n\n* When no subcommand is provided, this usage message is displayed\n* Provide all options in the following format (no \"--\" flag prefix): option=value\n\nSUBCOMMANDS:\n    help      Displays this usage message\n\n    version   Displays Wax's version\n\n    bundle    Builds a bundled script file from a given Roblox model (*.rbxm/*.rbxmx)\n              or Rojo project file (*.project.json, requires the `rojo` command\n              available in your PATH environment variable), to an output path\n\n      OPTIONS for `bundle`:\n      * input[=\"default.project.json\"]\n            The input Roblox model (*.rbxm/*.rbxmx) or Rojo project (*.project.json) file\n            path for Wax to bundle from\n\n      * output[=\"{input-filename}.lua\"]\n            The final output file path (must end in .lua or .luau) for the bundled script\n\n      * minify[=false]\n            If codegen output should be \"minified\", which also omits any runtime line\n            debugging info (offsets). For 'full' codegen minification (outside of just\n            LuaEncode's table output), you must have the `darklua` command available in\n            your PATH environment variable.\n            Additionally, with Darklua, if a \".darklua.json/json5\" file isn't found in the\n            CWD (your dir \"position\" in your terminal), it'll use the default configuration\n            we provide (see `lune/lib/data/DefaultDarkluaConfig.luau`)\n    \n      * env-name[=\"WaxRuntime\"]\n            The name of the \"environment\" of the bundled script. This is the \"name\" of\n            the root object (like the `game` DataModel in Roblox) and displays in virtual\n            runtime errors (e.g. \"[WaxRuntime].Script:1: Some error message\")\n    \n      * darklua-config-path[=(\".darklua.json\", \".darklua.json5\")]\n            When `minify` is set as true, this path can be used to directly pass your own\n            Darklua config file's path, instead of only checking for the default paths\n            it looks for\n\n      * temp-dir-base[=\"{output-dir}\"]\n            If you're providing a Rojo project file as input or minifying with Darklua,\n            a temporary directory is created inside of this directory path, and is removed\n            by the time Wax has completed processing\n\n      * extra-offset-lines[=0]\n            (Only applicable to when `minify` is set to false) Internally acknowledges\n            any extra lines offset from the top of the script (like if you're adding a\n            header of sorts to the codegen) for line debugging info. Ths MUST be exactly\n            accurate to its name (*extra* lines, so you may want to do something like\n            `#ExtraHeader - 1` if you're using this option)\n\n      * ci-mode[=false]\n            (*Primarily* for automated CI pipelines or deployment systems) Never gives\n            any user input prompts, and will *always* exit with a `1` status code upon an\n            'error' or warning during the build process\n\n      * verbose[=true]\n            \"Verbose\" (detailed) output logging from CLI/bundler\n```\n\n## Runtime Spec Details\n\n* If there's only 1 instance directly under the model root and it's a `ModuleScript`, that module will automatically run at init and pass its return through the **real** script, just as expected with normal module behavior. Additionally, like a model on Roblox's [Developer Marketplace](https://create.roblox.com/marketplace/models), a `ModuleScript` under the model root named (exactly) \"MainModule\" will also have the same functionality, even if there is more than 1 instance directly under the model root\n\n* The real `getfenv`/`setfenv` functions are not overriden by global flattening whatsoever, so by using for example `getfenv(0)` it will return the actual root function environment of the complete, bundled script. *Just know that its behavior isn't modified whatsoever for virtual closures!*\n\n* Instance `ClassName`s that will bundle:\n  * `Folder`\n  * `Script`\n  * `LocalScript`\n  * `ModuleScript`\n  * `StringValue`\n\n* Implemented Instance 'properties' :\n  * `Instance.ClassName: string`\n  * `Instance.Name: string`\n  * `Instance.Parent: Instance?`\n  * `StringValue.Value: string`\n\n* Implemented Instance 'methods':\n  * `Instance:GetFullName(): string`\n  * `Instance:GetChildren(): {Instance}`\n  * `Instance:GetDescendants(): {Instance}`\n  * `Instance:FindFirstChild(name: string, recursive: boolean?): Instance?`\n  * `Instance:FindFirstAncestor(name: string): Instance?`\n  * `Instance:WaitForChild(name: string, timeOut: number?)` *The actual behavior of the virtual `WaitForChild` impl is identical to `FindFirstChild`, but it needs to be implemented due to many codebases using it for relative module `require()` paths*\n\n## Runtime API Reference\n\n**All virtual closures have a special `wax` global for accessing AOT Wax build info, an isolated `shared` table, and 'real' globals Wax replaces.**\n\n* `wax.version`\n\nThe version of Wax the current script was bundled with.\n\n```lua\nwax.version: string\n```\n\n* `wax.envname`\n\nThe string provided in the `env-name` option at build-time. (\"`WaxRuntime`\" by default)\n\n```lua\nwax.envname: string\n```\n\n* `wax.shared`\n\nA table shared across all virtual closures in a bundled project, similar to the real `_G`/`shared` globals.\n\n```lua\nwax.shared: {[any]: any}\n```\n\n* `wax.script`\n\nThe real `script` global of the current script, (for with Roblox etc) as opposed to the virtual script ref override by Wax. If there isn't a real `script` global above Wax's environment anyway, this will be `nil`.\n\n```lua\nwax.script: LuaSourceContainer?\n```\n\n* `wax.require()`\n\nThe real `require()` function given by your Lua runtime as opposed to Wax's virtual override. (Lua, Luau (vanilla repl), Roblox Engine, Lune etc)\n\n```lua\nwax.require(...: any): ...any\n```\n\n## Build from Source\n\n1. Clone the repository with `git`:\n\n```\ngit clone https://github.com/latte-soft/wax.git\ncd wax\n```\n\n2. With [Aftman](https://github.com/LPGhatguy/aftman) installed and configured:\n\n*Accept any new tools for installation from the `y/n` prompts, or append `--no-trust-check` to the following command*\n\n```\naftman install\n```\n\n3. Build with `lune` ([lune/make.luau](lune/make.luau)):\n\n```\nlune run make\n```\n\nIf successful, the resulting bundled scripts will be output in the `build/` directory:\n\n```\nbuild\n├── wax.dbg.luau\n└── wax.luau\n```\n\n## 🏛️ License\n\n*See file: [LICENSE](LICENSE)*\n\n```\nMIT License\n\nCopyright (c) 2023-2024 Latte Softworks \u003chttps://latte.to\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flatte-soft%2Fwax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flatte-soft%2Fwax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flatte-soft%2Fwax/lists"}