Skip to content

luckgrid/luna

Repository files navigation

Luna

Luna is a polyglot monorepo starter built around moonrepo for the task graph, proto for pinned runtimes, and the luna CLI (Rust, Starbase + Clap) for orchestration across all toolchain layers. Each stack brings its own runtime — Bun for JS/TS, Go for Hugo, Python for FastAPI — managed and pinned by Proto. It layers three application stacks: a SolidStart interactive app with SSR and streaming, a Hugo static site for Markdown and templates, and a FastAPI service with Pydantic and Pydantic AI. Shared libraries live under packages/*. Ports, environment files, and moon tasks are covered in the sections and READMEs below.

Tech Stacks

Core monorepo and toolchain

Interactive application stack (SolidStart)

SolidStart on Vite and Nitro is the stack for SPA-style apps that need SSR, client-side fine-grained signals (SolidJS), routing (Solid Router), and streaming responses. Nitro gives you a server runtime alongside the browser bundle, so the same project can grow full-stack APIs and server logic without leaving the framework. Bun is pinned in .prototools as the JS/TS runtime and package manager for this stack.

Static site generator stack (Hugo)

The apps/web project is a static-site workflow: Markdown and front matter in src/content/, Go HTML templates in src/layouts/, and the published site in dist/. @luna/ds styles are compiled by the Tailwind CSS v4 CLI into src/assets/css/bundle.css before each build (same design system as apps/app). Go is pinned in .prototools; the Hugo CLI version is pinned in apps/web/go.mod as a go tool (same idea as Python deps living under apps/api). See apps/web/README.md.

  • 📰 Hugo (documentation) — static site generator; HTML, RSS, and sitemap from content + templates
  • ✍️ Goldmark — CommonMark-compatible Markdown (Hugo’s default renderer)
  • 🧩 Go HTML templates — partials, blocks, and baseof layouts under src/layouts/
  • 🎨 Tailwind CSS v4 (documentation) — utility CSS for @luna/ds (package); @tailwindcss/cli emits src/assets/css/bundle.css (same tokens as apps/app)
  • 🖍️ Chroma — syntax highlighting for fenced code blocks ([markup.highlight] in hugo.toml)

API service stack (FastAPI and Pydantic)

The apps/api stack centers on FastAPI, Pydantic, and Pydantic AI for a pure backend HTTP API: validation, settings, and agent-style features stay on the server. The same patterns extend to larger deployments (multiple services, workers, or runtimes) when you outgrow a single process; this repo keeps one API project as the starting point.

Workspace quality (TypeScript and OXC)

Quick Start

Run commands from the repository root unless an app README says otherwise.

Prerequisites

Install Proto and Moon on your PATH before setup (Moon is only needed until luna is installed; Proto pins moon, rust, bun, python, and go via .prototools).

After moon run cli:install, add ~/.cargo/bin to your PATH so the luna command is found (or use the full path in moon run luna:install below).

First-time install

One command from the repo root (fresh clone or after luna clean):

moon run luna:install

That runs proto installcli:buildcli:installluna install (toolchains, CLI, bun workspaces, web, api). Then:

luna dev

Equivalent steps (if you prefer to run them separately):

proto install
moon run cli:build
moon run cli:install
luna install

Without luna on PATH yet — stop after cli:install, then:

./target/debug/luna install    # or ~/.cargo/bin/luna install

Subsequent refreshes: luna install. New pins in .prototools are picked up by proto install (or luna update, which refreshes pins then re-runs install). .moon/toolchains.yml disables javascript.installDependencies and sets bun.installArgs: ["--ignore-scripts"].

Full reset: luna clean, then moon run luna:install again. Each project’s inherited :clean task clears its own outputs; root luna:clean clears repo-root artifacts (node_modules, .venv, target, …); .moon/cache is removed last. Lockfiles are kept (bun.lock, uv.lock, Cargo.lock, go.work / go.sum).

For a full compile of every application project first, run luna build.

Local dev ports (copy .env.example.env.local to customize): FastAPI / Uvicorn 8000 (common tutorial default — avoids stealing 3000 from the SPA), SolidStart 3000, Hugo static site 3001. Details and CORS URLs are in each app README.

Workspaces

  • apps/api/ — FastAPI + Pydantic AI · README
  • apps/app/ — SolidStart (SSR, Vite, Nitro) · README
  • apps/web/ — Hugo + Tailwind v4 + @luna/ds · README
  • packages/cli/luna CLI (Rust + Starbase; orchestrates Moon/Proto/Bun commands; outdated/update across all toolchains)
  • packages/ds/ — design system / Tailwind · README
    • Entrypoints: packages/ds/src/tailwind.css (main import), packages/ds/src/components.css, packages/ds/src/layouts.css, packages/ds/src/primitives.css
    • Modules: packages/ds/src/{components,layouts,primitives}/*.css (authored as modular CSS)
    • Patterns: scoped root + nested layers (@scope + @layer base|variants|patterns); see DS README
  • packages/ui/ — shared Solid UI · README
  • packages/py-demo/ — demo Python uv workspace member (not for production)
  • packages/go-demo/ — demo Go workspace library (not for production); apps/web links it via workspace/link.go + replace in go.mod (same idea as uv workspace = true)

Design system CSS (DS)

When updating packages/ds, follow the scoped root + nested layers CSS module pattern (@scope + @layer base|variants|patterns). The DS README is the source of truth: DS CSS patterns.

Moon wires build and dev tasks per project; api:dev depends on api:build (uv sync at the workspace root). luna install runs root uv sync (one shared .venv + uv.lock) and go work sync before luna dev. For step-by-step task graphs (luna build, Uvicorn, SolidStart), follow each workspace README above.

Commands

All day-to-day commands go through the luna CLI (packages/cli). It orchestrates Moon, Proto, and Bun directly — there are no root package.json scripts to remember.

Bootstrap and lifecycle

luna install     # bootstrap workspace
luna clean       # :clean per project → moon clean --all → root luna:clean → .moon/cache last
luna dev         # moon run :dev --query "projectLayer=application"
luna build       # moon run :build --query "projectLayer=application"
luna start       # moon run :start --query "projectLayer=application"
luna test        # moon run :test --query "projectLayer=application"

All build/dev/start/test commands accept an optional project name (luna build app) and --affected flag (luna build --affected).

Code quality

luna orchestrates quality across all stacks in one command — TS (oxlint/oxfmt/tsc), Python (ruff via moon), Rust (cargo clippy/fmt), and Go (hugo config via moon):

luna lint             # TS: oxlint, Python: ruff check, Rust: clippy
luna format           # TS: oxfmt, Python: ruff format, Rust: cargo fmt
luna typecheck        # TS: tsc --build, Go: hugo config
luna check            # lint + format:check + typecheck (all stacks)

luna lint --fix       # apply fixes (oxlint --fix, ruff --fix, clippy --fix)
luna format --check   # check only (oxfmt --list-different, ruff --check, fmt --check)
luna fix              # lint:fix + format (all stacks)

Moon: single apps, subsets, and packages

Pass multiple project:task targets to run them in one invocation:

moon run app:dev api:dev              # interactive app + API only (no web)
moon run app:build api:build web:build

Use --query to filter the graph instead of listing every target (same query language as moon query projects):

moon run :dev --query 'project=[app,api]'
moon run :typecheck --query "projectLayer=library"   # shared packages (per-project inherited tasks)
moon query projects --help                           # filters: --id, --language, --layer, etc.

Examples for shared packages (see each package README for inherited tasks):

moon run ds:typecheck
moon run ui:typecheck

Configuration map

Dependency maintenance

Repo-wide outdated checks and upgrades go through the luna CLI so every toolchain stays in sync:

The luna CLI (packages/cli, built with Rust + Starbase) reports outdated tiers in order: protoRust / Cargo (cargo outdated) → BunPython / uv (root lockfile dry-run) → Go per go.mod. Hugo-style modules (tool in go.mod, local code only under workspace/) use go list -m -u on tool lines; other modules use direct go list -m -u (not the full workspace graph). Set LUNA_GO_FULL_GRAPH=1 to scan or update with go list -m -u all / go get -u all. luna outdated prints a summary and exits 0 (findings are informational). luna update follows the same order, then re-runs install (uv sync, go work sync). After luna update, review diffs and run luna check before committing.

luna outdated      # report + summary (exits 0)
luna update        # bump pins and dependencies repo-wide; then review and run luna check
luna update --major  # also apply major-version bumps where supported

Per stack (manual add / remove) — use these when you are changing one project, not refreshing everything:

  • Toolchain (proto) — edit .prototools, then luna install or proto install individually. Removing a tool line drops it from proto’s install set for this repo.
  • Hugo (apps/web)luna update bumps the tool line with go get -u=patch (or go get -tool …@latest with luna update --major). To pin a specific release manually: cd apps/web then go get -tool github.com/gohugoio/hugo@vX.Y.Z (updates apps/web/go.mod / go.sum). Set LUNA_GO_FULL_GRAPH=1 to restore slow full-graph go get -u all on tool-only modules.
  • Bun / workspaces — from the repo root, add to a workspace with bun add <pkg> --cwd apps/app (or --cwd packages/ui, etc.); use bun add -d <pkg> --cwd <path> for devDependencies. Remove with bun remove <pkg> --cwd <path>. Root-only deps: bun add <pkg> at the root.
  • Python (uv workspace) — from the repo root: uv add <package> --package api / uv remove <package> --package api (updates member pyproject.toml and root uv.lock); sync with uv sync or luna install. Add a new member in root pyproject.toml [tool.uv.workspace] and use [tool.uv.sources] name = { workspace = true } for inter-member deps.

Troubleshooting

luna: command not found

Install the CLI (~/.cargo/bin must be on your PATH):

moon run cli:build
moon run cli:install
luna --help

To run without installing, build and invoke the debug binary ( target/ is gitignored):

moon run cli:build --force
./target/debug/luna --help

Port already in use (EADDRINUSE)

Another process is still bound to the port (often after stopping a dev server).

lsof -i :8000    # API (Uvicorn) default; :3000 app; :3001 web

Note the PID from lsof, then:

kill -9 <PID>

Stale API or Vite processes

If you know the command line, you can narrow cleanup:

ps aux | grep -E "(uvicorn|vite)" | grep -v grep
pkill -f "uvicorn src.main:app"   # API (adjust if your entrypoint differs)

About

a polyglot monorepo starter built with moon, proto, rust with multi-stack package management with bun, go, and uv

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors