A modular Rust toolkit for Minecraft launchers and reusable application infrastructure.
Elemental provides a typed pipeline for discovering versions, preparing
instances, resolving Java runtimes, and launching vanilla or modded Minecraft.
It also contains standalone building blocks for version-aware persistence and
migrations, type-indexed object pools, download infrastructure, and manifest
schemas. Use elemental-kit end to end, or adopt the individual crates in other
Rust applications.
Note
Elemental is under active development. The driver table below reflects current workspace coverage, not a stability guarantee. See the issue tracker for current scope and known gaps.
- End-to-end lifecycle: catalog, inspect, prepare/install, load, build a launch command, and launch.
- Loader-aware design: dedicated flows for Vanilla, Fabric-like, installer-driven, and profiled legacy distributions.
- Typed storage and layouts: game roots, instances, libraries, assets, and
version artifacts resolve through
StorageandLayout. - Runtime and authentication: discover or select a local Java runtime, and
use offline, Microsoft, or Yggdrasil accounts through one
Authorizerinterface. - Reusable infrastructure:
elemental-sharedfor versioned persistence and migrations,elemental-objectfor type-indexed object pools,elemental-infrafor downloads, andelemental-schemafor manifests. - Flexible adoption: use the
elemental-kitfacade end to end or pick the individual async crates for another Rust application.
| Family | Drivers | Lifecycle |
|---|---|---|
| Vanilla | Vanilla | Catalog, inspect, install, reload, launch |
| Fabric ecosystem | Fabric, Legacy Fabric, Babric, Quilt | Catalog, inspect, install, reload, launch |
| Installer-driven | Forge, NeoForge, CleanroomMC, Outlands | Catalog, inspect, install, reload, launch |
| Profiled legacy | Rift, LiteLoader | Catalog, inspect, install, reload, launch |
These are implementation claims, not stability guarantees. Compatibility regressions and missing coverage are tracked in the issue tracker.
- Rust 1.85 or newer. The workspace uses edition 2024.
- A compatible Java runtime for launching Minecraft. Elemental discovers local
runtimes by default; use
--runtime-major-versionto select a major version,--runtime-pathto add custom installation directories, orRuntimeOptions::set_runtime_overrideto supply a distribution directly. - Network access for catalog and artifact downloads. Use
--local-onlywhen the instance is already prepared.
git clone https://github.com/ElectronicWave/Elemental.git
cd Elemental
cargo run -p launchpad -- --help
cargo run -p launchpad -- listLaunchpad writes to .minecraft by default. Running it without launch
arguments opens the interactive wizard:
cargo run -p launchpadFor non-interactive launches, pass the driver id and optional versions directly. Other drivers accept the same storage, runtime, and local-only options:
cargo run -p launchpad -- forge 1.20.1 47.3.1
cargo run -p launchpad -- --local-only fabric 1.20.1 0.16.10 --instance-name MyFabric-1.20.1
cargo run -p launchpad -- vanilla 1.20.1 --instance-name MyVanilla-1.20.1
cargo run -p launchpad -- --runtime-major-version 21 vanilla 1.20.1Launchpad defaults live in
crates/launchpad/src/defaults.rs.
[dependencies]
anyhow = "1"
elemental = { package = "elemental-kit", version = "0.2" }
tokio = { version = "1", features = ["macros", "process", "rt-multi-thread"] }Prepare and launch a vanilla instance:
use anyhow::Result;
use elemental::{
core::auth::{
accounts::Account,
authorizers::{Authorizer, offline::OfflineAuthorizer},
},
launcher::{DriverSpec, LaunchOptions, Launcher, RuntimeOptions},
};
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
let launcher = Launcher::builder()
.storage_root(".minecraft")
.build();
let prepared = launcher
.prepare(
"Vanilla-1.20.1".to_owned(),
DriverSpec::vanilla("1.20.1".into()),
&RuntimeOptions::default(),
)
.await?;
let account = OfflineAuthorizer {
username: "Player".to_owned(),
}
.authorize()
.await?;
let credential = account.credential().await?;
let command = launcher
.build_launch_command(
&prepared,
&credential,
&RuntimeOptions::default(),
&LaunchOptions::default(),
)
.await?;
let mut game = launcher.launch(command)?;
let status = game.child.wait().await?;
println!("Minecraft exited with {status}");
Ok(())
}Offline authentication keeps local development simple. Use a production
Authorizer for real player accounts. Authentication and launch are separate:
obtain an Account, derive a Credential, build a LaunchCommand, optionally
customize its arguments, then spawn it. Use prepare_with_session() to supply a
configured session while the launcher finishes and validates it.
OfflineAuthorizer, MicrosoftAuthorizer, and YggdrasilAuthorizer implement
the same Authorizer contract. AccountStore persists accounts and refreshes
them before a credential is used. Microsoft and Yggdrasil accounts also expose
skin and cape reads and, when supported by the provider, uploads and cape
selection.
Enable yggdrasil-auth to install and inject authlib-injector for
authlib-compatible credentials, or offline-server to run a local Yggdrasil
server for development. See the
elemental-launcher README
for account-store, texture, and offline-server examples.
Inspect and reopen an existing instance without preparing it again:
let instances = launcher.inspect_instances().await?;
for instance in instances {
println!("{} ({})", instance.instance_name, instance.driver.driver.id);
}
if let Some(instance) = launcher.inspect_instance("MyFabric-1.20.1".to_owned()).await? {
let prepared = launcher.load_instance(instance).await?;
println!("Loaded {}", prepared.driver().id);
}0.2 is a breaking release at every layer. See the 0.1 to 0.2 migration guide for package, core, authentication, launcher, downloader, persistence, object, and schema changes.
| Crate | Purpose |
|---|---|
elemental-kit |
Re-export facade for the library crates |
elemental-core |
Storage, runtime discovery, authentication, and launch primitives |
elemental-driver |
Distribution catalogs, families, and loader-specific logic |
elemental-launcher |
High-level launcher facade and instance lifecycle |
elemental-infra |
Download planning, materialization, and archive utilities |
elemental-shared |
Version-aware persistence and migrations |
elemental-object |
Type-indexed global and task-local object pools |
elemental-schema |
Mojang and modloader manifest types |
launchpad |
End-to-end CLI launcher |
elemental-kit re-exports the library crates under stable module names. It is
the single dependency for applications that want the launcher stack and the
reusable infrastructure together.
| Module | Package | Feature |
|---|---|---|
elemental::core |
elemental-core |
core |
elemental::driver |
elemental-driver |
driver |
elemental::launcher |
elemental-launcher |
launcher |
elemental::infra |
elemental-infra |
infra |
elemental::object |
elemental-object |
object |
elemental::shared |
elemental-shared |
shared |
elemental::schema |
elemental-schema |
schema |
full enables every module. The default feature set is full plus
shared-json and object-notify.
Common launcher types are available through the prelude:
use elemental::prelude::*;The prelude only re-exports types from enabled modules, so it works with a selective feature set.
For a smaller dependency surface, disable default features and select only the modules an application uses:
[dependencies]
elemental = {
package = "elemental-kit",
version = "0.2",
default-features = false,
features = ["launcher"],
}Forwarded features:
| Feature | Effect |
|---|---|
shared-json |
Enables elemental-shared/json |
shared-toml |
Enables elemental-shared/toml |
infra-serde |
Enables elemental-infra/serde |
object-notify |
Enables elemental-object/notify |
yggdrasil-auth |
Enables Yggdrasil authentication support, including authlib-injector download and launch injection |
authlib-injector-embed |
Embeds an authlib-injector snapshot as a fallback when metadata retrieval, download, or verification fails |
offline-server |
Enables the local offline Yggdrasil server and authlib-injector support in elemental-launcher |
Important
Forwarded features enable their parent module where applicable:
shared-json and shared-toml enable shared, object-notify enables
object, infra-serde enables infra, and yggdrasil-auth enables core
and launcher. With default-features = false, add the module feature
directly when you need it without a forwarded feature.