Rhino: JavaScript in Java
Rhino is an implementation of JavaScript in Java.
License
Rhino is licensed under the MPL 2.0.
Summary
Rhino requires Java 17 or higher to run, and 21 or higher to build. Java 25 is highly recommended.
To build and run a Rhino shell:
./gradlew run -q --console=plain
To run the tests:
git submodule init git submodule update ./gradlew check
Releases
The current release is Rhino 1.9.1. Please see the Release Notes.
Releases
Rhino 1.9.1 February 15, 2026 Rhino 1.9.0 December 22, 2025 Rhino 1.8.1 December 2, 2025 Rhino 1.8.0 January 2, 2025 Rhino 1.7.15 May 3, 2024 Rhino 1.7.14 January 6, 2022 Rhino 1.7.13 September 2, 2020 Rhino 1.7.12 January 13, 2020 Rhino 1.7.11 May 30, 2019 Rhino 1.7.10 April 9, 2018 Rhino 1.7.9 March 15, 2018 Rhino 1.7.8 January 22, 2018 Rhino 1.7.7.2 August 24, 2017 Rhino 1.7.7.1 February 2, 2016 Rhino 1.7.7 June 17, 2015 Rhino 1.7.6 April 15, 2015 Rhino 1.7R5 January 29, 2015
Compatibility table which shows which advanced JavaScript features from ES6, and ES2016+ are implemented in Rhino.
Documentation
Information for script builders and embedders:
Code Structure
Rhino 1.7.15 and before were primarily used in a single JAR called "rhino.jar".
Newer releases now organize the code using Java modules. There are four primary modules and one auxiliary module for Kotlin developers:
rhino: The primary codebase necessary and sufficient to run JavaScript code. Required by everything that uses Rhino. In releases after* 1.7.15, this module does not contain the "tools" or the XML implementation.
- rhino-tools: Contains the shell, debugger, and the "Global" object, which many tests and other Rhino-based tools use. Note that adding Global gives Rhino the ability to print to stdout, open files, and do other things that may be considered dangerous in a sensitive environment, so it only makes sense to include if you will use it.
- rhino-xml: Adds the implementation of the E4X XML standard. Only required if you are using that.
- rhino-kotlin: Enhanced support for code written in Kotlin, see the details.
- tests: The tests that depend on all of Rhino and also the external tests, including the Mozilla legacy test scripts and the test262 tests.
- it-android: Integration tests for android, see the details.
- benchmarks: Runs benchmarks using JMH.
- examples: Surprisingly, this contains example code.
Recommendations
All applications that embed rhino need the main "rhino" module. Many applications don't need anything else -- consider doing the same, for a few reasons:
- While "rhino-engine" implements the Java ScriptEngine interface, this is a strange
- "rhino-tools" includes the Global module, which many tools use because it includes
Building
Requirements
It's recommended to build Rhino using Java 25. However, it will build with Java 17 and up. The "spotless" tool, which enforces code formatting, will not run on older Java versions -- it will emit a warning.
Rhino runs on Java 17 and higher. The build tools use the "--release" flag to ensure that only features from Java 17 are used in the product.
The CI tools run the Rhino tests on Java 17, 21, and 25. Regardless of what version of Java you are building with, you can test on another Java version using the RHINO_TEST_JAVA_VERSION environment variable.
The "production" builds of Rhino build using Gradle, but on Linux and Mac you can also build Gradle using Bazel.
How to Build
For normal development, you can build the code, run the static checks, and run all the tests like this:
git submodule init git submodule update ./gradlew check
To just run the Rhino shell, you can do this from the top-level directory:
./gradlew run -q --console=plain
Alternately, you can build an all-in-one JAR and run that:
./gradlew shadowJar java -jar rhino-all/build/libs/rhino-all-2.0.0-SNAPSHOT.jar
And finally, you can extract the classpath and use it in a variety of ways:
export CLASSPATH=$(./gradlew -q printClasspath) java org.mozilla.javascript.tools.shell.Main
Optional Bazel Build
Building with Bazel instead of Gradle gives you a few advantages:
- Bazel caches very aggressively which saves time the more you use it
- You can use a hosted build service and run your build in parallell on a few, or a dozen, machines. In this way you can run the tests in only a few minutes.
To build with Bazel:
- At the very least you will need a Java 25 JVM to bootstrap all this.
- Get Bazel.
- Build. Bazel downloads and caches all dependencies.
npm install -g @bazel/bazelisk
You can run all the tests:
bazel test ...
You can run the shell (or skip the tests and go right here):
bazel run //:shell
JLine-Based Console
If the JLine library is present, the Rhino shell will use it for command-line editing. The commands above will all include JLine. However, the Gradle wrapper interferes with JLine's ability to manipulate the terminal. For the best CLI experience, use either of the last two options, instead of ./gradlew run.
Benchmarking
You can also run the benchmarks:
./gradlew jmh
When running the benchmarks you may find a couple of environment variables useful.
BENCHMARKif set will limit the benchmarks run to those matching
INTERPRETEDcan be set totrueorfalseto only run the
PROFILERScan be set tocpuorallocto run the async profiler
JFR events
Rhino will produces JFR events for a number of internal operations
such as initialising global objects, parsing, compiling, and script
execution These, along with standard junit events, can be enabled for
rhino:test and tests:test by adding -PjfrTestRecording to the
gradle options. If test recording is switched on then a jfr file will
be created in the build/jfr/test/ directory of the task for each JVM
process which runs tests. You'll likely only want these types of
traces for large tests such as Test262SuiteTest.
Testing on other Java Versions
It is a good idea to test major changes on Java 17 before assuming that they will pass the CI tests. To do this, set the environment variable RHINO_TEST_JAVA_VERSION to the version that you want to test. For example:
RHINO_TEST_JAVA_VERSION=17 ./gradlew check
This will only work if Gradle can find a JDK of the appropriate version. You can troubleshoot this using the command:
./gradlew -q javaToolchains
Not all installers seem to put JDKs in the places where Gradle can find them. When in doubt, installations from Adoptium seem to work on most platforms.
Testing on Android
Code Coverage
The "Jacoco" coverage is enabled by default for the main published modules as well as the special "tests" module. Coverage is generated for each of the main projects separately and available by running
./gradlew jacocoTestReport
To see an aggregated coverage report for everything, which is probably what you want, run
./gradlew testCodeCoverageReport
The result is in:
./tests/build/reports/jacoco/testCodeCoverageReport/html
Releasing and publishing new version
- Ensure all tests are passing
- Remove
-SNAPSHOTfrom version ingradle.propertiesin project root folder - Create file
gradle.propertiesin$HOME/.gradlefolder with following properties. Populate them with maven repo credentials and repo location.
mavenUser=
mavenPassword=
mavenSnapshotRepo=
mavenReleaseRepo=
- Run
Gradletask to publish artifacts to Maven Central.
./gradlew publish
- Increase version and add
-SNAPSHOTto it ingradle.propertiesin project root folder. - Push
gradle.propertiestoGitHub
Java 16 and later
If you are using a modular JDK that disallows the reflective access to
non-public fields (16 and later), you may need to configure the JVM with the
--add-opens
option to authorize the packages that your scripts shall use, for example:
--add-opens java.desktop/javax.swing.table=ALL-UNNAMED
This is not necessary just to build or test Rhino -- it may be necessary when embedding it depending on what your project does.
Issues
Most issues are managed on GitHub:
https://github.com/mozilla/rhino/issues
Contributing PRs
To submit a new PR, please use the following process:
- Ensure that your entire build passes "./gradlew check". This will include
- Please write tests for what you fixed, unless you can show us that existing
- If you fixed ECMAScript spec compatibility, take a look at test262.properties and see
- Push your change to GitHub and open a pull request.
- Please be patient as Rhino is only maintained by volunteers and we may need
- Thank you for contributing!
Updating Test262 tests
If you are adding new capabilities to Rhino, you may be making more test262 tests pass, which is a good thing. Please see the instructions on how to update our test262 configuration.
Because of differences between Java and JavaScript, when testing on newer Java versions, many Unicode-related test262 tests appear to pass, but they will fail on Java 17. Please ignore these!
Code Formatting
Code formatting was introduced in 2021. The "spotless" plugin will fail your build if you have changed any files that have not yet been reformatted. Please use "spotlessApply" to reformat the necessary files.
If you are the first person to touch a big file that spotless wants to make hundreds of lines of changes to, please try to put the reformatting changes alone into a single Git commit so that we can separate reformatting changes from more substantive changes.
Currently, you must be building on Java 17 or higher for Spotless to run.
More Help
GitHub is the best place to go with questions. For example, we use "GitHub discussions":