Getting started

PaperScript is a Paper plugin that embeds a JavaScript engine and loads your plugins from a folder. You write TypeScript, bundle it to plain JS, drop it into the scripts directory, and hot-reload — no Java code required.

Requirements

PaperScript ships as two separate jars. Pick the one that matches your server.

LineMinecraftJavaEngineJar
ModernPaper 1.18 – 1.2117 / 21GraalJSpaperscript-host-*.jar
LegacyPaper 1.12.2 / 1.16.58 / 11Nashornpaperscript-legacy-*.jar

Both lines expose the same ps.* API. The legacy line exists because GraalJS requires Java 17+, while 1.12.2/1.16.5 servers run on Java 8/11 where Nashorn is bundled.

1. Install the host

  1. 1Download paperscript-host-0.2.0.jar (or paperscript-legacy-0.2.0.jar) from GitHub Releases and drop it into your server's plugins/ folder.
  2. 2Start the server once. PaperScript creates its scripts folder automatically.
  3. 3Verify in console or in-game: /ps list (permission paperscript.admin, default: op).

2. Set up the SDK

The SDK gives you typed autocompletion for the whole ps API and a CLI that scaffolds and bundles plugins:

bash
npm i -D @paperscript/sdk
npx paperscript init my-plugin
cd my-plugin
npm install
npm run build   # -> dist/index.js

paperscript init creates a project with TypeScript config and the @paperscript/sdk types wired in (types: ["@paperscript/sdk"]). npm run dev watches and rebuilds on save.

3. plugin.json

Every script is a folder with a manifest. The target field tells the bundler which JS dialect to emit — use es2015 for legacy (Nashorn) hosts:

plugin.json
{
  "name": "hello",
  "version": "0.1.0",
  "main": "dist/index.js",
  "apiVersion": "1",
  "authors": ["you"],
  "target": "es2022"
}

4. Your first script

src/index.ts
ps.onEnable(() => {
  ps.logger.info("Hello from TypeScript!");
  ps.commands.register("hello", (ctx) => {
    ctx.sender.sendMessage("<green>Hello, " + ctx.sender.name + "!</green>");
  });
  ps.events.onPlayerJoin((e) =>
    e.player.sendMessage("<gold>Welcome to the server!</gold>")
  );
});

On the modern line every message string is parsed as MiniMessage (<green>, <gradient:#a:#b>, hover/click events). On legacy hosts, use &-color codes instead.

5. Deploy & reload

Copy the plugin folder (manifest + bundled output) into the scripts directory:

modern (paperscript-host)
plugins/
  PaperScript/
    scripts/
      my-plugin/
        plugin.json
        dist/
          index.js
legacy (paperscript-legacy)
plugins/
  PaperScriptLegacy/
    scripts/
      my-plugin/
        plugin.json      # "target": "es2015"
        dist/
          index.js

Then manage scripts in-game or from console:

  • /ps list — show loaded scripts and their status
  • /ps reload <name> — hot-reload a script without restarting the server
  • /ps info — engine and host version info

Sandbox

Scripts run in a locked-down context: no Java.type, no host IO, no native access, no threads. Only the curated ps facade is exposed, guarded by a statement limit (modern line). The host touches script contexts only from the server main thread, so scripts are safe by construction.

Errors thrown by a script are caught and logged with the script name — a broken script never takes the server down. Fix the file and /ps reload.

What's next

  • API reference — every ps.* member with signatures.
  • Examples — hello world and a full Essentials-style command suite.