Lute is a standalone runtime for general-purpose programming in Luau. It is designed to make it easy
to write any sort of general-purpose programs in Luau, including manipulating files, making network requests, and even
developing tooling that directly manipulates Luau scripts. In addition to the runtime, Lute also includes a standard
library of Luau code, called std, that aims to expose a more featureful standard library for general-purpose
programming beyond just the runtime capabilities. We're working within Roblox to make std a shared interface across
our Luau runtimes, so that large portions of code written for Lute can be used in Roblox, and vice versa.
In its current state, Lute provides a set of core runtime libraries that have already proven useful to us at Roblox in building both developer tooling for Luau and internal infrastructure projects. Our 1.0.0 release intended to provide a stable version that this infrastructure could rely on as we continue to develop Lute and its standard library further. Neither of these facts are intended to suggest that Lute is a finished product, and we expect to continue to develop it further in the future.
Our high-level goal with Lute is to build out the requisite tooling and support for Luau to work effectively as general-purpose programming language, not limited to its current use in Roblox. We hope to continue to develop Lute and its standard library to provide a more complete experience for general-purpose programming in Luau, and we welcome contributions from the community to help us achieve this goal. There are still many gaps and areas we'd like to improve, and we expect it will take plenty of time to get there. We hope that Lute can serve as a useful tool for the community in the meantime, and again we welcome feedback and contributions to help us improve it.
The Lute repository fundamentally contains three sets of libraries. These are as follows:
lute: The core runtime libraries in C++, which provides the basic functionality for general-purpose Luau programming. These libraries extend Luau with additional capabilities for file I/O, networking, and other general-purpose programming tasks.std: The standard library, which extends those core C++ libraries with additional functionality in Luau. These libraries are embeddeded in Lute and any Lute-compiled executable, and can be treated as a extension of the runtime.batteries: A collection of useful, standalone Luau libraries that do not depend onlute. These libraries are ones that we intend to eventually separate from Lute itself, and publish as independent packages once a good dependency management solution is in place.
Contributions to any of these libraries are welcome, and we encourage you to open issues or pull requests if you have any feedback or contributions to make.
Lute has a fairly conventional C++ build system built atop CMake. However, in the interest of dogfooding Lute itself,
and avoiding the trap of shipping elaborate, difficult-to-maintain CMake configurations that attempt to perform
dependency resolution and code generation, we've written a build tool called luthier (located at
./tools/luthier.luau). luthier is written to appropriately run or re-run any of the steps in the build process as
needed based on local changes, which affords a more pleasant developer experience for folks working on lute than
invoking each step manually. Some luthier subcommands like configure and build just wrap the standard CMake
configuration and ninja invocations. Other commands include fetch which implements the logic to parse dependency
information from the TOML files (named extern/\*.tune) and resolve them efficiently using git, and generate which
performs the code generation steps necessary to embed both Lute's CLI frontend commands and Lute's standard library into
the executable. The generate step in particular is necessary to producing a full lute executable. Since you'll need
lute to execute luthier and you'll need luthier to run the code generation step in particular, there are a few
different paths to building Lute. If you do not have lute available to run this step, the CMake option
-DLUTE_STDLESS=ON can be passed to skip embedding entirely.
As a result, building a full version of Lute requires a local version of lute to run the code generation. We've
provide a few paths below for resolving this bootstrapping problem, depending on your preferences and constraints. You
can also download and manually install a prebuilt binary from our Releases
page, and place it wherever you'd like.
The simplest way to build lute without a version of lute already present is by bootstrapping it yourself. Toward
that end, we provide a small, easily auditable shell script ./tools/bootstrap.sh that will perform the entire build
process in sequence for a totally fresh build. This entails first building a debug version of lute called lute0
without any of the CLI commands implemented in Luau, and without the standard library embedded into the executable. We
can then use lute0 to run luthier, perform the requisite code generation step, and then build a fresh release
version of lute. The script supports a single command-line option --install which can be used to install this
release executable to a desired location on your machine. By default, this is $HOME/.lute/bin/lute, but the script
will provide a prompt during its execution about where lute should be placed. In order to then use this lute
executable, please ensure that it is accessible on your $PATH.
For subsequent builds, you can use your current copy of lute to invoke luthier directly to perform clean or
incremental builds of the CLI executable or the test suite:
# with `lute` on your path...
lute tools/luthier.luau build --clean {lute | Lute.CLI | Lute.Test}
# or referring directly to a specific location...
/path/to/lute tools/luthier.luau build --clean {lute | Lute.CLI | Lute.Test}
# you can also use `run`, instead of `build`, to also invoke the appropriate executable afterwards!A popular approach in the Roblox community generally is to leverage toolchain managers to handle the installation and
setup of developer tooling for projects, and this approach works just as well for building Lute. Out of the box, we
provide configurations for two popular toolchain managers, foreman and
rokit. You can invoke them with foreman install or rokit install respectively
to have them download an appropriate version of lute to use for the build process. With this copy present on your
system, you can then run the following to perform a clean build:
# with `lute` on your path...
lute tools/luthier.luau build --clean {lute | Lute.CLI | Lute.Test}
# or referring directly to a specific location...
/path/to/lute tools/luthier.luau build --clean {lute | Lute.CLI | Lute.Test}
# you can also use `run`, instead of `build`, to also invoke the appropriate executable afterwards!If you wish to work very manually with the build system, you can, of course, still invoke cmake and ninja directly
after pulling external dependencies into extern by hand. This will have you performing the steps of the bootstrap
script yourself. A manual build therefore would look something like:
- Fetch all the external dependencies from
externby hand, consulting the.tunefiles for the appropriate versions to pull in. - Configure with
cmake -G=Ninja -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DLUTE_STDLESS=ONto build a version with no embedded Luau functionality. - Build a
luteexecutable withninja -C build lute/cli/luteor our test suite withninja -C build tests/lute-tests. - Optionally, use this version to run
luthier generateto generate the embedded Luau source files, then reconfigure without-DLUTE_STDLESS=ONand rebuild to get a fully-featuredlute.
Lute supports the use of ccache to speed up builds. Both the bootstrap and luthier build scripts support a
--with-ccache option, which proxies all compilation through ccache. To benefit from caching during local development,
download ccache using your systems package manager (apt/brew/choco/etc), and perform a clean configure with
--with-ccache passed. Subsequent builds will then use the cached build artifacts in the .ccache directory.
Additionally, you'll need to set the following variables:
CCACHE_DIR=path/to/store/ccachedir
CCACHE_MAXSIZE=maximum size of the cache
CCACHE_COMPRESS=true