Community listing page, reviews here may not be monitored by the author.
FerricOxide
No reviews yet
Native WebView UI for Minecraft, driven by Rust.
Neoforge is a fork of the Minecraft Forge available for versions 1.20.1+ of Minecraft. Many Forge mods are compatible with Neoforge and vice versa.
Community voices
Reviews
Filters
Click once to include, again to exclude, again to clear
No reviews yet. Be the first to review this project!
Get it on
Available Platforms
About
Project Details
For authors
Embed Badge
If you're the author of this project, you can embed a live badge anywhere that supports HTML or Markdown. It updates automatically whenever ratings change.
Use HTML for any page that supports it, or Markdown for README files and Markdown-based descriptions.
Identifiers
Platform IDs
Resources
External Links
About
Description

FerricOxide
Native WebView UI for Minecraft, driven by Rust.
FerricOxide renders modern web UI (HTML/CSS/JS) inside Minecraft by calling the operating system's native WebView through a thin Rust JNI bridge — no bundled browser engines, no embedded Chromium. It is a lightweight, high-performance, cross-platform GUI foundation for Minecraft mod developers.
Preview

How it works
┌─────────────────────────── Minecraft (Java) ───────────────────────────┐
│ WebUi (public API) ──► NativeWebView (JNI stubs) │
└───────────────────────────────────┬────────────────────────────────────┘
│ JNI calls (fire-and-forget commands)
┌─────────────────────────── Rust (cdylib) ─────────────────────────────┐
│ ferric_oxide_native: jni + wry + tao │
│ dedicated event-loop thread owns every WebView/window │
└───────────────────────────────────┬────────────────────────────────────┘
│ OS native WebView
Windows: WebView2 (Chromium) │ macOS: WKWebView Linux: WebKitGTK
- Java exposes a small, mod-developer-friendly API (
WebUi), backed by thin JNI stubs (NativeWebView). - Rust (
rust/, crateferric_oxide_native) useswryto drive the platform's native WebView. All window/WebView work happens on one dedicated event-loop thread; JNI calls become messages sent through anEventLoopProxy, so no game thread is ever blocked. - Embedding: on Windows the WebView is created as an HWND child of the Minecraft window
(
WebViewBuilder::build_as_child), so the web UI is pinned to the game window and follows its size. Other platforms currently fall back to a standalone window. - Two-way bridge: events and queries flow in both directions over one JSON protocol.
Java uses
WebUi.bridge(), the page usesferric.emit / on / call / handle— the runtime is injected before any page script, so no feature detection is needed. Seedocs/webui-bridge.md.
Requirements
- Minecraft / NeoForge dev environment (see
gradle.propertiesfor the pinned versions) - JDK 25
- Rust toolchain (
cargo, stable) — needed to build the native library locally - Node.js 22+ — runs the page-side bridge tests during
./gradlew check - Windows: WebView2 Runtime (preinstalled on Windows 11 / modern Edge)
- Linux: WebKitGTK 4.1 and D-Bus runtime libraries (for example,
libwebkit2gtk-4.1-0andlibdbus-1-3on Ubuntu)
Building
./gradlew build
A normal local build invokes cargo build --release via the buildRustNative task, copies the
host library into the jar at natives/<platform>/<arch>/..., and configures dev runs with the
ferricoxide.native.path system property. The NativeLoader first honours that property and
otherwise extracts the matching library from the mod jar at runtime.
The reusable GitHub Actions build compiles these eight native targets in parallel and packages them into one mod JAR:
| Platform | Rust target | JAR resource |
|---|---|---|
| Windows x86 | i686-pc-windows-msvc |
natives/windows/x86/ferric_oxide_native.dll |
| Windows x86_64 | x86_64-pc-windows-msvc |
natives/windows/x86_64/ferric_oxide_native.dll |
| Windows aarch64 | aarch64-pc-windows-msvc |
natives/windows/aarch64/ferric_oxide_native.dll |
| Linux x86 | i686-unknown-linux-gnu |
natives/linux/x86/libferric_oxide_native.so |
| Linux x86_64 | x86_64-unknown-linux-gnu |
natives/linux/x86_64/libferric_oxide_native.so |
| Linux aarch64 | aarch64-unknown-linux-gnu |
natives/linux/aarch64/libferric_oxide_native.so |
| macOS x86_64 | x86_64-apple-darwin |
natives/macos/x86_64/libferric_oxide_native.dylib |
| macOS aarch64 | aarch64-apple-darwin |
natives/macos/aarch64/libferric_oxide_native.dylib |
The packaging job supplies the merged resource directory with
-PprebuiltNativesDir=/path/to/natives. In this mode Gradle copies every prebuilt native and
does not run Cargo; without the property, local and development-run behavior remains unchanged.
CI versions and publishing
The baseline version is mod_version in gradle.properties. CI passes an override to Gradle, so
the JAR filename and the embedded NeoForge metadata always carry the same version:
- A push that changes build inputs on
releases/**publishes an alpha to Modrinth and CurseForge as<mod_version>+build.<GitHub run number>, for example0.0.1+build.123. - Pushing a
v<mod_version>tag, for examplev0.0.1, validates that it exactly matchesgradle.properties, then publishes a stable release to Modrinth, CurseForge, and GitHub. - Pull requests only run the eight-target build and test checks; they cannot publish.
Repository secrets required for publishing are MODRINTH_TOKEN and CURSEFORGE_TOKEN. The
workflow fails visibly if either platform rejects an upload; it never silently skips a release.
The x86 libraries are built and packaged for completeness, but current Minecraft, JDK 25, and LWJGL distributions generally do not provide a complete 32-bit runtime. Loading an x86 native still requires an x86 JVM and an otherwise architecture-compatible game environment. Packaging the Linux libraries also does not bundle their WebKitGTK, GTK, or D-Bus system dependencies.
Using the API
Java side — payloads are plain records, converted with Gson:
import dev.anvilcraft.oxide.ferric.webui.WebUi;
record Clicked(int value) {}
record Data(int foo) {}
record PlayerInfo(String name, float health) {}
// Load your page from the mod's assets, embed it into the Minecraft window:
WebUi ui = WebUi.embedded(
"My Mod UI", "my_mod", "webui/index.html",
minecraft.getWindow().getWidth(),
minecraft.getWindow().getHeight()
);
ui.bridge()
// JS -> Java event (handlers always run on the render thread):
.on("my_mod.clicked", Clicked.class, clicked -> doSomething(clicked.value()))
// JS -> Java query — whatever you return is sent back to the page:
.handle("my_mod.player", Void.class, ignored -> new PlayerInfo("Steve", 20.0F));
// Java -> JS event:
ui.bridge().emit("my_mod.data", new Data(42));
// Java -> JS query:
ui.bridge().call("my_mod.form", null, FormValues.class).thenAccept(this::save);
// WebUi is AutoCloseable; close() destroys the native window (also reclaimed by GC).
ui.close();
Page side — the mirror image, no setup required:
ferric.emit('my_mod.clicked', {value: 42});
const player = await ferric.call('my_mod.player');
ferric.on('my_mod.data', (data) => render(data.foo));
ferric.handle('my_mod.form', () => collectFormValues());
// Game resources, without worrying about the platform's URL scheme:
img.src = ferric.resource('item/minecraft:apple', {size: 48});
Open a standalone (non-embedded) window with WebUi.window(...) instead. The raw lower-level
API (NativeWebView.Builder, MessageHandler, CreationCallback) is available under
dev.anvilcraft.oxide.ferric.webui for advanced use.
Demo
Run /ferric ui demo in-game to open the bundled demo UI. It exercises every direction of the
bridge: it pings the game chat (JS event), queries the player's name and health with
Who am I? (JS query), receives the world time once per second and rendered entity frames
(Java events). Press Esc in the WebView to close it and return mouse control to Minecraft.
Set FERRICOXIDE_AUTO_OPEN=1 to open the demo UI automatically after launch (used for
smoke-testing).
Project layout
rust/ Native JNI bridge (wry + tao + jni)
src/lib.rs JNI entry points, event-loop thread, embedded/standalone WebViews
src/main/java/dev/anvilcraft/oxide/ferric/
FerricOxide.java Mod entry point
client/FerricOxideClient.java Client command + demo UI wiring
webui/WebUi.java Public high-level API
webui/NativeWebView.java Low-level JNI wrapper
webui/NativeLoader.java Library loading (system property / jar extraction)
webui/bridge/ Two-way event/query bridge (WebBridge + protocol)
src/main/resources/assets/ferric_oxide/webui/
bridge.js Page-side bridge runtime (injected before page scripts)
demo.html Demo page
src/test/java/ JUnit tests for the Java bridge half
src/test/js/bridge.test.js Node tests for the page-side bridge half
docs/webui-bridge.md Bridge protocol and API design
License
GNU LGPL 3.0
Screenshots
Gallery
Versions
Files
Relations
Project Relations
More like this
Similar Mods
Suggestions use data such as tags, dependencies, dependents, descriptions, titles, and more to rank how much they overlap with this mod.
On ModDex
Community snapshot
By the numbers
Statistics
Want to reach Minecraft players?
We're looking for a server hosting partner to feature here and other parts of the site. Interested? Send us a message!
Get in touchGet it on
Available Platforms
On ModDex
Community snapshot
By the numbers
Statistics
Resources