Lute is a standalone runtime for general-purpose programming in Luau, and a collection of optional extension libraries for Luau embedders to include to expand the capabilities of the Luau scripts in their software.
It is designed to make it readily feasible to use Luau to write any sort of general-purpose programs, including manipulating files, making network requests, opening sockets, and even making tooling that directly manipulates Luau scripts.
Lute also features a standard library of Luau code, called std
, that aims to expose a more featureful standard library for general-purpose programming that we hope can be an interface shared across Luau runtimes.
Lute is still very much a work-in-progress, and should be treated as pre-1.0 software without stability guarantees for its API. We would love to hear from you about your experiences working with other Luau or Lua runtimes, and about what sort of functionality is needed to best make Luau accessible and productive for general-purpose programming.
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.std
: The standard library, which extends those core C++ libraries with additional functionality in Luau.batteries
: A collection of useful, standalone Luau libraries that do not depend onlute
.
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, but we provide empty versions of both embeddings (in ./tools/templates
) to be used for any builds that do not embed the standard library. 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.
The most straightforward, and generally recommended, way to build a local version of lute
is to have already installed an existing version of lute
. Today, you can do that using a toolchain manager like foreman
, rokit
, and mise-en-place, or by manually installing a prebuilt binary from our Releases. With a copy of lute
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 build lute
from scratch without a version of lute
already present on your machine, this is still possible! We've provided 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
.
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. In order for the build to succeed, you'll have to provide some version of a handful of generated files, but we provide empty versions to use in ./tools/templates
. A manual build therefore would look something like:
- Copy all of the templates from
./tools/templates
into the right locations to support building a version with no embedded Luau functionality, e.g.mkdir -p ./lute/std/src/generated cp ./tools/templates/std_impl.cpp ./lute/std/src/generated/modules.cpp cp ./tools/templates/std_header.h ./lute/std/src/generated/modules.h mkdir -p ./lute/cli/generated cp ./tools/templates/cli_impl.cpp ./lute/cli/generated/commands.cpp cp ./tools/templates/cli_header.h ./lute/cli/generated/commands.h
- Configure with
cmake -G=Ninja -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1
- Build a
lute
executable withninja -C build lute/cli/lute
or our test suite withninja -C build tests/lute-tests
. - Optionally, use this version to run
luthier generate
to generate the files for embedded Luau functionality.