CheerpJ is a WebAssembly-based JVM that runs fully client side in the browser. It supports Java applications, legacy applets and libraries, with no need for compilation, server backends, plugins, or post-processing steps.
CheerpJ was originally released in 2017, quickly becoming Leaning Technologies’ most widely known and successful product. In the last six years, we collected a vast amount of feedback from users that led us to perform a full rewrite of CheerpJ, which we announced in May.
CheerpJ 3.0 introduces a completely new JIT-based architecture which makes the tool faster, more usable and much more powerful. CheerpJ 3.0 was released in January 2024, with support for Java 8. Thanks to its new runtime architecture, subsequent releases of CheerpJ will expand its support to more recent LTS releases of Java, starting from Java 11.
What can CheerpJ do?
<script> tag. It requires no custom executable component, plugin, or server-side backend.
It exposes a simple API for executing standalone Java applications, applets, Java Web Starts, and Java libraries - entirely in the browser.
Being a collection of static assets, it is easily self-hostable, and we provide a cloud version under the CheerpJ Community Licence (free to use for personal projects and technical evaluations).
No modifications needed
CheerpJ can run unmodified Java applications, applets and libraries from JAR files. It does not require access to the source code, or specialized compile-time tools. This is especially useful when running legacy applications, whose source code might not be available, or applications based on 3rd party commercial libraries.
Developers can use their existing JAR files with no changes to your building process. Obfuscated and minimized artifacts are fully supported .
CheerpJ can run extremely large and complex applications: we recently stress-tested it on IntelliJ IDEA 2019, which ships ~400MB of JAR files.
Full Java support
CheerpJ supports multiple processes and threads. It can run a single or multiple independent Java applications, each consisting of multiple threads. Synchronization features are supported.
CheerpJ provides full support for ClassLoaders. Java classes are loaded following the same approach as native Java implementations. The correct ClassLoader is invoked, depending on the current execution context, which internally resolves the correct Java bytecode using arbitrary logic. User-provided ClassLoaders are also supported, including customs ones implementing encryption or obfuscation.
Reflective access to methods and fields is achieved via metadata provided by Java bytecode. After a ClassLoader resolves the bytecode CheerpJ will store it not only for the purpose of running and compiling Java code, but also to implement reflection. Annotations are also supported.
Extensive runtime and system access
CheerpJ provides a completely unmodified build of OpenJDK. Specifically, the most recent OpenJDK 8 revision. The architecture is designed to support multiple versions of Java, as well as custom runtimes. Future versions of CheerpJ will support Java 11, and newer LTS Java versions.
Graphical applications, including Swing and AWT are supported. Swing ones, being platform independent, will render exactly as they do in native. Swing Look&Feel is also supported, including 3rd party ones. Multi-window applications are supported, with keyboard focus being managed as expected. Integration with the system clipboard can be enabled via an initialization option.
How does CheerpJ 3.0 work?
The CheerpJ 3.0 architecture was engineered to solve the limitations present in CheerpJ 2.x and to take advantage of the unique experience about in-browser JIT-ting that we gathered from our work on CheerpX: a WebAssembly-based virtual machine for x86 binary code.
At a high level, CheerpJ is composed of the following building blocks:
- A virtualized window manager: Which supports AWT/Swing. Each window is converted to a hierarchy of HTML elements and HTML5 canvases.
- A virtualized File System: CheepJ provides multiple filesystem backends to accommodate different application needs, including access to server-hosted files and persistent local storage.
- Networking support: For same-origin HTTP/HTTPS requests, CheerpJ will be able to transparently use
fetch. More generalized networking is supported via Tailscale, a VPN technology using WebSockets as a transport layer. It can support many different networking scenarios, including access to private network services, peer-to-peer connections between users and access to the wider internet via a user/application provided exit node.
How does this compare to CheerpJ 2.x?
When designing the new CheerpJ 3.0 architecture, we had the objective of making a drop-in replacement for CheerpJ 2.3. With some minor exceptions (improved APIs that led to some others being removed), this objective was achieved.
Important information for CheerpJ 2.x users
If you used CheerpJ 2.x in the past, these are the most significant changes you should be aware of:
- No Ahead-Of-Time compilation: To achieve good performance, CheerpJ required you to post-process JAR files with a custom binary compiler. The compiler would generate a
.jar.jsfiles for each input JAR. CheerpJ 3.0 features an advanced JIT engine that can, even in this first release, generate better-performing code than CheerpJ 2.3 ever could. Removal of
.jar.jsfiles also significantly decreases how much data needs to be downloaded during application startup.
- Actual support for ClassLoaders: CheerpJ 2.3 had very limited support for ClassLoaders. As a consequence of requiring AOT compilation of
.jar.jsfiles, it could only support the standard one provided by OpenJDK. CheerpJ 3.0 radically improves the status-quo by properly using ClassLoaders as expected by Java.
- Breaking changes
- The API is not exposed until
cheerpjInitis called and its Promise resolves.
- Removal of specialized
importScriptsto include the CheerpJ 3.0 loader. Full applications can now be run within Workers, as well as libraries in library mode to offload computation workloads.
- Removal of
cheerpjRunJarWithClasspath: When using
java -jar, the JAR file is the source of all user classes, and any other class path settings are ignored - so this API was not very useful.
- Removal of the CheerpJ-DOM Java API: When we first released CheerpJ we planned on providing full access to the DOM APIs directly from Java, but the feature was never complete. We have removed this API in favor of the new
nativefeature, which makes it possible for third party libraries to implement something similar to the legacy CheerpJ-DOM in a more robust manner. A viable solution was already contributed by one of our users.
- The API is not exposed until
Library mode: A new way of using Java libraries in web apps
To illustrate this new feature a code snippet is worth a thousand words.
The new library mode API is also used for
native is effectively just a shorter library mode session.
What can I do with CheerpJ?
You might be wondering what use cases can CheerpJ support:
- Modernization of enterprise software: This includes Oracle Forms, EBS and similar Java based enterprise solutions, that are still widely used in Enterprise settings.
- Building Web Applications with Java libraries: CheerpJ can bring the power of Java libraries to Web apps. Thanks to library mode, Java libraries can now be integrated in Web applications via CheerpJ, rather than requiring a server-side component to run them.
- Fully client-side Java development environments and playgrounds: The
javaccompiler is itself written in Java and can run with CheerpJ. We showcase this in our JavaFiddle playground and the full source code is available if you want to delve deeper.
For further inspiration, take a look at what our community has already built.
CheerpJ is free to use for personal projects, including those that generate revenue, and for technical evaluations. An overview of licensing is available here.
What’s next for CheerpJ?
CheerpJ 3.0 is the most advanced solution for running large-scale Java applications in the browser.
We are very proud of what we have achieved, nevertheless there are currently some limitations that our users should be aware of:
- Java 8 only: The new CheerpJ 3.0 architecture is engineered to fix the gap with modern Java versions quite easily. We target supporting Java 11 (and possibly more) with the future CheerpJ 3.1 release. The architecture makes it possible to build specific past revisions for customers that have requirements from either dependencies or certifications.
- No support for third-party JNI components: There are a few large scale Java apps that cannot run in CheerpJ at this time since they depend on binary libraries. The most notable of these is Minecraft, which uses LWJGL. In the future we plan to release our JNI implementation to the public, allowing users to build their own WebAssembly JNI modules from C/C++.
- WasmGC support: The most keen reader might be wondering how the recently standardized WasmGC extension to WebAssembly impacts our work. As things stand we don’t think WasmGC will be necessary to reach a satisfactory level of performance, but it’s possible that our evaluation will change in the future. In any case, if CheerpJ will eventually introduce WasmGC as a JIT target, it will be a purely internal implementation detail. From the point of view of the user nothing will change besides a performance improvement.
You can use CheerpJ by simply adding a script tag to any HTML page:
For additional information please refer to our fully revamped documentation.
CheerpJ is a product built with passion by our talented team in Amsterdam (NL) and Leeds (UK). Try it out and let us know what you think!