Get Started
SuperJ is a systems programming language with Java's syntax, compiled ahead-of-time to native code through LLVM. You write what looks like ordinary Java and get a single self-contained native binary — no JVM, no JIT, no garbage collector. This walk takes you from install to a running web server in a few minutes.
clang/LLVM 22.x and the other prerequisites via your platform package manager. Pass --no-deps if you prefer to manage those yourself. No JVM, no JIT, no runtime to install alongside it.Targets. macOS arm64 (kqueue), Linux x86_64 and aarch64 (epoll). The community distribution is a prebuilt tarball — no build step required.
Run the one-liner from the Download page. The installer auto-detects your platform, installs any missing dependencies (including clang/LLVM 22.x), downloads and verifies the tarball, extracts to ~/superj, and wires up SJ_HOME and PATH in your shell profile.
curl -fsSL https://superj.dev/releases/v1.3/install.sh | sh -s -- https://superj.dev/releases/v1.3
Open a new shell (or source your profile) so the new SJ_HOME/PATH take effect. Pass --no-deps to skip the dependency auto-install, or --prefix=/opt/superj to install elsewhere.
Check the version, then scaffold and run a project.
superj --version # 1.3.0 (community)
SuperJ has a Cargo-inspired build system built into the superj binary. One command scaffolds a project; two more build and run it.
superj new myapp
cd myapp
superj run # Hello from myapp
Edit src/myapp/Main.sj. It looks like Java — but arena is a keyword, and there's no GC underneath.
package myapp;
public class Main {
public static void main(String[] args) {
int total = 0;
arena scratch {
int[] rows = new int[1 << 16];
for (int i = 0; i < rows.length; i++)
total += (rows[i] = i * 3);
} // scratch dropped here — O(1), no pause
System.out.println("total = " + total);
}
}
superj run # rebuild + run
superj build --release # optimized build → target/release/myapp
superj check # whole-project type-check (no codegen/link)
superj test # run the unit-test suite
The same SDK stack that powers the 515K req/s benchmark is one handler and one main away. Compile it to a single native binary — no framework, no runtime to install alongside it.
package sj.demo;
import sj.http.*; import sj.net.*; import sj.util.ByteArray;
class HelloHandler implements HttpRequestHandler {
private final ByteArray response;
HelloHandler() {
String body = "Hello from SuperJ!\n";
this.response = new ByteArray(
"HTTP/1.1 200 OK\r\nContent-Length: "
+ body.length() + "\r\n\r\n" + body);
}
public void handle(HttpRequest r, SessionWriter w) {
this.response.rewind();
w.write(this.response);
}
}
public class WebServer {
public static void main(String[] args) {
int port = 8080;
if (args.length > 0) { port = Integer.parseInt(args[0]); }
NioConfig cfg = new NioConfig(65536, 16384, 64, 262144, true, 1024);
NioAdapter adapter = new NioAdapter(cfg);
adapter.open("127.0.0.1", port, new HttpSessionProvider(new HelloHandler()));
System.out.println("listening on http://127.0.0.1:" + port + "/");
while (true) { adapter.poll(0); }
}
}
superj compile sj/demo/WebServer.sj --sdk-path "$SJ_HOME/sdk" --link --output webserver
./webserver 8080
# in another terminal:
curl http://127.0.0.1:8080/ # → Hello from SuperJ!
Single-threaded doesn't mean single-core. The true in NioConfig is reusePort — run several copies on the same port and the kernel balances incoming connections across them. No code change.
for i in 1 2 3 4; do ./webserver 8080 & done