Lute Runtime
repository·primary·Indexed 43 days ago
https://github.com/luau-lang/luteA standalone runtime for general-purpose programming in Luau, designed for file I/O, networking, and tooling development. Lute includes a core C++ runtime, a shared Luau standard library (std), and a collection of standalone libraries called batteries. It also features a programmable linter, lute lint, for static analysis of Luau code.
What's inside Lute
- Lute is a standalone runtime for the Luau programming language, designed for general-purpose programming outside of sandboxed environments like game engines. It functions similarly to Node.js or Deno, providing the necessary capabilities for Luau to interact with the host system.
Overview of Lute and its libraries
primaryLute is a standalone runtime for general-purpose programming in Luau. It enables tasks like file manipulation, networking, and developing Luau tooling.
Lute consists of three primary library sets:
lute: Core runtime libraries written in C++ that extend Luau with file I/O, networking, and other general-purpose capabilities.std: A Luau standard library that extends the core C++ libraries. It is embedded in Lute and any Lute-compiled executable, providing a shared interface that can be used across different Luau runtimes (including Roblox).batteries: A collection of standalone Luau libraries that do not depend onlute. These are intended to eventually be published as independent packages.
Lute core features and capabilities
primaryLute provides built-in APIs and tooling for general-purpose development, including:
- System APIs: File system access, HTTP networking, cryptography, and process management.
- Tooling: A suite of CLI tools including a test runner, a linter, and the Luau type checker.
- Roblox Compatibility: Ability to run Luau modules that do not depend on the Roblox game engine.
How Lute APIs are organized
primaryLute provides its capabilities through two distinct layers of libraries accessible via Luau's
requirefunction using specific aliases:- Low-level libraries: Exposed under the
@lutealias. These provide the core system capabilities. - Standard Library (
@std): A higher-level library built on top of the@lutelibraries. This is the recommended way to perform common tasks.
For Roblox developers, Lute aims for compatibility by using the same
@stdAPI set, allowing code to run in both Lute and Roblox with minimal changes.- Low-level libraries: Exposed under the
Understand the `constant_table_comparison` lint rule
primaryThe
constant_table_comparisonlint rule identifies code that attempts to compare a variable to a table literal (e.g.,if x == {} then).In Luau, tables are compared by reference, not by value. Comparing a variable to a new table literal will always evaluate to
falsebecause the literal creates a new, unique table in memory that the variable cannot possibly reference.To check if a table is empty, use the
next()function instead of comparing to{}.-- Violation: if x == {} then ... end -- Correct approach: if next(x) == nil then ... endUse the Lute Standard Library (@std)
primaryThe Lute Standard Library provides a set of high-level, common utilities designed to make Luau useful for general-purpose programming. It is accessible via the reserved alias
@stdand is categorized into four main areas:- Language Interaction: Parsing Luau, interacting with the compiler, virtual machine, and type checker.
- I/O: Interacting with the command line, file system, external processes, and the network.
- Platform Abstractions: File system paths, time measurements, and cooperative multitasking.
- General Programming Utilities: Table manipulation, string utilities, JSON handling, and testing frameworks.
To use a module from the standard library, use the
requirefunction with the@std/prefix.local _ = require("@std/json")Understand the difference between @lute and @std libraries
primaryLute provides two distinct sets of libraries:
@std(Standard Library): High-level modules designed for portability. You should prefer these whenever possible, as they are intended to be supported across various Luau runtimes, including Roblox, Lute, and other game engines.@lute(Runtime Builtins): Low-level, native APIs that provide foundational capabilities like file system access, network access, and access to Luau internals. These are built directly into the Lute runtime.
Warning: Using
@lutelibraries will make your code less portable. Code relying on@lutewill not function in Roblox or other Luau environments that do not implement these specific native builtins.Understand the reassigned_parameter lint rule
primaryThe
reassigned_parameterlint rule detects instances where a function parameter is reassigned within the function body. Reassigning parameters is discouraged because it can cause hard-to-spot bugs in downstream code that expects the parameter to maintain its original value.local function _(x) x = 2 x += 3 endHandle command line arguments in Luau
primaryIn Lute/Luau, command line arguments can be captured at the top of a script using the variadic unpack syntax
.... This unpacks the arguments into an array.Important: The first element in the resulting array (
args[1]) is always the name of the script itself. Subsequent arguments follow fromargs[2]onwards.local args = { ... } -- args[1] is the script name -- args[2] is the first actual argumentUnderstand the `no_any` lint rule
primaryThe
no_anylint rule identifies explicit uses of theanytype annotation in Luau code. Usinganyis discouraged because it disables type checking for the associated values, potentially masking bugs and allowing unsafe operations.To maintain type safety, follow these patterns:
- Use
unknowninstead ofany: Theunknowntype is type-safe and requires you to perform type narrowing (e.g., usingtypeofchecks) before performing operations on the value. - Use unsound casts for escape hatches: If you must assume a specific type, use the type assertion syntax (
value :: T) to narrow the type and explicitly document the assumed runtime contract.
-- Violation local x: any = getValue() -- Recommended local x: unknown = getValue() assert(typeof(x) == "table") local field = (x :: { field: unknown }).field- Use
Configure and use breakpoints in Lute
primaryBreakpoints are identified by a unique ID and a specific line in a source file. They can be set while the
Targetis paused or before the program launches.Breakpoint Types
- Standard Breakpoints: Trigger the
debugbreakcallback, stopping execution and scheduling user event coroutines. - Conditional Breakpoints: Use
Target::evaluateExpressionto check if an expression is truthy before stopping. - Hit Conditional Breakpoints: Similar to conditional breakpoints, but allow conditions based on the number of times the line has been executed (a "hit").
- Logpoints: Do not stop execution. Instead, they log a message via
onLogpoint. Messages support interpolation of expressions using{}syntax.
Important Constraints
- Installation: Breakpoint changes (add/delete) are not reflected in the debuggee until the
Targetis next paused. This is because modifying breakpoints requires changing Luau bytecode, which is unsafe while running. - Scope: Expressions used in conditional breakpoints only evaluate within the variables available at the current stack frame (not parent frames).
- Availability: Breakpoints are installed via
lua_breakpointonce a source becomes available (either the starting file or a file loaded viarequire).
- Standard Breakpoints: Trigger the
Use the `lute/debugger` library for programmatic debugging
primaryThe
lute/debuggerlibrary allows you to write Luau scripts that can debug other Luau scripts. This is useful for building custom debugging tools or automated testing environments.Core Workflow:
- Initialize: Construct a
Targetobject usingnewTarget. - Configure: Before launching the debuggee, use methods like
setBreakpointandremoveBreakpoint. You can also configure callbacks such asonBreakpointHitto react to specific events. - Control Execution: Once the code is paused, you can inspect state or move through the code.
- Resume: Always call
continueProcessto restart the execution of the debuggee after pausing.
Common Operations when Paused:
- Thread Inspection: Use
getThreads,getMainThread, orgetStoppedThreadto inspect running coroutines. - Stack/Variable Inspection: Use
getStackTraceorgetVariablesto drill into the current state. - Expression Evaluation: Use
evaluateExpressionto evaluate Luau expressions dynamically. - Stepping: Use
stepOver,stepInto, orstepOutto navigate the code.
- Initialize: Construct a