Skip to content

Getting Started

This guide walks you through installing Luax and running your first Lua program from Dart. It assumes you have a working Dart SDK (>= 3.0.0) and a basic familiarity with Lua syntax.

Installation

Add Luax to your pubspec.yaml:

yaml
dependencies:
  luax:
    git: https://github.com/NaivG/Luax.git

Then fetch the package:

bash
dart pub get

Luax has no native dependencies — just one runtime dependency on dart_sprintf (pulled in via git). It runs on every Dart platform: native (VM), the Dart web compiler (dart compile js), Flutter, and Dart-on-servers.

Your first Lua program

dart
import 'package:luax/lua.dart';

void main() {
  final state = LuaState.newState();
  state.openLibs();
  state.doString(r'''
    for i = 1, 5 do
      print("Hello from Luax!", i)
    end
  ''');
}

Output:

Hello from Luax!	1
Hello from Luax!	2
Hello from Luax!	3
Hello from Luax!	4
Hello from Luax!	5

Three things to notice:

  1. LuaState.newState() creates a fresh VM. The returned object is the main thread; coroutines are derived from it.
  2. state.openLibs() loads the standard libraries (print, math, string, table, os, package, coroutine, utf8, event, ...). Skip this call to start with a sandboxed environment.
  3. state.doString('''...''') parses, compiles, and runs the snippet in a single step. For larger programs, see load and loadFile.

The API mirrors the Lua C API — if you've written lua_State code in C, the Dart API will feel familiar.

Loading a .lua file

dart
final ls = LuaState.newState();
ls.openLibs();
ls.doFile('config.lua');

doFile resolves paths against the current working directory. On the web, doFile is not available — use loadString with the file contents fetched ahead of time.

Calling Dart from Lua

The whole point of an embeddable VM is letting Lua scripts call back into the host application. Register a Dart function and Lua can invoke it by name:

dart
import 'dart:math';
import 'package:luax/lua.dart';

int dartRandom(LuaState ls) {
  final max = ls.checkInteger(1);
  ls.pop(1);
  ls.pushInteger(Random().nextInt(max));
  return 1;  // number of values pushed onto the stack
}

void main() {
  final state = LuaState.newState();
  state.openLibs();

  state.pushDartFunction(dartRandom);
  state.setGlobal('dartRandom');

  state.doString('print("Random:", dartRandom(100))');
}

The wrapper signature is int Function(LuaState ls). The return value is the number of values you pushed onto the stack.

Calling Lua from Dart

lua
-- math_utils.lua
function add(a, b)
    return a + b
end
dart
ls.doFile('math_utils.lua');
ls.getGlobal('add');
ls.pushInteger(3);
ls.pushInteger(4);
ls.pCall(2, 1, 0);  // 2 args, 1 result, no message handler
print('3 + 4 = ${ls.toInteger(-1)}');  // 7

See the Dart↔Lua Interop guide for the full push/check/call conventions, error handling with pCall, and reading Lua tables and functions from Dart.

Next steps