Introduction
EasyLauncher is a modern, modular library designed to make building custom Minecraft launchers as simple as possible across multiple programming languages.
Instead of reinventing the wheel with complex authentication flows, JSON parsing for versions, and multithreaded asset downloading, EasyLauncher provides a unified API to handle all the heavy lifting. Our architecture is designed to be completely decoupled from the UI, meaning you have complete freedom over how your launcher looks and feels.
Installation
Choose your preferred language environment to install the library. We distribute packages across all major package managers.
npm install easylauncher-node
Quickstart
Here's how to launch vanilla Minecraft in under 10 lines of code using Python:
from easylauncher import MinecraftLauncher, Version
from easylauncher.auth import OfflineAuth
# Initialize the launcher with a working directory
launcher = MinecraftLauncher(directory="./.minecraft")
# Setup offline authentication (or use MicrosoftAuth)
account = OfflineAuth("Notch")
# Install the necessary game files
launcher.install(Version("1.20.4"))
# Launch the game with arguments
launcher.launch(
version="1.20.4",
auth=account,
ram_mb=4096
)
Authentication
EasyLauncher supports both Offline (cracked/testing) authentication and official Microsoft Authentication via OAuth2. We abstract away the Xbox Live and Minecraft Services handshakes.
Offline Authentication
Useful for local testing or custom servers without premium mode enabled.
import { OfflineAuth } from 'easylauncher';
const auth = new OfflineAuth('PlayerName123');
Microsoft Authentication
To use official Microsoft accounts, you need to initiate the OAuth2 Device Code flow or the Interactive flow.
import { MicrosoftAuth } from 'easylauncher';
const auth = new MicrosoftAuth({ clientId: 'YOUR_AZURE_CLIENT_ID' });
// This will open the user's browser to login to Microsoft
const session = await auth.loginInteractive();
console.log(`Logged in as ${session.profile.name}`);
Version Resolution
EasyLauncher automatically fetches the official Mojang version manifest. You can easily query for releases, snapshots, or specific versions.
use easylauncher::versions::VersionManifest;
// Get the latest release version (e.g. 1.20.4)
let manifest = VersionManifest::fetch().await?;
let latest_release = manifest.latest.release;
println!("Latest Minecraft Version: {}", latest_release);
Modloaders (Fabric / Forge)
Installing a modloader is just as easy. Simply pass a modloader configuration object to the install step.
from easylauncher.modloaders import Fabric
# This will download Minecraft 1.20.4 AND the Fabric Loader
launcher.install(Version("1.20.4"), modloader=Fabric(loader_version="0.15.7"))
Asset Downloading
Minecraft requires thousands of individual assets (sounds, textures, objects) and Java libraries to run. EasyLauncher handles this natively using a highly-optimized, multi-threaded download pool.
You can hook into the download progress to update your GUI's progress bars:
launcher.on('download_progress', (event) => {
// event contains: { totalFiles, downloadedFiles, bytesTotal, bytesDownloaded, currentFile }
const percent = (event.bytesDownloaded / event.bytesTotal) * 100;
updateProgressBar(percent);
updateStatusText(`Downloading: ${event.currentFile}`);
});
Launch Arguments
You have full control over the JVM arguments, memory allocation, and game window size. EasyLauncher intelligently sets the defaults based on the Java version required for the specific Minecraft version.
LaunchOptions options = new LaunchOptions.Builder()
.setRamMb(8192) // 8GB RAM
.setJavaPath("C:\\Program Files\\Java\\jdk-17\\bin\\java.exe")
.setWindowSize(1920, 1080)
.setFullscreen(true)
.addJvmArgument("-XX:+UseG1GC") // Custom Garbage Collector
.build();
launcher.launch("1.20.4", auth, options);
Python Guide
The Python version of EasyLauncher is fully type-hinted and supports asynchronous downloads via asyncio and aiohttp.
Beginner: Simple Launch
The easiest way to get started is using the synchronous wrapper. This handles everything automatically in the background.
from easylauncher import MinecraftLauncher, Version
from easylauncher.auth import OfflineAuth
launcher = MinecraftLauncher(directory="./.minecraft")
launcher.install(Version("1.20.4"))
launcher.launch(version="1.20.4", auth=OfflineAuth("Player"))
Pro: Async Customization
For advanced GUIs (like PyQt), you'll want to use the async API to avoid blocking the main thread, and hook into the event system.
import asyncio
from easylauncher.asyncio import AsyncMinecraftLauncher
from easylauncher.events import DownloadProgressEvent
async def main():
launcher = AsyncMinecraftLauncher(directory="./.minecraft")
@launcher.on(DownloadProgressEvent)
async def on_progress(event):
print(f"Downloaded {event.downloaded_files}/{event.total_files} files")
await launcher.install_async("1.20.4")
process = await launcher.launch_async("1.20.4")
await process.wait()
asyncio.run(main())
Node.js Guide
The Node.js implementation is built specifically with Electron and Tauri in mind.
Beginner: Express Launch
import { MinecraftLauncher, OfflineAuth } from 'easylauncher';
const launcher = new MinecraftLauncher('./.minecraft');
await launcher.install('1.20.4');
await launcher.launch({
version: '1.20.4',
auth: new OfflineAuth('Steve')
});
Pro: Electron IPC & Modloaders
When building an Electron app, use the IPC bridge to pipe progress safely to the renderer process while injecting a custom Fabric modloader environment.
import { ipcMain } from 'electron';
import { MinecraftLauncher, Modloaders } from 'easylauncher';
ipcMain.handle('launch-game', async (event, args) => {
const launcher = new MinecraftLauncher(args.dir);
// Pipe events to the frontend UI
launcher.on('progress', (data) => event.sender.send('dl-progress', data));
// Install with Fabric configuration
await launcher.install('1.20.4', {
modloader: new Modloaders.Fabric('0.15.7'),
parallelDownloads: 16 // Max out network threads
});
return await launcher.launch({
version: '1.20.4',
memory: { min: '2G', max: '6G' },
jvmArgs: ['-XX:+UnlockExperimentalVMOptions', '-XX:+UseZGC']
});
});
Java Guide
The Java version uses modern Java 17 features and provides detailed callbacks.
Beginner: Quick Launch
MinecraftLauncher launcher = new MinecraftLauncher(Path.of("./.minecraft"));
launcher.install(new Version("1.20.4"));
launcher.launch("1.20.4", new OfflineAuth("Player"));
Pro: Custom Auth Flow & Game Output
Build a robust headless launcher tracking the game's stdout logs and utilizing the full Microsoft OAuth2 Device Code flow.
MicrosoftAuth auth = new MicrosoftAuth(CLIENT_ID);
auth.loginDeviceCode(code -> {
System.out.println("Please go to: " + code.verificationUrl());
System.out.println("Enter code: " + code.userCode());
}).thenAccept(session -> {
LaunchProcess process = launcher.launch("1.20.4", session,
new LaunchOptions.Builder().setRamMb(8192).build()
);
// Read game logs in real-time
process.onLogLine(line -> logger.info("[MINECRAFT] " + line));
process.onCrash(crash -> handleCrashReport(crash));
});
Rust Guide
The Rust library utilizes tokio for lightning-fast concurrent operations.
Beginner: Standard Launch
use easylauncher::{MinecraftLauncher, auth::OfflineAuth};
#[tokio::main]
async fn main() -> Result<(), Box> {
let launcher = MinecraftLauncher::new("./.minecraft");
launcher.install("1.20.4").await?;
launcher.launch("1.20.4", OfflineAuth::new("Player")).await?;
Ok(())
}
Pro: Total Customization
Hook deeply into the HTTP client to add custom headers (for reverse proxies) and fully customize the JRE resolution.
use easylauncher::{MinecraftLauncher, config::LauncherConfig};
let config = LauncherConfig::builder()
.proxy("http://localhost:8080")
.custom_jre_provider(|version| {
// Resolve JREs from a custom internal mirror
format!("https://mirror.company.com/jre/{}-linux.tar.gz", version)
})
.max_concurrent_downloads(32)
.build();
let launcher = MinecraftLauncher::with_config("./.minecraft", config);
let mut rx = launcher.install_with_channel("1.20.4").await?;
while let Some(event) = rx.recv().await {
// Process stream of high-speed download events
update_ui(event);
}