On this page

Helper scripts

Build tools, codegen, and one-off maintenance scripts belong outside your Defold source tree, in a project-root /scripts folder, and run with Bun. This keeps them off the Lua build path and gives them Node-style typings without polluting the types your game code sees.

Run with Bun, never node

Run a helper script with Bun:

bun scripts/generate-levels.ts

The node:* builtins — node:fs, node:path, node:child_process, and the rest — work under Bun unchanged; @types/bun types them. There is no reason to reach for the node binary, and doing so skips the TypeScript execution Bun gives you for free.

Put them in /scripts, not src/

Keep helper scripts in a /scripts folder at the project root. Do not put them under src/ — the Defold build compiles source by tsconfig.include (default src/**/*.ts) and ignores exclude, so any .ts file under src/** is transpiled to Lua and shipped into your game, whether you meant it to be or not.

src/ is also the wrong place for typing: the scaffolded tsconfig.json pins compilerOptions.types to ["@defold-typescript/types"] so your game code sees the Defold API and nothing else. A build script that imports node:fs under that pin would not type-check.

A project-root /scripts folder sits outside both the src/** include and the main tsconfig.json, so a dedicated scripts/tsconfig.json with its own types gives Bun typing with zero changes to your game's compile.

Type them with scripts/tsconfig.json

Add a scripts/tsconfig.json that types the folder for Bun. Do not re-pin the Defold types here — these scripts are not Defold code:

{
  "compilerOptions": {
    "noEmit": true,
    "types": ["bun"]
  },
  "include": ["**/*.ts"]
}

noEmit because Bun runs the TypeScript directly — nothing is compiled to disk. types: ["bun"] swaps the Defold API surface for the Bun and node:* typings. Editors auto-discover the file for anything under scripts/, so your helper scripts get autocomplete and tsc coverage on their own terms.

Script dependencies go in the root package.json

Any package a helper script needs is a dev-time dependency of the project, not a runtime dependency of your game. Add it to the root package.json devDependencies (@types/bun is already there in a scaffolded project):

bun add -d fast-glob

A minimal example

import { readdir } from "node:fs/promises";

const files = await readdir("assets/levels");
console.log(`${files.length} level files`);

Run it with bun scripts/count-levels.ts. It imports a node:* builtin, is typed by scripts/tsconfig.json, and never touches the Lua build.