Open-source project
terralang/terra avatar
terralang/terra

Terra: a low-level language meta-programmed by Lua

Terra is a low-level system programming language that is embedded in and meta-programmed by the Lua programming language.

2,914 stars210 forksC++NOASSERTION

At a glance

What is it?
Terra is a statically typed, compiled systems language that lives inside Lua, so Lua code can generate, specialize and JIT Terra functions at runtime. It is a fit for people who want C-like codegen without writing a full compiler, and a poor fit for anyone who just wants a scripting language.
Who is it for?
Adopt Terra if you need to generate low-level machine code from a host program, want Lua-style metaprogramming with C-like types and manual memory management, or are embedding a compiled language into an existing C or C++ codebase through libterra_s.a. Do not adopt it if you want a general-purpose scripting runtime, a garbage-collected application language, or a toolchain that installs with a single package manager command.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 43 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Terra is for, and who should care

Terra occupies a narrow slot: it is a compiled, monomorphic, statically typed language with manual memory management, and its distinguishing feature is that Lua sits above it as the metaprogramming layer. The README states that Terra code shares Lua's syntax and control-flow constructs, and that calling between the two directions is easy.

The practical consequence is that the awkward parts of low-level programming, conditional compilation, namespaces and templating, are handled by ordinary Lua code instead of by special syntax in the language. The README lists function specialization, lisp-style macros and manually controlled JIT compilation as things this coupling enables. Because the compiler is available at runtime, a library or an embedded language can generate low-level code while the host program is already running.

That makes Terra interesting to a specific audience: people writing language runtimes, DSL engines, numeric kernels that need per-type specialization, or C programs that want to compile code on the fly. It is much less interesting if you want a scripting language, because Lua already covers that, and Terra's value comes from being the compiled counterpart rather than a replacement.

How Lua metaprogramming reaches the compiled layer

The design is two layers in one process. Lua is the host: it parses, runs and holds your metaprogram. Terra is the guest: a compiled language whose functions are produced when the metaprogram asks for them. The README describes Terra as embeddable in existing C code and backwards compatible with it, and the same design lets it be used as a standalone executable, a REPL, or a library.

The runtime compiler is what makes the layering real rather than cosmetic. A Lua metaprogram can decide at run time which Terra functions exist, what types they take, and when they are compiled. Conditional compilation and templating stop being parser features and become control flow in Lua. Manually controlled JIT compilation is the same idea taken further: the host decides when the cost of compiling is worth paying.

This is the trade-off to weigh. You get flexibility that a fixed compiler pipeline cannot offer, and you pay for it by having two languages and two mental models in one file. The README is explicit that a general understanding of Lua is helpful but not strictly required, which is honest but also a hint: the metaprogramming half is where the real work happens.

Installing Terra and running a first file

The README recommends binary releases over building from source, and gives a concrete reason: building requires a working install of LLVM and Clang, which it describes as difficult to get working. Releases are published for Linux (x86_64, AArch64, PPC64le), macOS (x86_64, AArch64), FreeBSD (x86_64) and Windows (x86_64).

On macOS 10.15 Catalina and later, the README says you must define SDKROOT before including C headers in Terra. Run this in the shell you will use:

bash
export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"

With the release unpacked, the standalone executable is invoked as ./terra. Started with no arguments it opens a REPL, which behaves like Lua's, with one difference the README calls out: expressions need a return prefix or the = shorthand to produce a value.

bash
$ ./terra
> return 3
3
> = 3
3

The README notes that a bare 3 is an error because the REPL expects a statement. To run a file instead, pass its path. The repository's tests/ directory holds example scripts, and the README's own example is tests/hello.t, which prints hello, world:

bash
$ ./terra tests/hello.t
hello, world

To confirm the build is sound, the README gives a test runner in the tests directory. Expect a lot of output and a summary line at the end:

bash
cd tests
../terra run

Building from source is the other path. Dependencies listed in the README include a C/C++ compiler supporting at least C++17, CMake 3.26.4 or greater, GNU Make on Linux, macOS and FreeBSD (needed for LuaJIT), LLVM and Clang, and LuaJIT, which is downloaded and installed automatically by default. CUDA is optional. The README notes that AMD and Intel GPUs are supported but their toolkits are not linked directly, so they are not build requirements. On recent Ubuntu the README gives this dependency line:

bash
sudo apt-get install build-essential cmake git llvm-21-dev libclang-21-dev clang-21 libpolly-21-dev libncurses-dev libzstd-dev zlib1g-dev

On macOS with Homebrew the README gives brew install cmake llvm@21, and on FreeBSD pkg install -y cmake gmake llvm21. The README states that LLVM 22 is the current recommended version for all platforms, with a support table covering older versions and per-platform notes.

Embedding Terra in a C or C++ program

Terra is not only a command-line tool. The README says it can be used as a library from C by linking against libterra_s.a, or terra.dll on Windows, and that the interface closely resembles that of the Lua interpreter. The initialization sequence is short: create a plain Lua state, open its libraries, then initialize Terra inside that state.

cpp
#include <stdio.h>
#include "terra.h"

int main(int argc, char ** argv) {
    lua_State * L = luaL_newstate();
    luaL_openlibs(L);
    terra_init(L);
    for(int i = 1; i < argc; i++)
        if(terra_dofile(L,argv[i]))
            return 1;
    return 0;
}

The README then shows how to build that program, linking against the Terra library and pointing the include path at the terra/include directory inside the Terra folder:

bash
c++ simple.cpp -o simple -I<path-to-terra-folder>/terra/include \
-L<path-to-terra-folder>/lib -lterra_s -ldl -pthread

The macOS variant in the README drops -ldl and -pthread. Notice what this means for integration: you are not starting a subprocess or talking over a socket. Terra runs in your address space, on the Lua state you already control, which is why the README describes it as backwards compatible with existing C code. The README also notes that Terra code can be compiled to .o files for linking into an executable, or compiled straight to an executable.

Where Terra is the wrong tool

The clearest limitation is the build story for anyone who wants to modify the compiler or work on an unsupported platform. The README does not hide this: it recommends binary releases precisely because LLVM and Clang are difficult to get working. If your environment cannot use a published binary and cannot match a supported LLVM version, you are in for a long setup. The README's support table lists specific LLVM versions per platform, and version 11 is marked deprecated, so the window of supported toolchains is real.

Manual memory management is the second boundary. The README states plainly that Terra has manual memory management, like C. That is a feature for kernel-adjacent and runtime work and a liability for application code where a garbage-collected language would be the better choice.

The third is the two-language model. Terra's power comes from Lua driving compilation, and that same structure means a reader of a Terra codebase needs to follow both a dynamically typed metaprogram and the statically typed code it emits. For a small, fixed workload with no need for specialization or runtime code generation, that overhead buys you nothing, and plain C or C++ is the simpler answer.

Finally, the repository root contains a STABILITY.md file. Its presence is a signal worth reading before you depend on internal interfaces: the README does not document stability guarantees for the C embedding API, so that file is where any such statement would live.

How Terra differs from LuaJIT and from C

The nearest comparison is LuaJIT, which Terra actually depends on for its build. LuaJIT is a tracing JIT for Lua: you write Lua, and the runtime decides what to compile, with no static types and no way to hand the compiler a type signature. Terra inverts that. You write the compiled code yourself in a statically typed language, and Lua decides when and with which types it gets compiled. The README's phrase for this is manually controlled JIT compilation, and the word manually is the whole difference: specialization becomes your decision rather than a heuristic's.

Against C, the difference is metaprogramming. C has a preprocessor and, in C++, templates; Terra replaces both with a real language that runs at compile time and at run time, and whose output is code the compiler then compiles. The README frames this as moving details like conditional compilation, namespaces and templating out of special constructs and into Lua. The cost is that your build now embeds a Lua interpreter and an LLVM-based compiler, which is a heavier dependency than a C compiler alone.

Release cadence, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-08-19. Releases are recent: release-1.2.2 on 2026-08-14, release-1.2.1 on 2026-08-01, and before those release-1.2.0 on 2024-06-25. That gap between 1.2.0 and 1.2.1 is worth noticing: the project can go a long time between releases and then ship two in a fortnight, so pinning a version and reading CHANGES.md before moving is the sensible pattern. The repository ships a CHANGES.md file at its root for exactly that.

The licence is recorded as NOASSERTION, which means the repository metadata does not resolve to a recognized SPDX identifier. A LICENSE.txt file sits in the top-level directory, so the terms are stated there rather than in the metadata. Read that file yourself before you ship anything built on Terra; this article cannot tell you what it permits.

Upgrade cost is dominated by LLVM. The README's support table ties Terra versions to specific LLVM releases, and the recommended version is LLVM 22. If your distribution moves to an LLVM version outside that table, you either hold back your toolchain or build Terra against a supported one. That is the main recurring cost of staying current. On the embedding side, the C API is a thin layer over Lua's, so upgrades mostly track LuaJIT and the Terra library rather than a large surface of your own code.

The repository also carries a terra-scm-1.rockspec, a default.nix and a nix/ directory, and a docker/ directory, so LuaRocks, Nix and container-based setups are present in the tree. The README itself does not walk through any of them, so treat those as starting points to inspect rather than documented install paths.

Editorial conclusion

Adopt Terra if you need to generate low-level machine code from a host program, want Lua-style metaprogramming with C-like types and manual memory management, or are embedding a compiled language into an existing C or C++ codebase through libterra_s.a. Do not adopt it if you want a general-purpose scripting runtime, a garbage-collected application language, or a toolchain that installs with a single package manager command. Before committing, verify that a binary release exists for your exact platform and LLVM version, run the bundled suite with cd tests && ../terra run to confirm your build is sound, and read STABILITY.md in the repository root to see what the project itself says about API guarantees.

Frequently asked questions

What does Terra mean as a programming language name?

The README does not explain the name. It presents Terra as a low-level counterpart to Lua, and the REPL banner prints exactly that phrase, which is the closest the documentation comes to describing the intent.

How do I install the Terra language?

The README recommends downloading a binary release for your platform rather than building from source, because building requires a working LLVM and Clang installation. Releases cover Linux, macOS, FreeBSD and Windows on the architectures listed in the README.

Does Terra run on Windows?

Yes. The README lists Windows (x86_64) among supported platforms, notes that binary releases are available for popular versions of those systems, and states that building on Windows requires Visual Studio 2022, with other versions possibly working but untested.

How do I run the Terra test suite to check my build?

Change into the tests directory and run ../terra run. The README says to expect a lot of output and that the run ends with a summary line reporting how many tests passed and failed.

Can I use Terra as a library from C?

Yes. The README states Terra can be used as a library from C by linking against libterra_s.a, or terra.dll on Windows, and shows a short program that creates a Lua state, calls terra_init, and runs each file argument with terra_dofile.

Official sources

  1. Issues
  2. README
  3. Releases
  4. terralang/terra on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/terralang-terra.svg)](https://hysenlabs.com/projects/terralang-terra)