It does all of this work for you and its a standard tool that dumps out a platform specific application bundle.
The only people living in 2010 are the ones that choose to live there with incredibly outdated takes on things they dont understand.
Even Eclipse and Intellij ship openjdk based runtimes with their distributions and have even stricter GPL limits.
An app bundle (.app, .rpm, .deb, .msi/.exe etc.) are things jpackage can build for you and are a single shippable artifact for a user with a JRE included so they don't need to do that. It's designed to make it easy to ship Java applications around.
If you want a fully statically linked binary you're diving into graalvm and native-image: https://www.graalvm.org/latest/reference-manual/native-image.... This will give you what you want which is basically something you can wget and chmod +x.
Write once, run everywhere.
Or use a graal to build a native-image and ship that around.
But that's not what people want. They want an .exe or a .app, or .rpm, or whatever. That's a container for holding that .jar and it is platform specific and there is no workaround to that problem.
No more FreeBSD, Solaris, open Solaris (illumos smartos etc).
https://github.com/psumbera/solaris-openjdk seem to work?
Pretty sure many other runtimes aren't exactly supported on all platforms by single vendor/projects?
So will we see python stop being used?
No, because instead of sitting in corner and mope about it the ecosystem just kept working and filling in the gaps.
Java ecosystems done lot of that - but general public keep having the old changes stuck in their mind.
Lets change that :)
Most devs have npm installed always, I don't like it but its effective at delivering software to my development environment.
and yes, works on npm, uvx, etc. too.
`npx @jbangdev/jbang`
Python packaging has always been painful and it’s a popular option for CLI regardless.
I don’t think there only rational explanations, technology choices are a lot about culture and dogmas too.
The JVM installs cleanly and is self contained, but any artifacts, by default, are not shared system wide as this _always_ have been seen as a security risk. The hot term for it today is "supply chain attack".
Instead, most Java programs tow their dependencies, giving it a bloated feel because its all just there, present in front of you, stored and running as your own user.
jbang is to java, what uv(x) is to python and what npm/npmx is to javascript.
A single executable is always just one "pyinstaller --onefile --noconsole main.py" away.
Understandably so, given that some Java runtimes (most notably, Oracle's) require a paid license for commercial use. Having users installing that can get the company in hot water.
Or do what the rest of the world does, use Eclipse Adoptium (the best JDK in my opinion) or the one from OpenJDK, Microsoft, etc.
You and the parent raising the specter of Oracle's Java licensing isn't applicable any more. It isn't 2009.
Type the following prompt into any AI and feel free to argue your point with the AI: "what does jbang solve?"
My text editor, KeenWrite[1], offered binaries for Linux, macOS, and Windows. The Windows binary was axed due code signing costs and requiring third-party builds, rather than any technical issues with cross-platform packaging.
One way is to create self-extracting executable binaries using a tool such as warp[2]. I've built an installer script[3] (install.sh) to create platform-specific launchers. Running `time keenwrite.bin --version` on Linux shows 0.327s; after the first run, subsequent launches are quick.
[2]: https://github.com/kirbylink/warp
[3]: https://repo.autonoma.ca/?action=repo&repo=keenwrite.git&vie...
They've kept it alive, allowed it to grow, and innovate, even let Green threads back in.
I'm not planning on going back to Java, but that's no longer because Oracle.
Heh, I find this very amusing and ironic, seeing how Write Once Run Anywhere was a stated goal with Java, that failed miserably.
For that use case, was it active content, was it shipping intermediate representation, was it a sandbox? To all three: yes, very poorly.
It's not dynamic linking, despite excellent support for very late binding in historic Java versions. (Newer versions require specific launcher configurations to use certain platform features, which breaks late loading of classes that use those features.)
GraalVM native image allows doing exactly that. Should be as easy as adding a single gradle plugin
I haven't really had the burning need for app+jvm since I used graalvm and made jbang and its now trivial to run app + shared jvm for me - but I can see the utility for it.
Noted down the various pointers and existing attempt to explore in 2026 !
About build and publishing - this I feel is also solvable.
Especially if we stop trying to solve it for all possible mutations of gradle/maven builds and just make it work for jars...this is where jbang/jreleaser really simplifies more than I think many realize.
So in 2026 I'll definitely try get more recipes published on this and also see if we can make something like `jbang publish` "Just Work"
I really think that this aligns with the “paving the on ramp” type of stuff. Making the build tooling first class and simple will help adoption.
For end-user apps, this is basically solved: use jpackage to ship an installable app with a bundled, trimmed JRE. Better yet, distribute via the OS app store so updates are handled for you (on Linux, Flatpak is probably the right answer today).
For CLI tools, you’re already assuming a more technical audience. At that point you have two real options:
- ship everything bundled (Go/Rust static binaries, pyinstaller, jpackage)
- ship just the app and rely on a smart launcher/runtime manager (npx, bunx, uvx, jbang), and assume your technical audience can install that first
The real question isn’t "is it a single binary?", it’s "how do users install, run, and update it?". In practice, that’s already been solved by developer package managers like brew and scoop. All the Go and Rust CLIs on my machine are installed via brew, not manually downloaded from GitHub releases.
You also want CLIs on PATH or inside a dev environment (mise, direnv, etc.), so whether that executable is a true single binary or a symlink to a bundle is mostly irrelevant.
So the trade-off becomes, do you support `brew install foo-java-tool` with a bundled JRE, or do you ask users to `brew install jbang` and then `jbang install foo-tool`? Either way, the end result is the same, you run `foo-tool`.
Note, Claude Code for instance supports both options (curl | bash, brew cask, and npm -i), isn't a single binary, and that still hasn't stopped it from being the most popular CLI tool released this/last year.
There’s definitely room for improvement in Java’s packaging story, I just think the focus shouldn’t be on "single binary" as the primary goal.
Java on the other hand makes it impossible to get a single distributable. There is no way to get your jar + the vm into a binary. You could use graal native image, but build times are super slow, use too many resources, and it’s non-trivial to get working.
Build tooling in the Java ecosystem just isn’t good enough.