- GraalVM Release Calendar
- Vulnerability Advisories
- GraalVM 25.1
- GraalVM 25
- GraalVM for JDK 24
- GraalVM for JDK 23
- GraalVM for JDK 22
- GraalVM for JDK 21
- GraalVM for JDK 20
- GraalVM for JDK 17
- GraalVM 22.3.x
- GraalVM 22.2.x
- GraalVM 22.1.x
- GraalVM 22.0.x
- GraalVM 21.3.x
- GraalVM 21.2.x
- GraalVM 21.1.x
- GraalVM 21.0.x
- GraalVM 20.3.x
- GraalVM 20.2.x
- GraalVM 20.1.x
- GraalVM 20.0.x
- GraalVM 19.3.x
GraalVM 25.1.3
(2026-06-30)
- Platform and Distributions
- Graal Compiler
- Native Image
- GraalJS
- GraalPy
- GraalWasm
- Polyglot Runtime
- Truffle Framework
Platform and Distributions
- Starting with the 25.1 release line, GraalVM provides innovation (feature) releases on a monthly cadence with quarterly Critical Patch Updates (CPUs) incorporated when available. Previously, feature releases were shipped every six months, with each release receiving two quarterly CPUs before being superseded by the next feature release. The most recent feature release supersedes the previous feature release.
- Released GraalVM Community Edition 25.1.3 based on OpenJDK 25.0.3+9. See OpenJDK 25 Updates.
- Released Oracle GraalVM 25.1.3 based on Oracle JDK 25.0.3+9. See Java SE 25 Release Notes.
- Version compatibility:
- GraalVM 25.1.3 is compatible with Graal Languages and other components version 25.1.3.
Graal Compiler
- Enabled the use of the
graal.prefix for compiler options without issuing a warning (in addition to-Djdk.graal). - Added support for recording and replaying JIT compilations. The
-Djdk.graal.RecordForReplay=*option serializes all compilations matching the pattern to JSON files, which contain the results of JVM Compiler Interface (JVMCI) calls. The recorded compilations can be replayed with themx replaycompcommand. Truffle compilations are currently not supported. For details, see the documentation Replay Compilation. - Added a new disassembly tool that can disassemble
HexCodeFilesections in.cfgfiles andMachCodesections in HotSpoths_err_pidfiles. Run the tool withmx, for example:mx distool hs_err_pid5677.log. - Added optional constant blinding for untrusted code. Enable it with
-Djdk.graal.BlindConstants=true.
Native Image
New Features and Improvements
- Reduced Native Image size by compacting image heap metadata and storage, including module metadata, runtime dynamic-access metadata, and symbol table data, and intrinsifying simple constant
String.formatandString::formattedcalls. This reduces the size of a HelloWorld application on Linux AMD64 to ~6.5 MB. - Added support for using G1 GC in Native Image on macOS AArch64 (Oracle GraalVM-only feature).
- Added a new tool,
--tool:llvm-backend, to enable the LLVM backend for Native Image. - Introduced
--future-defaults=class-for-name-respects-class-loaderthat changesClass.forNameandClassLoader#loadClassto respect the class loader arguments. - Introduced a new value for
--future-defaults=run-time-initialize-resource-bundlesthat shifts away from build-time initialization forjava.util.ResourceBundle. Unless you storeResourceBundle-related classes in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages. - Made
--future-defaults=complete-reflection-typesdefault. All reflective operations on types registered for reflection will now return complete results. - The context class loader seen during build-time context initialization is now part of the
native-imagemodule layer. This means that, by default, service loaders will now see extra service provider definitions from thenative-imagemodule path. JNI_CreateJavaVMnow runs Native Image startup hooks by default for JNI-created VMs. If your image must delay startup hooks until a later explicitVMRuntime.initialize()call, use-H:-InitializeVM.- Made
ParseRuntimeOptionsa non-experimental option and extracted a separate experimentalInitializeVMflag. If your project previously usedParseRuntimeOptionsand you callVMRuntime.initialize()manually, you might have to disable the new option. - The
-H:options can now be used at build time to set defaults for both build-time and run-time options. For example, the run-time option-R:MaxHeapSizecan now also be set via-H:MaxHeapSize. - Added randomized runtime code entry points via
-H:+MaxRuntimeCodeOffset. - Relative code pointers are now enabled by default for position-independent executables (PIE) and shared library images. They can be disabled with
-H:-RelativeCodePointers. - Added component hashes to the SBOM
-H:+MemoryMaskingAndFencing(Oracle GraalVM-only feature). Users can now benefit from strengthened integrity verification by comparing the SBOM digests with those published to trusted sources like Maven Central. - Removed all support for running the
native-imagebuilder on classpath. - Renamed the
native-image-configuretool tonative-image-utils. - Added a new API option
-Werrorto treat warnings as errors. - Added size warnings for bundles created with
bundle-createwhen individual or total file sizes exceed configured limits. Configure these limits using thesize-warning-file-limitandsize-warning-total-limitoptions (values in MiB). - Moved
native-image-utils extract-sbomto GraalVM Community Edition. - Added the
--print-optionsflag tonative-imagefor printing available options in table, Markdown, or JSON format.
Performance Improvements
- Introduced a new Serial GC policy,
Adaptive2, which uses mark-compact collection in the old generation by default. On average, this reduces memory usage and often improves throughput and latency. To restore the previous behavior, use:-H:-CompactingOldGen -H:InitialCollectionPolicy=Adaptive. - Serial GC collection policy can now be selected at run time with
-XX:InitialCollectionPolicy.
Debugging and Monitoring Improvements
- Added the
jitdumpsupport for recording run-time compilation metadata forperf(see Perf Profiler Support in Native Image). It can be enabled with-g -H:+RuntimeDebugInfo -H:RuntimeDebugInfoFormat=jitdump. - Added POSIX support for Native Image JFR emergency dumps. When an
OutOfMemoryErroroccurs while a JFR recording is active, Native Image can preserve in-memory recording data in an emergency JFR file. - JFR now uses the safepoint-based execution sampler by default on all platforms.
- JFR stack traces are no longer disabled entirely with runtime compilation; traces containing JIT-compiled code are skipped individually.
Improved Compatibility
- Added an early version of dynamic class loading for libraries and tools that generate JVM bytecode at run time, such as Byte Buddy. It also enables more plugin use cases, such as dynamically loading
javacannotation processors. To enable dynamic class loading, pass-H:+RuntimeClassLoadingto thenative-imagetool. - Introduced
-H:+CompatibilityModethat aligns Native Image execution more closely with standard Java semantics by disabling implementation-specific behavior. In this mode, the following features are disabled: build-time initialization of classpath classes, native-image-specific system properties, classpath substitutions, user-defined features. This mode does not modify key restrictions related to dynamic access (reachability metadata) and run-time class loading as those are accepted limitations of Native Image. For behavior closer to the JVM, consider combining this mode with:native-image -H:+CompatibilityMode -H:Preserve=all -H:+RuntimeClassLoading App - Improved the schema to capture detailed constraints about each element in the reachability-metadata-schema.json file.
- The reachability-metadata-schema.json file is now included in the GraalVM distribution at
<graalvm-home>/lib/svm/schemas/reachability-metadata-schema.json, making the schema available locally without requiring a separate download. -H:Preservenow preserves reached lambda proxy classes whose capturing classes are preserved.- Added
-XX:TraceMetadataConditionPackagesfor collecting conditional reachability metadata from a native image at run time. - Improved URL protocol reachability metadata collection.
--enable-url-protocolsis now deprecated in favor of reachability metadata. - Made bundle path maps portable across platforms; bundle format is now 1.0, with backward compatibility.
Platform Updates
- On macOS, the build process now uses
memory_pressureinstead ofvm_statfor a more accurate detection of free memory. - Added Windows support for Native Image JFR recordings and heap dumps.
- Linux builds now produce position-independent executables (PIE) by default. This can be disabled with
-H:NativeLinkerOption=-no-pie.
Deprecated Functionality
- Deprecated the
native-image-inspecttool. To extract embedded SBOMs, usenative-image-utils extract-sbom --image-path=<path_to_binary>. - Deprecated
native-image-utils generate-filters; the agent now applies built-in filters by default. - Removed the Fallback feature. The
--no-fallbackflag is deprecated and no longer has any effect, and other related options have been removed. - Deprecated the API method
Threading.registerRecurringCallback(...)without replacement. This method should not be used as it is inherently unsafe. - Removed the deprecated API method
ProcessPropertiesSupport.setLocale(...). - Removed the deprecated
@AutomaticFeatureannotation and its handling. Features should be registered via the--featuresargument.
Web Image
- Web Image is a recently introduced experimental backend for GraalVM Native Image that compiles a Java application ahead-of-time and produces a WebAssembly (Wasm) module with a JavaScript wrapper. Then it can be run in browsers, Node.js, or on the GraalJS-based Node runtime. It is available with Oracle GraalVM 25.1 or later. Web Image is enabled by passing the
--tool:svm-wasmoption to thenative-imagetool. Find some examples and more documentation in the demos repository.
GraalJS
- ECMAScript 2026 mode/features are enabled by default.
- Updated Node.js to version 24.14.1.
- Finished support for Temporal. It is available in ECMAScript 2027 mode (
--js.ecmascript-version=2027). - Implemented the
Explicit Resource Managementproposal. It is available behind the experimental option--js.explicit-resource-management. - Implemented the
Joint Iterationproposal. It is available in ECMAScript staging mode (--js.ecmascript-version=staging). - Implemented the
Import Textproposal. It is available behind the experimental option--js.import-text. - Implemented the
Import Bytesproposal. It is available behind the experimental option--js.import-bytes. - Implemented the
Error Stack Accessorproposal. It is available behind the experimental option--js.error-stack-accessor. - Removed support for legacy import assertions (
import ... assert {type: "..."}) and the--js.import-assertionsoption. Use import attributes (import ... with {type: "..."}) and the--js.import-attributesoption instead. - Removed support and builds for macOS x86-64 (darwin-amd64).
- Added an experimental option
js.cryptothat providesgetRandomValues()andrandomUUID()from the Web Crypto API. - Added stable option
js.performancethat providesperformance.now(),timeOrigin, andtoJSON()from the Web High Resolution Time API. - Implemented the
Immutable ArrayBuffersproposal. It is available in ECMAScript staging mode (--js.ecmascript-version=staging). - Limited Chrome inspector remote debugging to localhost.
- The JavaScript polyglot isolate now includes support for WebAssembly (Wasm).
GraalPy
- The standalone artifacts now include the Python version before the GraalVM version in their names. Artifact names now start with
graalpy<PYTHON_VERSION>-<GRAAL_VERSION>-<OPERATING_SYSTEM>-<ARCHITECTURE>. - Standalone JVM artifacts are no longer released as separate distributions. For standalone deployments, use the GraalPy native artifacts. For Java interoperability, use the jbang launcher (
jbang graalpy@oracle/graalpython -c "print('hello from GraalPy')") or a custom embedding. - Added
-X jit=0|1|2presets to tune startup-heavy or throughput-oriented workloads. The GraalPy launcher now defaults to thejit=1preset. - Interned string literals in source files.
- Improved
readlinesupport via JLine. Autocompletion and history now work inpdb. - Added GitHub workflows that run the same gates as internal CI. This helps contributors ensure their PRs pass the same tests run internally.
- Dispatch
sys.auditevents to hooks registered withsys.addaudithook, including audit events raised through thePySys_AuditC API. - The GraalPy Native standalone on Linux now uses a lower-footprint Native Image garbage collection configuration. This reduces resident set size (RSS) for many workloads, but may increase startup or warmup time and can slow down some workloads.
- Replaced the intrinsified
_ctypesmodule with the native CPython version. This makes GraalPy’sctypesimplementation more compatible and reduces the memory footprint of usingctypes. - Removed allocation reporting via Truffle. Python object sizes were never reported correctly, so the data was misleading. Reporting also added non-negligible overhead even when inactive.
GraalPy Embedding in Java
- Added a new, more natural style of subclassing Java classes from Python by passing the
new_style=Truekeyword. Multiple levels of inheritance are supported, andsuper()calls both in the constructor override via__new__as well as in Java method overrides work as expected. - Added the
polyglot.gil_locked_during_interopcontext manager. By default, the global interpreter lock (GIL) is released when interacting with foreign objects to allow other Python threads to run in parallel. This context manager keeps the GIL held for short-running interop, reducing repeated lock/unlock overhead. - Foreign buffer objects are now treated as Python buffer-compatible binary objects, so APIs such as
memoryview,bytes,bytearray,binascii.hexlify, andio.BytesIOwork naturally on them when embedding GraalPy in Java. - Added support for specifying generics on foreign classes and inheriting from them. This allows expressing generic types in Python type annotations, especially when using Java classes that support generics.
- Added a Java backend for the
pyexpatmodule that uses a Java XML parser instead of the nativeexpatlibrary. This is the default for embeddings and can be switched back to nativeexpatwith thepython.PyExpatModuleBackend=nativeoption. - Added the
python.UnicodeCharacterDatabaseNativeFallbackcontext option to control whether the ICU database may fall back to CPython’s native Unicode character database. - Added the
python.AllowSignalHandlerscontext option to control whether Python code may install signal handlers. It is disabled by default for Java embeddings and enabled in the standalone. - Added the experimental
python.InitializationEntropySourceoption to control the entropy source used for initialization-only randomness. - Foreign temporal objects, such as dates, times, and time zones, are now given Python classes corresponding to their interop traits:
date,time,datetime, ortzinfo. - Made BouncyCastle an optional dependency for embedding use cases. To support legacy RSA, DSA, and EC private key versions 0 and 1 from Python embeddings, explicitly add the
org.graalvm.python:python-bouncycastle-supportMaven artifact.
GraalWasm
- Adopted a bytecode-handler-based design for the WebAssembly interpreter, improving interpreted performance when GraalWasm runs as a native image.
- Implemented the legacy exception handling proposal. It is disabled by default and can be enabled independently with the experimental option
wasm.LegacyExceptions=true. - Implemented the exception handling proposal. This feature is enabled by default and can be disabled with the experimental option
wasm.Exceptions=false. - Implemented the typed function references proposal. This feature is enabled by default and can be disabled with the experimental option
wasm.TypedFunctionReferences=false. - Enabled the standardized features Extended Constant Expressions, Multiple Memories, and Relaxed SIMD by default.
- Implemented the GC proposal. This feature is enabled by default and can be disabled with the experimental option
wasm.GC=false.
Polyglot Runtime
- Isolated
EngineandContextare now available in GraalVM Community Edition. They can be enabled withengine.SpawnIsolate=true; for community language libraries, use-isolate-communityartifacts such asjs-isolate-community. SandboxPolicy.ISOLATED,SandboxPolicy.UNTRUSTED, and sandbox resource limits are now supported in GraalVM Community Edition.- Added
Context.Builder#spawnIsolate(boolean)andEngine.Builder#spawnIsolate(boolean)to configure polyglot isolates directly. If a permitted language is unavailable on the class path or module path but a polyglot isolate for that language is present, the isolated language is selected automatically. - Starting with Polyglot 25.1, the optimizing Truffle runtime is supported only with GraalVM 25.1 or later, including Oracle GraalVM and GraalVM Community Edition. It is no longer supported with GraalVM 25.0 or earlier, or on plain OpenJDK or Oracle JDK via
jargraal(org.graalvm.compiler:compileron--upgrade-module-path). The fallback runtime remains supported on standard JDKs and remains backward compatible down to JDK 21, but runs without runtime compilation. If you need the optimizing runtime on plain OpenJDK or Oracle JDK, continue using the 25.0 LTS release. - Introduced the
-Dpolyglot.engine.allowUnsupportedPlatform=truesystem property to enable the Truffle framework to run on unsupported platforms. When enabled, this property suppresses the unsupported-platform failure. See follow-up errors and warnings for instructions on how to continue. Note that using an unsupported platform will also force the fallback runtime without runtime optimization. - If neither a log handler nor the
log.fileoption is set on theEngine.BuilderorContext.Builder, Truffle and language log messages will be written to the Context’s error output stream by default. Thelog.fileoption is now also supported onContext.Builder. - Made
--polyglotthe default for language launchers, so there is no need to specify it anymore to use other languages in standalones. As a result,AbstractLanguageLauncher#getDefaultLanguages()andLauncher#canPolyglot()have been deprecated. - Closing a garbage-collected engine or context now logs only the first failure by default. To log all failures, use
engine.CloseOnGCFailureAction.PrintAll. Engine.getVersion()now returns the Truffle API version rather than the GraalVM version.- Polyglot isolate hosts now use the fallback Truffle runtime by default, enabling isolate hosting on JDKs that do not support the optimized Truffle runtime.
- Added constant-option support and native-image preset options. Selected polyglot option values can now be fixed before runtime initialization or captured as native-image build-time defaults.
- Added
Engine.supportsCompilation()to check whether the current host runtime supports optimized guest language execution. - Added
FileSystem#allowInternalResources(FileSystem), allowing embedders to expose internal resources and language homes through a read-only view of the default file system when using a custom file system.
Find a complete list of updates in the changelog.
Truffle Framework
- Multiple improvements in the
DynamicObjectAPI: introducedDynamicObjectnodes as a lighter replacement forDynamicObjectLibrary, and deprecatedDynamicObjectLibrary. See the migration guide. - Bytecode DSL performance improvements: specialization state and primitive constants are now encoded directly in bytecode, and threaded switch execution is enabled by default for bytecode interpreters.
- Bytecode DSL runtime and diagnostics improvements: added generated bytecode descriptors (
BytecodeDescriptor/InstructionDescriptor) and instruction-level tracing/histogram options (engine.TraceBytecode,engine.BytecodeHistogram). - Bytecode DSL stack-trace support improvements: introduced
BytecodeFrameand optional frame capture inTruffleStackTraceElements for more reliable frame data in traces. - Added more Bytecode DSL runtime support, including lazy source-content loading, generated
BytecodeRootNode#getSource(), stricter bytecode-index validation, frame-walk helpers, and improved generated root-node delegation. - Interop API modernization:
InteropLibrary#hasLanguage/getLanguagewere replaced byhasLanguageId/getLanguageId; new host interop methods onInteropLibrarywere added and correspondingEnvhost-object APIs were deprecated. - Host adapter instances created with
TruffleLanguage.Env#createHostAdapternow delegate unresolved direct member operations to the original guest object. - Truffle DSL behavior change: single-specialization nodes no longer specialize on first execution unless needed (assumptions/cached state/multiple instances), improving interpreter footprint and startup behavior.
- Added support for passing primitive arrays to native code through the Truffle NFI Panama backend.
- Debugger stepping behavior was refined: pending steps are now independent from breakpoint handling and thread resume operations.
- Improved optimized performance of host proxy interfaces (
org.graalvm.polyglot.proxy.Proxy). - Added compiler guidance APIs for partial evaluation, including
@HostCompilerDirectives.InliningRootand@CompilerDirectives.EarlyInline/@CompilerDirectives.EarlyEscapeAnalysis. - Added new Truffle engine options for compilation tuning, including
engine.DynamicCompilationThresholdsHighLoadSlopefor high-load threshold scaling andengine.CompilerThreadStackSizefor configuring compiler thread stack size. - Added
Engine.persistCache(Engine.CancellationCallback)to persist the auxiliary engine cache into an in-memoryByteBufferwith cancellation support. - Added support for constant polyglot options and native-image preset options, allowing selected option values to be fixed before runtime initialization or captured as native-image build-time defaults.
Find a complete list of updates in the Truffle changelog.