CLI Headless Mode

Overview

Quarkus Forge supports two entry points:

  • quarkus-forge.jar (full) — includes TUI and headless generate subcommand

  • quarkus-forge-headless.jar (headless-only) — smaller jar without TUI/terminal dependencies, ideal for CI

Both jars share the same generate subcommand with identical flags and behavior.

Build

# Full jar (TUI + headless)
mvn clean package -DskipTests

# Headless-only jar
mvn clean package -Pheadless

Command

Use generate for non-interactive project generation:

java -jar target/quarkus-forge-headless.jar generate \
  --group-id org.acme \
  --artifact-id demo \
  --project-version 1.0.0-SNAPSHOT \
  --build-tool maven \
  --java-version 25 \
  --output-dir .
The full jar also works: java -jar target/quarkus-forge.jar generate …​

Common Examples

Dry-run validation only:

java -jar target/quarkus-forge-headless.jar generate \
  --group-id org.acme \
  --artifact-id demo \
  --build-tool maven \
  --java-version 25 \
  --dry-run

Use extensions and preset together:

java -jar target/quarkus-forge-headless.jar generate \
  --group-id org.acme \
  --artifact-id demo \
  --build-tool maven \
  --java-version 25 \
  --preset web \
  --extension io.quarkus:quarkus-smallrye-health

Generate from a Forgefile template:

java -jar target/quarkus-forge-headless.jar generate --from ./Forgefile

Generate and write/update the locked section:

java -jar target/quarkus-forge-headless.jar generate --from ./Forgefile --lock

Verify no drift against the locked section:

java -jar target/quarkus-forge-headless.jar generate --from ./Forgefile --lock-check --dry-run

Save a reusable template by name into ~/.quarkus-forge/recipes:

java -jar target/quarkus-forge-headless.jar generate \
  --dry-run \
  --group-id org.acme \
  --artifact-id demo \
  --build-tool maven \
  --java-version 25 \
  --save-as starter.json

Reuse that template later by name:

java -jar target/quarkus-forge-headless.jar generate --from starter.json
All examples above also work with the full jar (quarkus-forge.jar). The headless jar is preferred for CI/containers as it has no TUI or terminal dependencies.

Key Flags

  • Metadata: --group-id, --artifact-id, --project-version, --package-name, --output-dir

  • Platform/build: --platform-stream, --build-tool, --java-version

  • Extensions: --extension (repeatable or comma-separated)

  • Presets: --preset (repeatable; keys resolved from code.quarkus.io/api/presets, plus favorites)

  • Validation only: --dry-run

  • Diagnostics: --verbose

  • Forgefile: --from, --save-as, --lock, --lock-check

Exit Codes

  • 0: success

  • 2: validation/input error

  • 3: network/API error

  • 4: archive/extraction/output-path error

  • 130: cancelled/interrupted

The Forgefile

A Forgefile is a shareable JSON template that captures all inputs needed to reproduce a Quarkus project generation.

{
  "groupId": "com.acme",
  "artifactId": "my-service",
  "buildTool": "maven",
  "javaVersion": "25",
  "extensions": ["io.quarkus:quarkus-rest"],
  "presets": ["web"],
  "locked": {
    "platformStream": "io.quarkus.platform:3.31",
    "buildTool": "maven",
    "javaVersion": "25",
    "extensions": ["io.quarkus:quarkus-rest", "io.quarkus:quarkus-arc"],
    "presets": ["web"]
  }
}

The optional locked section pins exact resolved values for deterministic builds:

  • --lock writes or updates the locked section after generation

  • --lock-check verifies no drift between current inputs and locked values

  • If drift is detected, the build fails with a validation error listing the differences

Notes

  • Output path resolves to <output-dir>/<artifact-id>.

  • Extension IDs are validated against the loaded catalog.

  • When --from is set, request metadata fields come from the Forgefile; CLI --preset and --extension are appended.

  • --from <name> falls back to ~/.quarkus-forge/recipes/<name> when no local file exists.

  • --save-as <name> writes to ~/.quarkus-forge/recipes/<name> when <name> has no path separators.

  • Source mode is surfaced in diagnostics (live, cache, snapshot).