XHMCL architecture
Technology decision
XHMCL uses Kotlin/JVM 21 and Compose Desktop. Kotlin provides concise domain code and safe coroutines, while Compose gives a shared declarative UI across Windows, Linux, and macOS. JVM 21 is the launcher runtime; managed game runtimes remain isolated per Minecraft generation.
Boundaries
Compose UI
│
AppState (user intent + observable state)
│
├── Instance / content / account / server services
├── Manifest and artifact download services
├── Java runtime discovery and provisioning
├── DownloadQueue ── source routing, segmented transfers, retries, hashes, progress, cancellation
├── LoaderInstaller ── Fabric/Quilt profiles + Forge/NeoForge official installers
├── NetworkSupport ── environment/Windows system-proxy detection and child-process propagation
├── HostedServerManager ── core install, EULA, server.properties
├── ServerProcessController ── process, console, commands, safe stop
├── MemoryOptimizer ── optional elevated helper mode (Windows only)
├── Launch-plan resolver and game process supervisor
└── PluginManager ── ServiceLoader plugins
│
JSON metadata + isolated instance directoriesThe UI does not directly implement download, authentication, filesystem, or launch behavior. Core services are intentionally independent from Compose so they can be tested and reused by a future CLI.
Instance layout
instances/<name>/
├── xhmcl-instance.json
├── version.json
├── libraries/
├── natives/
├── logs/
├── modpacks/
└── minecraft/
├── mods/
├── shaderpacks/
├── resourcepacks/
└── saves/Dedicated servers are isolated under hosted-servers/<uuid>/; their process working directory is never the launcher installation directory. Deleted profiles are moved to the recovery directory.
Security rules
- Microsoft refresh/access tokens must move to the platform credential store before production release.
- Downloads must be verified with SHA-1/SHA-256 from the authoritative metadata source.
- A server EULA is written only after the user explicitly enables acceptance for that profile.
- The application manifest remains
asInvoker. Only the explicit memory-optimization action starts a short-lived helper mode through the Windowsrunasverb. - The memory helper accepts no path or general command. The parent waits on its process handle and decodes the released-memory count from the exit code, so the elevated mode performs no filesystem operations.
- Changing the game root never migrates, deletes, or overwrites the previous instance root automatically.
- Console commands are sent through the process standard input and newline/control characters are rejected.
- Modpack extraction rejects paths outside the selected instance.
- Plugins use a versioned API boundary. A future release should add signatures, declared permissions, and out-of-process isolation for untrusted plugins.
- Instance deletion moves data to an application recovery directory instead of erasing it immediately.
Delivery phases
- Foundation: local instances, locales, themes, runtime discovery, official manifest, content files.
- Launch pipeline: Mojang metadata inheritance, assets/libraries, native extraction, argument rules, logging, process supervision.
- Loaders and catalogs: Forge, Fabric, Quilt, NeoForge, Modrinth and CurseForge integrations.
- Accounts and sync: Microsoft device-code authentication, platform credential vault, server status, update engine.
- Ecosystem: signed plugin SDK, permissions, extension marketplace, telemetry opt-in, release packaging.