Developer guide
This guide is for you if you want to build njMule from its sources, change it, translate it, package it or drive it from your own programs through its remote-control API. If you only want to use njMule, the user guide is the place to start.
njMule is a Java 25 re-implementation of eMule's networks (eD2K and Kad 2), compatible with the
eMule network and licensed under the GPL 3.0 or later. One engine without any user interface
(njmule-core) runs as a GraalVM native executable that is also the command line. One interface
(njmule-ui), written for the browser, drives it only through its remote-control API: in the
desktop window, a small Tauri shell that starts the engine, and as the web interface the engine
serves.
Technology stack
| Area | What njMule uses |
|---|---|
| Language and build | Java 25 (JPMS modules), Gradle through the Gradle Wrapper, a convention plugin of its own in build-logic/ |
| Engine | virtual threads, Bouncy Castle, Guava, Jackson 3, Eclipse Jetty 12 (HTTP client and server), Kwik (QUIC), Angus Mail (e-mail notifications), semver4j, Apache Commons Compress and XZ for Java (update packages) |
| Remote-control API | an OpenAPI 3.2 document, validated with the networknt JSON Schema validator, served by Jetty |
| Command line and logging | picocli, SLF4J with Logback |
| Interface | Vue 3 in TypeScript, built with Vite; Reka UI, TanStack Table and TanStack Virtual; openapi-typescript and openapi-fetch for the API, eventsource-parser for its events; its own SVG line icons and the colours of the AtlantaFX themes |
| Desktop window | Tauri 2 in Rust, with its single-instance, deep-link, dialog, opener, window-state and notification plugins |
| Web interface | Jetty, with a login page, sessions and form tokens, serving the interface and the API |
| Native executables | GraalVM Community Native Image 25.0.4.1.1 (native-image); a small C service host on Windows |
| Tests | JUnit (Jupiter) with AssertJ, jqwik for property-based tests, Jimfs, openapi-parser; Vitest with happy-dom for the interface; cargo test for the desktop window |
| Quality gates | Spotless with palantir-java-format, Checkstyle, Error Prone, JaCoCo, SpotBugs with FindSecBugs, SonarQube Cloud; Prettier and vue-tsc for the interface; cargo fmt and Clippy for the desktop window |
| Packages | WiX 5 (Windows MSI), nfpm (deb and rpm), codesign and hdiutil (macOS), a shell script for the Synology package, Docker |
| Documentation | Docusaurus 3.10 with the OpenAPI docs plugin; its screenshots taken with Playwright |
Every library and plugin version of the Java build lives in one file,
gradle/libs.versions.toml;
the npm packages and the Rust crates are pinned in their own lock files: see
Dependencies.
Repository layout
| Path | Content |
|---|---|
njmule-core (module org.njmule.core) | the engine: protocols, files, persistence, networking, and the remote-control API; no dependency on any interface |
njmule-app (module org.njmule.app) | the headless launcher and command line, the Logback set-up, the Windows service commands and their service host |
njmule-ui | the interface of the desktop window and of the web interface (Vue 3, TypeScript, Vite), with its translations (i18n/) and country flags (flags/) |
njmule-desktop | the desktop window: a Tauri 2 shell in Rust (src-tauri/) that starts the engine and shows the interface |
njmule-http (module org.njmule.http) | the web interface on Jetty (password, sessions, form tokens), which serves the interface and the core's remote-control API, and the desktop window's control endpoint |
njmule-testkit (module org.njmule.testkit) | test doubles shared by the modules (a fake server, a fake peer, free ports) and the end-to-end tests |
njmule-bench | JMH benchmarks; a classpath build so that it reaches internal core packages; never distributed |
website | this documentation site (Docusaurus): docs/ is the user guide, developer/ this guide |
build-logic/ | the Gradle convention plugin every Java module applies (njmule.java-conventions) |
gradle/ | libs.versions.toml, verification-metadata.xml and the Gradle Wrapper |
config/ | the license header, the Checkstyle and SpotBugs configuration |
packaging/ | Windows installer (WiX), Linux packages (nfpm), macOS bundle metadata, Docker image, Synology package |
branding/ | original artwork: the master SVG and the PNG, ICO and ICNS files made from it |
tools/ | single-file helper programs (icons, flags, translations, update information) and Docker build scripts |
.github/ | the CI, release and documentation workflows, Dependabot, issue and pull request templates |
LICENSES/ | the texts of every license used in the repository (REUSE) |
What each module exports
The Java modules expose only what their module-info.java exports:
org.njmule.coreexportsorg.njmule.core.api(the engine facade, events and application information),org.njmule.core.config(preferences and directory layout) andorg.njmule.core.remote(the remote-control API, which a front end serves on its HTTP server). Everything else is internal; a few codec packages andorg.njmule.core.persist(the preferences as the profile keeps them) are exported toorg.njmule.testkitonly.org.njmule.appexportsorg.njmule.appandorg.njmule.app.logging, and provides njMule's Logback configurator;org.njmule.app.logging.internalis not exported.org.njmule.httpexportsorg.njmule.http.org.njmule.testkitexportsorg.njmule.testkit.
njmule-bench is not a module, and njmule-ui, njmule-desktop and website are not Java
projects.
Where to start
- Build njMule and run it from the build.
- Read the code style and the testing rules: every change keeps to them, and the build checks most of them.
- Read Contributing before you open a pull request.
- Pick the page of the area you work on: the interface, translations, native images, packaging, releases, benchmarks or this documentation.
- To drive njMule from a script or another program, read the remote-control API.