- A first script is three steps: register, hook an event, save it into the scripts folder.
- The host bundles GraalVM, so you write real JavaScript and never install it yourself.
- Scripts hot-reload in seconds with no Java rebuild.
- A script can only call the objects the host exposes through its host-access whitelist.
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.
Where Opal fits
Opal is a Fabric mod with a GraalVM JavaScript scripting engine, so these steps apply directly. To get started, see the scripting docs.
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.
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.
Create a script file
Make a new .js (or .mjs) file in that folder. The host picks it up the next time it loads scripts.
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.
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 (names vary by 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.
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 |
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.
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.