Learn · guides
Write Your First GraalVM JavaScript Script (2026)
Write your first GraalVM JavaScript script: register an entry point, hook an event, and hot-reload it without recompiling Java. With a working example.
Write Your First GraalVM JavaScript Script
Writing a first GraalVM JavaScript script means three small steps: register the script with the host's entry point, attach it to an event or module, and save it into the scripts folder so the engine loads it. The engine runs on the GraalVM Polyglot API, so the script is real JavaScript and reloads without recompiling any Java.
What you need first
A host program that embeds the engine. The host ships GraalVM JavaScript, exposes a set of objects for scripts to call, and watches a scripts folder. You do not install GraalVM yourself; the host bundles it. You write plain JavaScript against the objects the host hands you.
Knowing what those objects map to helps, but you do not need to write any Java to get started. If you've written JavaScript before, the pattern will be familiar: the host acts like a library you import, and you use it to tap into the program's internals.
The three steps
Find the scripts folder
The host loads scripts from a known directory on startup. Check the host's documentation for the exact path. Usually it's a
scripts/folder in the installation directory.Create a script file
Make a new
.jsfile in that folder. The host picks it up the next time it loads scripts, either on startup or when you run a reload command if supported.Register and hook
Inside the file, register the script with the host's entry point, then attach behavior to an event or define a module that the host recognizes.
That's it. Save the file, reload, and the script runs. No build step, no compilation, no waiting. Just edit and reload.
A minimal example
Most hosts give a script one entry point to register itself and a few proxy objects that bridge JavaScript to the program. The exact names depend on the host, but the shape is the same. A first script usually just announces itself and reacts to one event:
// Register the script with the host.
script.register({
name: "hello-world",
version: "1.0.0",
});
// React to an event the host exposes.
script.on("enable", () => {
client.print("Hello from my first script.");
});Read the host's own API reference for the real object and method names. The point is the pattern: register, then hook an event or define a module. Most hosts expose an event loop or lifecycle hook, and most scripts start by listening to one.
Hot reload while you work
Save the file and reload scripts (or restart the host if it does not support live reload). The change takes effect with no rebuild. This fast loop is the main reason to script instead of compiling a mod: a script reloads in seconds, while a compiled mod has to be rebuilt and relaunched.
| Approach | Iteration loop | Language | When it fits |
|---|---|---|---|
| GraalVM JavaScript script | Edit, save, reload | JavaScript | Quick tweaks, custom behavior |
| Compiled mod | Rebuild, relaunch | Java or Kotlin | Larger features, deeper hooks |
If you're adding a simple feature or tweaking behavior, scripting is the way. If you need to hook deep into the engine or expose new primitives, a compiled mod might make sense.
What scripts can and cannot do
A script can call into the objects the host exposes and nothing else. The host declares which classes and methods scripts may touch through the GraalVM Polyglot host-access whitelist, and the default is deny. That keeps scripts safe and predictable. If the object you want is not exposed, the host has to add it; you cannot reach past the whitelist from the script side.
This is a feature, not a bug. It means scripts can't accidentally (or maliciously) break the host by calling internal methods or reaching into objects they shouldn't. It also means the host's maintainers have clear control over what's supported and what's not.
FAQ
No. The host program bundles GraalVM and its JavaScript engine. You only write the JavaScript file and drop it in the scripts folder.
Yes. The engine supports recent ECMAScript features, including modules with import and export, so you are not stuck with an old subset.
Check that the file is in the host's scripts folder, has the extension the host expects, and registers itself with the host's entry point. A typo in the register call is the usual cause.
No. The engine is embedded inside the host JVM, so your script talks to the host program, not to a standalone Node.js runtime.