Skip to main content
Essential Loader is split into multiple stages where earlier stages are generally harder to upgrade and must therefore be less complex. This architecture enables safe auto-updates while maintaining backward compatibility.

Architecture Overview

Each stage has a specific purpose and complexity level:
  • Stage 0: Minimal, rarely updated bootstrap
  • Stage 1: Simple update orchestration
  • Stage 2: Complex loading logic with auto-updates
  • Stage 3: The actual mod (e.g., Essential)

Stage 0: Bootstrap

The “zero-th” stage is what mods bundle into their jar directly. It’s the entry point for Essential Loader.
Stage 0 can never be reliably updated because there could always be a mod with an older version that gets loaded first (especially on LaunchWrapper).

Responsibilities

Stage 0 has a single, focused responsibility:
  1. Look through all stage1 jars visible on the classpath and at predetermined file locations
  2. Pick the latest version
  3. Extract it to a specific file location if necessary
  4. Transfer execution to it by loading it via a plain URLClassLoader
This minimal scope allows stage1 to be updated either because:
  • A mod bundles a newer version
  • A later stage downloads an update to the predetermined location

Platform Implementations

On LaunchWrapper, stage0 is implemented as a simple Tweaker class that forwards all tweaker methods to stage1.Third-party mods may use it either by:
  • Specifying it as the TweakClass in the modjar’s manifest directly
  • Extending it with their own tweaker class
Relocation: Safe to relocate, but there are no direct advantages to doing so.

Relocation Guidelines

When relocating stage0, the bundled stage1 jar file MUST NOT be relocated. It must remain at a fixed location so all stage0 instances can discover it.
Each stage0 includes a stage1 jar which it will load (unless it found a more recent one). The stage1 jar must remain discoverable by all stage0 instances at the same fixed location in each jar.

Stage 1: Update Manager

The first stage handles update orchestration and platform-specific compatibility.

Core Responsibilities

Stage 1’s workflow:
  1. Check for updates for stage2
  2. Download the latest version if not already present (full download, no diffs)
  3. Load stage2 and transfer execution
Currently distributed exclusively as part of stage0, but may be distributed in other ways in the future if needed.

Singleton Enforcement

Unless noted otherwise in the platform section, stage1 ensures that stage2 is only loaded once per boot, not once per stage0 instance (there may be multiple if they were relocated).

Platform-Specific Behavior

On LaunchWrapper, stage1 is even simpler:
  • The stage2 jar file is embedded in the stage1 jar
  • No update checks or downloads
  • Simply extracts and jumps to stage2
Stage1 used to do much more on LaunchWrapper, but this functionality has since been moved to stage2.

Stage 2: Heavy Lifting

The second stage is where all the complex work happens. This is the most sophisticated component of Essential Loader.

Core Features

  • Checks for updates with configurable branch support (e.g., stable, beta, staging)
  • Downloads updates efficiently using diffs when a previous version is available
  • Displays a fancy progress popup during downloads
  • Can receive auto-updates by default for quick fixes
  • Loads downloaded mods via the native mod loader
  • Makes the dynamic loading process transparent to the mod itself
  • Handles platform-specific loading quirks
Houses the vast majority of ugly hacks required to make everything work. These can be fairly fragile, which is why they’re in stage2 where auto-updates can fix issues quickly without user intervention.

Distribution

Currently distributed exclusively via Essential’s mods API under the slug essential:loader-stage2.
May be pre-bundled into stage0 in the future to allow for offline use or environments where auto-updates are strongly discouraged (such as large modpacks).

Platform Details

See the Platforms documentation for detailed information on what stage2 does on each platform.

Stage 3: Your Mod

This is the mod (currently always Essential) that gets loaded by stage2. It does not live in the essential-loader repository.
Usually not called “stage3” unless directly compared with the other stages. It’s just your regular mod.

Platform-Specific Initialization

Once loaded, stage2 calls:
gg.essential.api.tweaker.EssentialTweaker.initialize
Which in turn calls:
gg.essential.main.Bootstrap.initialize
This adds:
  • Mixin exclusions
  • Mixin configs
  • Mixin error handler
  • LaunchWrapper transformers to fix bugs in third-party mods

Design Goals

Currently stage2 makes some assumptions about the loaded mod. Long-term, it should ideally be able to load any regular mod that could be loaded on the host mod loader, in the same way one would without auto-updating.

Why This Architecture?

The multi-stage design solves several critical challenges:
  1. Update Safety: Earlier stages are simpler and less likely to break, while later stages can auto-update
  2. Platform Independence: Each stage can adapt to platform-specific requirements
  3. Backward Compatibility: Old stage0 instances can still discover and use newer stage1/stage2 versions
  4. Offline Support: Pinned versions allow operation without update servers
  5. Developer Flexibility: Mods can customize update behavior while inheriting the core loader functionality
The stage architecture is inspired by similar patterns in bootloaders and operating system initialization, adapted for the unique constraints of Minecraft mod loading.

Build docs developers (and LLMs) love