Skip to content

Quickstart

Gustavo Malvestiti edited this page Aug 16, 2026 · 1 revision

The three terminal builder methods correspond to three threading models:

Method Thread safety Best fit
create() Caller's thread only Regular single-threaded config
createAsync() Safe from any thread Shared or background access
createImmutable() Read-only, safe from any thread Config that never mutates at runtime

Declare the config class. Fields must be public, initialized to their defaults, and the class must have a public no-argument constructor.

@Config(name = "mymod") // format defaults to JSON5
public final class MyModConfig {
    public boolean showHints = true;
    public int hudScale = 2;
}

or for TOML:

@Config(name = "mymod", format = ConfigFormat.TOML)
public final class MyModConfig {
    public boolean showHints = true;
    public int hudScale = 2;
}

Create the holder once during mod initialization and keep it for the lifetime of the mod. create() resolves the file path, validates the model, loads any existing file (or writes the defaults if none exists), and validates the loaded state — the holder is ready to read immediately after it returns:

public final class MyMod implements ModInitializer {

    public static final ConfigHolder<MyModConfig> CONFIG = EasyConfig.holder(MyModConfig.class)
        .modId("mymod")
        .create();
}

Read through data(), mutate through update / updateAndSave:

if (MyMod.CONFIG.data().showHints) {
    // ...
}

MyMod.CONFIG.updateAndSave(config -> config.hudScale = 3);

That writes config/mymod.json5:

{
  "showHints": true,
  "hudScale": 3
}

Clone this wiki locally