Docs
CLI Commands
Reference

CLI reference

Lithos has six subcommands. For flag-level detail, run lithos --help or lithos <subcommand> --help.

All commands accept a positional PROJECT argument. If omitted, Lithos searches the current directory — see Configuration → file resolution.

CommandPurpose
deployReconcile state with config and apply the diff.
diffPrint the diff without applying it.
undoRestore the last recorded checkpoint for an environment.
outputsPrint the outputs of the last deploy as JSON, YAML, or importable modules.
destroyRemove every resource Lithos manages for an environment.
importAdopt an existing experience into a Lithos project.

deploy

lithos deploy [PROJECT] --environment <label> [flags]

deploy is the normal workflow: load config and state, reconcile them against Roblox, run preflight, show a plan, checkpoint the current graph, and apply the diff in dependency order.

Live reconciliation

Before diffing, deploy checks that the resources recorded in state still exist. Each one ends up verified, missing, skipped, or unknown.

  • missing: drop it from state so the next plan recreates it.
  • unknown: keep it in state so the deploy fails safe on transient API trouble.

Lithos currently verifies experiences, places, game passes, and developer products directly. Sub-resources are inferred from their parent or skipped.

Plan preview and confirmation

Before apply, Lithos prints a structured preview of creates, updates, deletes, noops, and skips. Riskier resources show field-level summaries when possible, and destructive operations are marked explicitly.

Interactive terminals prompt for confirmation. Non-interactive stdout auto-approves after printing a plain summary so existing scripts keep working.

Preflight diagnostics and checkpoints

Preflight catches the common Roblox failures before apply: missing Open Cloud keys, missing universe-places.write, wrong universe scope, unsupported access combinations, and oversized place files.

If preflight passes, Lithos records a checkpoint of the current environment so lithos undo has a baseline.

Useful flags

FlagEffect
--environment <label> / -eRequired. Which environment block to apply.
--yes / -ySkip the confirmation prompt and apply immediately.
--no-previewSkip the preview entirely. Implies --yes.
--plain-previewRender a plain (non-colored) summary. Useful in CI log viewers without ANSI support.
--allow-purchasesAllow paid-asset operations (developer products, etc.) without an extra confirm.
⚠️

Avoid --no-preview unless the pipeline already gives you enough confidence in the diff.

diff

lithos diff [PROJECT] --environment <label> [--live]

diff prints the plan without applying it. By default it is offline and compares config to persisted state.

Use --live to run the same reconciliation pass as deploy first:

lithos diff --environment dev --live

Use plain diff for config-only review. Use --live when you suspect drift.

undo

lithos undo [PROJECT] --environment <label> [flags]

undo rolls an environment back toward its most recent checkpoint. It does not read old YAML or Git history. Instead it:

  1. Loads the baseline snapshot stored before the last deploy or undo.
  2. Imports the live Roblox experience so rollback plans against reality, not stale state.
  3. Runs the same preflight diagnostics and plan preview as deploy.
  4. Applies the diff back toward that snapshot and records the result.

Use the same preview flags as deploy: --yes, --no-preview, and --plain-preview. --allow-purchases is also supported.

Roblox deploys are not transactional. undo reconciles live state and then drives it back toward the last checkpoint Lithos recorded.

outputs

lithos outputs [PROJECT] --environment <label> [--output <file>] [--format <format>] [--roblox-ts]

outputs prints the last deploy's outputs. Stdout defaults to JSON.

  • --output ending in .lua or .luau implies Luau.
  • --format accepts json, yaml, yml, lua, and luau.
  • --roblox-ts writes a .d.ts sidecar next to a Luau output.

You can also move those defaults into project config:

lithos.yml
outputs:
  writeDir: src/shared/generated
  outputName: lithosOutputs
  format: luau
  robloxTs: true

The codegen alias with snake_case also works:

lithos.yml
codegen:
  write_dir: src/shared/generated
  output_name: lithosOutputs
  format: luau
  typescript: true

Rules to know:

  • Use either path or writeDir + outputName, not both.
  • If outputName has no extension, Lithos adds one from format.
  • If robloxTs / typescript is enabled and format is omitted, Lithos defaults to .luau.
  • CLI flags override config values.

With either config, this is enough:

lithos outputs --environment dev

After deploying the getting-started example (opens in a new tab), default JSON output looks like:

{
  "experience_singleton": {
    "experience": {
      "assetId": 3296599132,
      "startPlaceId": 8667346609
    }
  },
  "place_start": {
    "place": { "assetId": 8667346609 }
  },
  "placeFile_start": {
    "placeFile": { "version": 2 }
  }
}

To require outputs from game code, write a Luau module:

lithos outputs --environment dev --output src/shared/generated/lithosOutputs.luau
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local outputs = require(ReplicatedStorage.shared.generated.lithosOutputs)

local startPlaceId = outputs.experience_singleton.experience.startPlaceId
local placeVersion = outputs.placeFile_start.placeFile.version

For roblox-ts, add --roblox-ts so Lithos also writes lithosOutputs.d.ts beside it:

lithos outputs --environment dev --output src/shared/generated/lithosOutputs.luau --roblox-ts
import outputs from "shared/generated/lithosOutputs";
 
const startPlaceId = outputs.experience_singleton.experience.startPlaceId;
const placeVersion = outputs.placeFile_start.placeFile.version;

destroy

lithos destroy [PROJECT] --environment <label> [--yes]

destroy applies a full delete plan for the environment. It uses the same preview, confirmation, and dependency ordering as deploy.

🚫

From Lithos's point of view, destroy is final: state is wiped. Roblox usually archives the assets instead of hard-deleting them.

import

lithos import [PROJECT] --environment <label> --target-id <experience-id>

import adopts an existing Roblox experience into a Lithos project. Use it when the experience already exists and you want Lithos to manage it.

⚠️

import is experimental. It does not match every existing resource to a configured one, so many resources will be re-created on the next deploy. Test it on staging before you point it at production.

A safer pattern is to mirror production into a staging environment first, verify that the diff is empty, and only then import production.

Exit codes

CodeMeaning
0Success. Includes the case "nothing to do."
1A user-facing failure. Bad config, auth failure, apply failure, conflicting state, etc. The error message names the cause.
2The command was cancelled at the preview / confirmation step.

In CI, treat any non-zero exit as failure.

Next steps