Map

moonstone

Toolbox toolboxzigluapackage-managerreproducible-buildswatchlistZigApache-2.0 โ†ณ show in map Markdown
title
moonstone
type
toolbox
summary
Lua package manager and environment tool in Zig, with lockfiles and a content-addressed store
tags
zig, lua, package-manager, reproducible-builds, watchlist
language
Zig
license
Apache-2.0
created
2026-07-18
updated
2026-07-18

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

# 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 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.