Skip the hassle of Java mod projects and customize Minecraft with modern JavaScript / TypeScript
If you've used KubeJS or CraftTweaker, here's what you might be looking for:
- Modern JavaScript: Runs on GraalJS, with support for the latest ECMAScript syntax,
import/export, top-levelawait, and dynamicimport(). - TypeScript runs directly: Drop
.tsor.tsxfiles into a script folder and they run. You don't need to compile or bundle anything yourself. - Built-in autocompletion: Run
/nekojs probeand NekoJS generates type declarations for the mods you have installed, so VS Code shows you the available events, methods, and item IDs. You don't need to install ProbeJS or a similar mod. - npm packages work: Put a pure-JavaScript npm package in
nekojs/node_modulesand you canimportit. Common Node.js built-in modules (fs,path,events, and others) are available too.
| What you want to do | Where to write it | Docs |
|---|---|---|
| Add, remove, or replace recipes | server_scripts |
Recipe System |
| Add items, blocks, fluids, entities, and creative tabs | startup_scripts |
Registering New Content |
| Run code when a player logs in, a block is broken, an entity takes damage, and more | server_scripts |
Event Reference |
| Add custom commands | server_scripts |
Event Reference |
| Draw HUDs and build screens (JSX) | client_scripts |
Client Rendering, JSX UI |
| Change the items and descriptions shown in JEI | client_scripts |
Event Reference |
| Save data and sync it to clients | Any | Data and State |
| Call Java classes and other mods' APIs | Any | Module System |
| Loader | Minecraft | Java | Status |
|---|---|---|---|
| NeoForge | 1.21.1 | 21 | Supported |
| NeoForge | 26.1.2, 26.2.0 | 25 | Supported, most complete |
| Fabric | 26.1.2, 26.2 | 25 | Supported, some features not yet ported |
Every version requires the Graal library mod: GraalMC 25.5.0 or later for both Fabric and NeoForge; use the loader-specific downloads. For per-platform differences, see Platform Compatibility.
1. Install. Download the NekoJS build for your Minecraft version and loader from Releases, put it in mods/ together with Graal, and launch the game.
One NekoJS jar per Minecraft version and loader is used on both client and server; there is no separate
-serverartifact. NekoJS does not bundle ICU4J; the GraalMC 25.5.0 builds for both loaders supply their own relocated ICU.
2. Find the script folder. After the first launch, a nekojs/ folder appears in your game directory:
nekojs/
├── startup_scripts/ Register items, blocks, etc. Changes need a game restart
├── server_scripts/ Recipes, events, commands. Run /nekojs reload after changes
├── client_scripts/ HUDs, key bindings, screens. Run /nekojs reload client after changes
├── test_scripts/ Tests. Only run when you execute /nekojs test
├── assets/ data/ Resource pack and data pack content
└── config/ Configuration files
3. Write a script. Create nekojs/server_scripts/welcome.js:
PlayerEvents.loggedIn(event => {
// The player is event.entity on NeoForge and event.player on Fabric
const player = event.entity ?? event.player
player.displayClientMessage(Text.of('Welcome to the server!').gold(), false)
})Run /nekojs reload, then rejoin the world to see the welcome message.
4. Turn on autocompletion. Run /nekojs probe in-game, then open the nekojs/server_scripts folder in VS Code.
For the full tutorial, see Quick Start. If you run into problems, check the FAQ first.
Register an item and a creative tab
// nekojs/startup_scripts/items.js
RegistryEvents.register(event => {
event.item('mymod:cool_gem', item => {
item.maxStackSize = 16
item.rarity = 'rare'
})
event.creativeModeTab('mymod:main', tab => {
tab.title = 'My Modpack'
tab.icon = 'mymod:cool_gem'
tab.add('mymod:cool_gem')
})
})Takes effect after a game restart. Put the texture at nekojs/assets/mymod/textures/item/cool_gem.png.
Split code into TypeScript modules
Every file in a script folder gets loaded, so keep only exported functions and constants in lib/.
// nekojs/server_scripts/lib/ores.ts
export const ORES: string[] = ['minecraft:iron_ore', 'minecraft:gold_ore']
// nekojs/server_scripts/recipes.ts
import { ORES } from './lib/ores.ts'
ServerEvents.recipes(event => {
for (const ore of ORES) {
event.remove({ input: ore, type: 'minecraft:smelting' })
}
})Call Java classes
import { ArrayList } from 'java:java/util'
const list = new ArrayList()
list.add('hello')
console.info(list.size())Some high-risk Java classes are blocked by default. See Module System.
Write recipes in Python
# nekojs/server_scripts/recipes.py
from nekojs import *
def on_recipes(event):
event.remove({'output': 'minecraft:stick'})
ServerEvents.recipes(on_recipes)from nekojs import * is only there for your editor. Run /nekojs probe python to get autocompletion. See Python Scripts.
Change what JEI shows
// nekojs/client_scripts/jei.js (requires JEI, NeoForge only)
RecipeViewerEvents.removeEntries('item', event => {
event.add('minecraft:debug_stick')
})
RecipeViewerEvents.addInformation(event => {
event.add('minecraft:echo_shard', 'Can be used to craft a Recovery Compass.')
})Scripts are very powerful and can reach most of the game's internals. Only run scripts written by people you trust.
By default, NekoJS restricts some dangerous operations: scripts can only read files inside the game directory, can only write files inside nekojs/, and can't create threads, use reflection, or access high-risk Java classes such as those for networking and processes. These restrictions are not guaranteed to stop a malicious script. Also, NekoJS does not forcibly interrupt infinite loops, so a buggy loop will freeze the game.
You need JDK 17 or later (25 recommended). Gradle automatically downloads the JDK each Minecraft version needs.
git clone https://github.com/NekoJS-Dev/NekoJS.git
cd NekoJS
./gradlew :26.1.2:build # Build one version
./gradlew sandboxCheck # Full check before submittingBuild output goes to versions/<version>/build/libs/. For the project layout and other commands, see Build System and Project Architecture.
Issues and pull requests are welcome.
- When reporting a problem, please include the logs from
logs/nekojs/, the script that caused it, and your Minecraft, loader, and NekoJS versions. - Before opening a PR, read the PR checklist and the coding conventions.
- Community chat: QQ group 1158525822 (join)
LGPL-3.0 © Tki_sor