# moonstone

Moonstone is a Lua environment and package manager written in [[zig]]. It installs and selects Lua-family interpreters (PUC Lua or LuaJIT), resolves and builds packages, checks Lua ABI compatibility, and creates isolated per-project environments backed by a content-addressed store. The author is careful to correct a common misreading of the HN title: it is not a new Lua VM implemented in Zig. The closest mental model is LuaRocks plus isolated project environments, plus a lockfile, plus Zig-powered native builds, plus multi-interpreter workspaces. The CLI entrypoint is `moon`.

## How it works

The core problem it targets is the usual Lua environment breakage: you clone a project, run it, and hit a missing native dependency, a version mismatch (local Lua 5.4 vs. a codebase expecting LuaJIT 2.1), or a `LUA_PATH` polluted by artifacts from other projects. Lua stays deliberately small and pushes environment management onto the host. Moonstone moves that responsibility into a dedicated tool.

Everything is keyed off a global content-addressed store (CAS). Package files live read-only under `~/.local/share/moonstone/`, sharded by their BLAKE3 hash into `store/v0/b3/<h0h1>/<h2h3>/<full-hash>-<name>-<version>/`. Each stored artifact carries a `manifest.toml` that declares what it exposes — CLI binary names, Lua module entrypoints, C-modules — so the linker knows what to project into an environment. A SQLite database at `index/v0/index.sqlite` caches the registry index, package descriptors, and shim paths to speed up solver lookups.

A project is described by two files. `moonstone.toml` is the declarative manifest: metadata, the interpreter requirement under `[interpreter]`, scripts, and packages under `[[dependencies]]`. `moonstone.lock` freezes resolution — exact versions, source hashes, ABI targets, and the compiler/materializer recipes used to build native modules. Running `moon sync` reads the lockfile and materializes a project-local `.moonstone/env/` directory by symlinking the exact interpreter and package files out of the global CAS. Because the store is shared and read-only and the environment is just symlinks, multiple projects share one copy of each artifact while staying isolated from each other.

Dependencies come from several resolvers, selected by prefix: a bare name (`moon add inspect`) hits the default registry, `rocks:lua-cjson` pulls from LuaRocks, `path:../my-lib` uses a local directory, and `link:my-lib` uses a registered link. Native C modules are built with `zig cc` (LLVM-backed) for Moonstone's own hermetic recipes, but building existing LuaRocks packages still relies on the system GNU toolchain because those packages ship makefiles and GCC-oriented build recipes. The author frames that as a deliberate compatibility choice rather than the intended path — native hermetic recipes via `zig cc` are what's encouraged.

The `moon` binary and project environments are versioned separately. `moon install --latest` or `--version 0.1.1` manages the CLI release itself, `moon setup` repairs global shims, and `moon interpreter remove lua@5.4.7` drops an unreferenced interpreter artifact (with `--target <triple>` when several target builds match, and `--force` when the runtime is still selected globally or referenced by a project). The store follows XDG base directory conventions, overridable via a global `config.toml` or `MOONSTONE_CONFIG` / `MOONSTONE_DATA` / `MOONSTONE_CACHE` / `MOONSTONE_HOME` environment variables.

Two sibling projects extend it: Ballad forges an environment into a standalone binary export, and Meteorite compiles native services. Moonstone uses thematic names (orbits, Ballad) as an intentional design language; the author acknowledges the docs need a clearer translation layer for first-time readers.

## Usage

```bash
# initialize a project
moon init . --name my-app --kind script --interpreter lua@5.4

# add dependencies from different resolvers
moon add inspect
moon add rocks:lua-cjson      # LuaRocks
moon add path:../my-lib       # local path
moon add link:my-lib          # registered link

# materialize the project-local environment from the lockfile
moon sync

# run
moon run dev
moon exec lua src/main.lua
```

## Limitations

POSIX only — Linux and macOS, no Windows, despite the "cross-platform" label (which here means more than one arch/ABI, not every platform). It needs Zig 0.16.0 to build and expects a set of system tools present: `gcc`, `make`, `cmake`, `tar`, `curl`, `zstd`, `sqlite3`. So the "no runtime dependencies" claim covers the single compiled binary, not the build path for third-party LuaRocks packages, which still pulls in the GNU toolchain. The project is early and self-described as under heavy, messy, active development, with API contracts, CLI flags, and config shifting as the author builds Lua+Zig projects on top of it. Much of the documentation is AI-authored — the author says this is a survival tactic to keep docs in sync with a fast-moving codebase, and has openly asked for help rewriting it to read more naturally, which drew most of the HN criticism. It is one of several newer Lua environment tools; Lux is the closest adjacent project on the package-management side, and Nix/mise/asdf/hererocks already cover interpreter pinning for some users.

Tracked on [[toolbox/watchlist]] — young, single-author, single-platform, and still pre-1.0.

Related: [[zig]], [[comptime]].

Repo: <https://github.com/moonstone-sh/moonstone> — 29 stars, Apache-2.0.
