Open-source project
oracle/graal avatar
oracle/graal

GraalVM: what oracle/graal actually contains

GraalVM compiles applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀

21,720 stars1,826 forksJavaNOASSERTION

At a glance

What is it?
The oracle/graal repository is the source tree behind GraalVM, not the game servers that share its name. Here is what each component does, and where the documentation stops short.
Who is it for?
Adopt GraalVM when startup time or memory footprint is the binding constraint and you can afford to test the native path properly. Do not adopt it for a long-running service whose throughput is already acceptable on a standard JDK, because you inherit a build step, a closed-world assumption and a larger release surface for no measurable gain.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What oracle/graal is, and what it is not

The first thing to settle is the name. GraalVM is a Java Development Kit distribution whose distinguishing feature is ahead-of-time compilation of applications into standalone binaries. The README states that GraalVM "compiles applications ahead of time into standalone binaries that start instantly, provide peak performance with no warmup, and use fewer resources," and adds that you can use it "just like any other Java Development Kit in your IDE." That second sentence matters more than the first for adoption decisions: the intended migration path is to swap the JDK, keep the build, and only then reach for native images where they pay off.

The repository at oracle/graal is the main source repository for GraalVM, not a single tool. Its directory table lists the Graal compiler, SubstrateVM (the framework for AOT compilation with Native Image), the Truffle language implementation framework, the GraalVM SDK, Espresso (a meta-circular Java bytecode interpreter), Sulong (an LLVM bitcode engine), GraalWasm, TRegex, the Ideal Graph Visualizer, and the VM components used to build distributions. Languages such as GraalJS and GraalPy live in separate repositories, which the README lists explicitly.

Who this is for: teams running JVM services where cold start or resident memory is a real line item, and language implementers who want to build a runtime on top of Truffle. If you are looking for the browser game, this is a different project entirely, and the repository contains nothing about it.

How the pieces fit: compiler, SubstrateVM, Truffle

Three mechanisms do most of the work.

The Graal compiler is described in the repository table as "a modern, versatile compiler written in Java." It is the optimizing compiler. On a standard JDK it can be used through JVMCI as a replacement for the default JIT compiler, which is the path behind the graal vs hotspot and graal vs openjdk comparisons people search for. That path is a runtime swap and does not produce a binary.

SubstrateVM is the other path, and it is the one that changes your deployment. It performs ahead-of-time compilation with Native Image. The output is a standalone executable that does not need a JVM at startup. The cost is the closed-world assumption: anything the compiler cannot see at build time has to be declared, which is why reflection, dynamic proxies and resource loading are the usual sources of build failures.

Truffle is the framework for building languages and tools on top of GraalVM. Espresso, Sulong, GraalWasm and TRegex are all implementations that sit on this layer. If you are not writing a language or a language tool, Truffle is probably not the part of the repository you will touch, but it explains why the tree contains so many engine directories.

The data flow for a native build is roughly: your compiled classes plus the reachability metadata for your dependencies go into the native-image tool, SubstrateVM analyses them under the closed-world assumption, and it emits a platform-specific executable. Anything reachable only through reflection that was not declared simply is not in the image.

Getting GraalVM and the components you actually touch

The README does not contain install commands, and it is worth being blunt about that: there is no copy-paste setup here. It points to the project website for getting started and to the downloads page, and it states that instructions for building GraalVM from source are in vm/README.md. So the honest starting point is https://www.graalvm.org/downloads/, and the source-build path runs through vm/README.md.

What the repository does give you is the map. If you plan to produce native executables, the directory you care about is substratevm/, and the build tool plugins you will need are Native Build Tools, which the README lists under related repositories rather than in this tree. If you plan to run JavaScript, Python or WebAssembly on the JVM, those engines are in GraalJS, GraalPy and wasm/ respectively, and the README points to separate repositories for the first two.

A useful sanity check before investing in the native path: confirm which of the components you depend on carry which licence, because the README's table shows the terms are not uniform across the tree. That is a five-minute read of the licence table and it can change the shape of a distribution decision.

Where native image breaks, and when to skip it

The limitation that catches most teams is the closed-world assumption. Native Image cannot include code it cannot prove is reachable. Libraries that resolve classes by name at runtime, that scan the classpath, or that load configuration files through the class loader will behave differently or fail outright unless the necessary entries are declared. The graalvm-reachability-metadata repository exists precisely because this is a per-library problem that the GraalVM project cannot solve centrally for every dependency.

A second constraint is build time and build complexity. You are adding a compilation stage that produces a platform-specific artifact. Cross-compilation is not the same story as a jar, so a build matrix that used to be one artifact becomes one artifact per target.

A third is that not every workload benefits. A long-running server that has already warmed up its JIT compiler is not obviously better off as a native binary. The gains the README describes are about startup and resource use. If your service runs for days and your p99 latency is fine, the native path adds a build step and a class of runtime failures in exchange for a startup improvement nobody measures.

Wrong tool, concretely: an application whose behaviour depends on dynamically loading user-supplied plugins at runtime. The closed-world assumption is directly opposed to that design, and no amount of metadata makes it a good fit.

GraalVM against a standard OpenJDK build

The real alternative for most readers is the JDK they already run, typically a HotSpot-based OpenJDK build. The difference in approach is not a feature list, it is when compilation happens. HotSpot compiles at runtime: the JVM starts, interprets, profiles, and promotes hot methods to optimized code. Startup is a cost you pay on every launch, and peak throughput arrives after warmup. GraalVM's Native Image compiles ahead of time: the analysis happens during the build, the executable starts without a JIT warmup phase, and the peak is available immediately.

That inversion is the whole trade. Ahead-of-time compilation cannot use runtime profiling, so it cannot specialize on the code paths your production traffic actually exercises. It also cannot see code that only becomes reachable at runtime. HotSpot can do both, at the price of startup time and a larger resident footprint.

The Graal compiler as a JIT replacement is a third position, and it is worth separating from Native Image in your head. Using Graal as the JIT compiler on a standard JDK keeps the runtime model of HotSpot while changing the optimizer. It is not the same decision as producing a native binary, and the two are often conflated in discussion.

Maintenance, release cadence and what the repository shows

The last push to the default branch was on 2026-09-18, and the repository is not archived. That is the only maintenance signal available here, and it is a strong one for the source tree itself.

The releases list tells a different story and is worth reading carefully. The most recent entries are vm-19.3.1, vm-19.3.0 and vm-19.2.1, all from late 2019 and early 2020. The vm-19.3.1 entry carries the note "Releases have moved." So the GitHub releases page for this repository is not where current GraalVM versions are published. Anyone tracking versions by watching this repository's releases will be looking at a page that stopped being the distribution channel six years ago. Use the downloads page instead.

Upgrade cost is dominated by the reachability metadata problem rather than by API churn. The GraalVM SDK is described in the repository table as "long-term supported APIs of GraalVM," which is the layer to build against if you want stability. Everything below that, including the native image analysis, can change in ways that surface as new missing declarations at build time. Expect a metadata review when you bump the GraalVM version, not just a dependency bump.

Licensing across the component tree

This is not a single-licence repository, and the README says so. GraalVM Community Edition is distributed under version 2 of the GNU General Public License with the Classpath Exception, described as the same terms as for Java. Below that, the licences differ by component.

The compiler, SubstrateVM, the tools and the VM are GPL 2 with Classpath Exception. Espresso, the Ideal Graph Visualizer and Web Image are GPL 2 without the exception. The GraalVM SDK, GraalWasm, the Truffle framework and TRegex use the Universal Permissive License. Sulong is 3-clause BSD.

The practical consequence is that the licence attached to your build depends on which components you link, not on the repository as a whole. The Classpath Exception on the compiler and SubstrateVM is what makes the common case of compiling and shipping your own application unremarkable, but that is a reading of the stated terms and not legal advice. If you redistribute a modified GraalVM or embed components under the plain GPL 2 entries, check the terms with someone qualified rather than assuming the Classpath Exception covers you.

Editorial conclusion

Adopt GraalVM when startup time or memory footprint is the binding constraint and you can afford to test the native path properly. Do not adopt it for a long-running service whose throughput is already acceptable on a standard JDK, because you inherit a build step, a closed-world assumption and a larger release surface for no measurable gain. Before committing, verify three things in your own project: that every reflection and resource access your libraries perform is covered by reachability metadata, that your build tooling has a Native Build Tools plugin version compatible with your GraalVM release, and that the licence terms of the specific components you link (GPL 2 with Classpath Exception for the compiler and SubstrateVM, Universal Permissive License for the SDK and Truffle, 3-clause BSD for Sulong) match how you intend to distribute the result.

Frequently asked questions

What is GraalVM and how does it relate to the oracle/graal repository?

GraalVM is a JDK distribution that compiles applications ahead of time into standalone binaries which start without a JIT warmup phase. The oracle/graal repository is the main source repository for it, containing the Graal compiler, SubstrateVM (Native Image), Truffle, the GraalVM SDK and the VM components used to build distributions.

How does GraalVM compare with OpenJDK or HotSpot?

The difference is when compilation happens. HotSpot compiles at runtime, so startup is a cost paid on every launch and peak throughput arrives after warmup. GraalVM's Native Image compiles ahead of time, so the executable starts without warmup, but the analysis cannot use runtime profiling or see code that only becomes reachable at runtime.

How do I install GraalVM?

The README does not give install commands. It points to the project website for getting started and to https://www.graalvm.org/downloads/ for downloads, and it states that instructions for building GraalVM from source are in vm/README.md.

Why does a GraalVM native image build fail on reflection or resources?

Native Image works under a closed-world assumption: code it cannot prove is reachable is left out of the executable. Libraries that resolve classes by name at runtime or load resources through the class loader need those entries declared, which is why the graalvm-reachability-metadata repository exists.

Where are current GraalVM releases published?

Not on this repository's releases page. The most recent entries there are vm-19.3.1, vm-19.3.0 and vm-19.2.1 from 2019 and 2020, and the vm-19.3.1 entry notes that releases have moved. The README links to the downloads page for current versions.

Official sources

  1. Issues
  2. oracle/graal on GitHub
  3. Project website
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/oracle-graal.svg)](https://hysenlabs.com/projects/oracle-graal)
Community notes

Community notes