Skip to content

ayagmar/quarkus-forge

Repository files navigation

Quarkus Forge

CI Release codecov Java JBang

Documentation & Landing Page Β· Getting Started Β· Security

Quarkus Forge is a keyboard-first terminal UI (TUI) and headless CLI for generating Quarkus projects. It provides a faster, more repeatable terminal workflow than quarkus create while staying aligned with code.quarkus.io metadata and generation behavior.

Quarkus Forge TUI

Why use Quarkus Forge?

  • Fast terminal workflow: Browse extensions, adjust metadata, and generate a project without leaving the keyboard.
  • Works well online and offline: Live metadata is preferred, but cached and snapshot data keep the tool usable when the network is unreliable.
  • Good fit for CI: The headless artifact keeps scripted generation small, predictable, and easy to wire into pipelines.
  • Deterministic project templates: Forgefile plus the optional locked section gives teams a simple way to make generation reproducible.
  • Thoughtful post-generation flow: Open the project in your IDE, hand off to a shell, or publish to GitHub without retyping context.
  • Customizable but explicit: Theme overrides, IDE command overrides, and post-generation hooks are supported and documented clearly.

Quarkus Forge vs quarkus create

Feature Quarkus Forge quarkus create
Offline / no-internet βœ… snapshot cache fallback ❌ requires network
Keyboard-first TUI βœ… full Vim-style navigation ❌ wizard prompts
Deterministic replay βœ… Forgefile + --lock ❌
CI headless jar βœ… no TUI deps (~40% smaller) ⚠️ includes full CLI toolchain
Fuzzy extension search βœ… ❌
Session persistence βœ… remembers last config ❌
Theming βœ… .tcss override ❌
Post-gen IDE open βœ… auto-detects IDEs ❌
Quarkus CLI required ❌ plain JRE / JBang βœ…

TUI vs Headless

TUI (interactive) Headless (generate)
Best for Local development, exploration CI pipelines, scripting, containers
Jar quarkus-forge.jar quarkus-forge-headless.jar
Interaction Keyboard-driven UI Flags only, non-interactive
Extension search Live fuzzy search --extension / --preset flags
Forgefile Export via post-gen menu --from, --save-as, --lock
Post-gen hooks IDE open, GitHub, shell handoff n/a
JVM flag needed --enable-native-access=ALL-UNNAMED none

Which Artifact Should I Use?

If you want to... Use Why
Explore extensions interactively quarkus-forge.jar Includes the full TUI
Run in CI or containers quarkus-forge-headless.jar Smaller and has no TUI or terminal dependencies
Automate generate locally quarkus-forge-headless.jar Same command surface with less runtime baggage
Keep one local developer jar quarkus-forge.jar Supports both TUI and generate
Avoid the JVM at runtime native binary Standalone executable

GitHub Release Asset Guide

Use case Download this release asset
Interactive JVM app on any OS quarkus-forge-jvm.jar
Headless JVM app for CI/containers quarkus-forge-headless.jar
Interactive native app on Linux quarkus-forge-linux-x86_64
Interactive native app on macOS (Apple Silicon) quarkus-forge-macos-aarch64
Interactive native app on Windows quarkus-forge-windows-x86_64.exe
Headless native app on Linux quarkus-forge-headless-linux-x86_64
Headless native app on macOS (Apple Silicon) quarkus-forge-headless-macos-aarch64
Headless native app on Windows quarkus-forge-headless-windows-x86_64.exe

Every GitHub release publishes a matching .sha256 file for each artifact.

On Linux, download both files and verify locally:

sha256sum -c <artifact>.sha256

On macOS:

shasum -a 256 -c <artifact>.sha256

Examples:

sha256sum -c quarkus-forge-jvm.jar.sha256
shasum -a 256 -c quarkus-forge-headless-macos-aarch64.sha256

On Windows PowerShell:

$expected = (Get-Content .\quarkus-forge-windows-x86_64.exe.sha256).Split(' ')[0].ToLower()
$actual = (Get-FileHash .\quarkus-forge-windows-x86_64.exe -Algorithm SHA256).Hash.ToLower()
$actual -eq $expected

Keyboard Quick Reference (TUI)

Key Action
? Help overlay
Ctrl+P Command palette
/ or Ctrl+F Focus extension search
Space Toggle extension
Enter / Alt+G Generate project
Ctrl+R Reload catalog
Ctrl+K Toggle favorites-only
Alt+S Toggle selected-only view
v Cycle category filter
c Toggle current category
C Open all categories
x Clear selected extensions
Esc Unwind filter context / exit
Ctrl+C Quit immediately

Full keybindings: docs/modules/ROOT/pages/ui/keybindings.adoc

Requirements

  • Java 25+
  • Maven 3.9+

Build

Full build (TUI + headless)

./mvnw clean package -DskipTests

Output: target/quarkus-forge.jar

Headless-only build

./mvnw clean package -Pheadless

Output: target/quarkus-forge-headless.jar β€” ~40% smaller, no TUI or terminal dependencies.

Native image build

./mvnw clean package -Pnative

Output: target/quarkus-forge β€” standalone binary, no JVM required at runtime.

For a headless native build, use:

./mvnw clean package -Pheadless,native

Output: target/quarkus-forge-headless

Note: Native image requires GraalVM or a compatible toolchain. Set GRAALVM_HOME before building. CI enforces native binary size budgets for both the interactive (-Pnative) and headless (-Pheadless,native) builds, and keeps the build report and native-image log for diagnostics.

Bash Completion

Generate completion scripts after building the jars:

just completion-bash

This writes:

  • target/completions/quarkus-forge.bash
  • target/completions/quarkus-forge-headless.bash

Load them into the current shell:

source target/completions/quarkus-forge.bash
source target/completions/quarkus-forge-headless.bash

Release Checksums

Generate .sha256 files for locally built release jars:

just release-checksums

Verify locally built artifacts:

sha256sum -c target/quarkus-forge.jar.sha256
sha256sum -c target/quarkus-forge-headless.jar.sha256

Quick Start

JBang (no build required)

Run directly from the JBang catalog:

jbang quarkus-forge@ayagmar

Headless-only (no TUI dependencies, ideal for CI):

jbang quarkus-forge-headless@ayagmar generate \
  --group-id org.acme \
  --artifact-id demo \
  --build-tool maven \
  --java-version 25

Install as a persistent local command:

jbang app install --name quarkus-forge quarkus-forge@ayagmar
quarkus-forge

Interactive TUI

java --enable-native-access=ALL-UNNAMED -jar target/quarkus-forge.jar

Note: The --enable-native-access=ALL-UNNAMED flag suppresses Panama FFM warnings from the TamboUI terminal backend.

Hit ? for help, Ctrl+P for the command palette, or / to jump to extension search.

Headless Generate

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

The full jar (quarkus-forge.jar) also supports the generate subcommand. The headless-only jar is preferred for CI/containers β€” no TUI or terminal dependencies.

Dry-Run

java -jar target/quarkus-forge-headless.jar generate \
  --group-id org.acme \
  --artifact-id demo \
  --preset web \
  --extension io.quarkus:quarkus-smallrye-health \
  --dry-run

Post-Generation Hooks

java -jar target/quarkus-forge.jar \
  --post-generate-hook="git init && git add . && git commit -m 'Initial commit'"

Warning: --post-generate-hook is executed by your local shell in the generated project directory. Only use trusted command strings.

Deterministic Replay

# 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 locked section
java -jar target/quarkus-forge-headless.jar generate --from Forgefile --lock-check --dry-run

# Save current configuration as a shareable template
java -jar target/quarkus-forge-headless.jar generate --save-as my-template.json --lock \
  --group-id com.acme --artifact-id my-service -e io.quarkus:quarkus-rest

Customization

Theming

Create a .tcss file with semantic color tokens (one token = value per line):

base = #1e1e2e
text = #cdd6f4
accent = #f38ba8
focus = #89b4fa
muted = #6c7086

Apply via environment variable or system property:

export QUARKUS_FORGE_THEME=/path/to/my-theme.tcss
# or
java -Dquarkus.forge.theme=/path/to/my-theme.tcss -jar target/quarkus-forge.jar

IDE Auto-Detection

After generating a project, Quarkus Forge auto-detects installed IDEs (IntelliJ IDEA, VS Code, Eclipse, Cursor, Zed, Neovim) and shows one menu entry per detected IDE.

To override auto-detection, set QUARKUS_FORGE_IDE_COMMAND:

export QUARKUS_FORGE_IDE_COMMAND="idea ."           # Force IntelliJ
export QUARKUS_FORGE_IDE_COMMAND="code-insiders ."  # VS Code Insiders

Warning: QUARKUS_FORGE_IDE_COMMAND is executed through the local shell. Use only trusted command strings.

Where Files Live

  • Machine-local app state: ~/.quarkus-forge/
    • catalog-snapshot.json β€” catalog cache/snapshot (offline fallback)
    • preferences.json β€” user preferences (restored on next launch)
    • favorites.json β€” favorite extensions
    • recipes/ β€” reusable Forge recipes
  • Project/workflow files:
    • Forgefile β€” shareable project template with optional locked section for CI reproducibility

Forgefile path resolution:

  • --from <name>: uses local file if found; otherwise resolves ~/.quarkus-forge/recipes/<name>.
  • --save-as <name>: writes to ~/.quarkus-forge/recipes/<name> when <name> is just a filename.

Architecture

The codebase is organized into focused modules that follow SOLID principles and separate concerns cleanly.

API Layer (api/)

  • QuarkusApiClient β€” Async HTTP client with retry/backoff, implements AutoCloseable for resource safety. Responsible only for transport orchestration.
  • ApiPayloadParser β€” Stateless JSON deserialization for all API payloads (extensions, metadata, streams, presets, OpenAPI).
  • JsonFieldReader β€” Shared JSON field reading helpers used across all store and parser classes (DRY).
  • CatalogSnapshotCache β€” Local catalog snapshot persistence and freshness management.

Domain Layer (domain/)

  • ProjectRequest / ProjectRequestValidator β€” Immutable project configuration with validation rules.
  • MetadataCompatibilityContext β€” Enforces metadata-driven compatibility constraints (build tool ↔ Java version).
  • CliPrefillMapper β€” Maps CLI options to validated project requests.

Persistence Layer (persistence/)

  • UserPreferencesStore β€” Persists the last successful request used to prefill the next TUI session.
  • ExtensionFavoritesStore β€” Owns favorites/recents storage for TUI filters and headless favorites preset expansion.

UI Layer (ui/)

  • CoreTuiController β€” TUI orchestration shell and callback sink.
  • CatalogLoadCoordinator / GenerationFlowCoordinator β€” Dedicated async workflow coordinators for catalog loading and generation.
  • CoreUiReducer β€” Pure reducer for UI intents and effects.
  • UiRenderStateAssembler β€” Builds immutable render models from reducer state plus runtime-only render context.
  • ExtensionCatalogProjection / ExtensionCatalogNavigation / ExtensionCatalogPreferences β€” The extension browsing stack for filtering, selection, favorites, and projection updates.
  • OverlayRenderer β€” Stateless overlay rendering (command palette, help, progress, post-generation menus).
  • MetadataSelectorManager β€” Metadata selector state (platform stream, build tool, Java version cycling and label generation).
  • BodyPanelRenderer / FooterLinesComposer β€” Layout rendering helpers.

Runtime Layer (runtime/)

  • RuntimeServices β€” Shared runtime composition for API, catalog, archive, and persistence services.
  • TuiBootstrapService β€” Runtime wiring for TUI startup, catalog bootstrap, Tamboui backend preference, and session execution.

Post-Generation Layer (postgen/)

  • PostTuiActionExecutor β€” Post-generation shell actions (IDE open, GitHub publish, terminal handoff).
  • IdeDetector β€” Cross-platform IDE auto-detection (macOS, Linux, Windows).
  • TuiSessionSummary β€” Immutable summary of the final request and post-generation exit plan.

Application Layer (application/)

  • InputResolutionService β€” Shared pure pipeline for resolving CLI/headless prefill into validated request state.
  • StartupMetadataSelection β€” Startup metadata source selection and fallback detail.

CLI Layer (cli/)

  • QuarkusForgeCli β€” Picocli command entry point for TUI mode, runtime configuration, and startup metadata resolution.
  • HeadlessCli β€” Lightweight entry point for headless/CI mode (no TUI or terminal dependencies).
  • GenerateCommand / RequestOptions β€” Headless generation command model and option parsing.
  • ExitCodes β€” Central exit code constants shared by both entry points.

Headless Layer (headless/)

  • HeadlessGenerationService β€” Decoupled headless generation engine for CI/scripting, resolving Forgefiles through InputResolutionService and narrow catalog/generation/favorites collaborators.
  • AsyncFailureHandler β€” Headless boundary adapter for consistent exit codes, diagnostics, and user-facing messages.
  • HeadlessCatalogClient β€” Internal timeout-aware adapter that fronts catalog, preset, and archive services for one headless session.
  • HeadlessOutputPrinter β€” Text-mode summaries and validation/error output.

Shared timeout/cancellation/failure classification is provided by dev.ayagmar.quarkusforge.diagnostics.BoundaryFailure and reused by headless and runtime code.

Forge Layer (forge/)

  • ForgefileStore β€” Forgefile persistence with omission-preserving top-level template fields.
  • Forgefile / ForgefileLock β€” Shareable intent template plus explicit deterministic lock data.

Archive Layer (archive/)

  • SafeZipExtractor β€” Hardened ZIP extraction with Zip-Bomb and Zip-Slip protections.
  • ProjectArchiveService β€” Orchestrates download, extraction, and progress reporting.

For a complete overview of the internal design, see the Architecture & Internals documentation.

Docs

Public documentation: ayagmar.github.io/quarkus-forge/docs. Security details are documented separately in Security.

Useful entry points:

Antora source lives in docs/. The site build lives in site/. For local docs work, see site/README.md.

Contributing

sdk env install          # install Java 25 via SDKMAN! (.sdkmanrc)
scripts/verify/verify.sh # shared CI/local verification entrypoint
just verify              # format-check + headless compile + all tests
just format              # auto-format

Docs verification uses the same shared entrypoints as CI:

scripts/verify/docs-build.sh
scripts/verify/docs-linkcheck.sh

Native packaging and release smoke checks use the same shared scripts as release automation:

scripts/verify/native-size.sh headless
scripts/verify/native-size.sh interactive
scripts/verify/native-release-smoke.sh <binary> <headless|interactive-posix|interactive-windows>

Or without just, use the shared scripts directly instead of retyping the underlying Maven and npm commands.

Coverage reports (after scripts/verify/coverage.sh): target/site/jacoco/index.html (HTML) and target/site/jacoco/jacoco.xml (XML).

See CONTRIBUTING.md for full setup guide, code style, testing conventions, and commit format. PRs welcome.

About

πŸ”¨ Forge your next Quarkus app in the terminal. A lightning-fast, keyboard-driven TUI built with Java 25, TamboUI, and GraalVM.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors