Build your Defold game in TypeScript and get VSCode's full editor experience — autocomplete, inline type errors, and safe refactors — across the whole Defold API, while still shipping the plain Lua the engine runs.
- The full Defold API, typed — every module and namespace is typed from the official reference, so
go,gui,vmath,msg, and the rest autocomplete and type-check as you write. - Compiles to plain Lua — your TypeScript runs through the battle-tested TypeScriptToLua (TSTL) compiler down to the Lua Defold already runs: no engine fork, no proprietary runtime, no lock-in.
- Typed scripts end to end —
self,on_message, andon_inputpayloads are typed throughdefineScript,defineGuiScript, anddefineRenderScript. - Fits new and existing projects — scaffold from scratch, or add the TypeScript surface to a project that already has
game.projectand adopt type safety gradually, one script at a time alongside your existing Lua.- Preserves your project layout — TypeScript blends into the existing project structure without creating a wrapper folder.
- Built for the real loop —
watchrecompiles beside the Defold editor, live transpile diagnostics surface errors inline, and source maps let you set breakpoints in your.ts.
This guide shows how to scaffold a project, write TypeScript that the toolchain compiles to Lua, and look up the language-and-toolchain quirks you will hit along the way.
The sections below mirror the top navigation; each lists the pages in its left-sidebar order. The repository README.md is generated from this file so the GitHub landing page and docs homepage stay aligned.
- Getting started — install Bun, scaffold a new project with
bunx @defold-typescript/cli@latest init my-game, add TypeScript to an existing Defold project withinit ., write a one-screen script, and build to Lua withbunx @defold-typescript/cli build. - Editor setup — open the project in VSCode, use the generated
tsconfig.json, and runbunx @defold-typescript/cli watchbeside the Defold editor. - Defold editor — install Defold, open the generated project folder, attach a compiled script (
.ts.script,.ts.gui_script, or.ts.render_script) to its game object, GUI scene, or render pipeline, and run the game (TypeScript is transpiled to Lua by the CLI, not the editor).
- Build Tetris — build a complete Tetris game from scratch: write TypeScript, compile it to Lua, and wire the scene in the Defold editor, seeing the whole workflow end to end.
- TypeScript vs Lua — the Lua-developer on-ramp: a cheat sheet that translates syntax, tables, modules, and the standard library from Lua to the TypeScript the toolchain expects.
- TypeScript gotchas — the canonical catalog of TS / TypeScriptToLua (TSTL) / Defold sharp edges. Today: the unary-minus quirk that silently produces
numberfrom aVector3. Future entries land here as the toolchain encounters them. - Data structures — what's built in for Defold:
Array, tuple,Map,Set,WeakMap,WeakSet, object record, andclass, each with its Lua lowering andlualibcost, plus the not-available list (regex,BigInt,LinkedList) and what to reach for instead.
- Script lifecycle — type
self,on_message, andon_inputpayloads withdefineScript,defineGuiScript, anddefineRenderScript. - Messages — the
BuiltinMessagescatalog,msg.postsend-side payload narrowing, and theisMessage/onMessagereceive-side helpers. - Where script state lives — the four state tiers — per-instance
self, a shared module local, a cross-script module singleton, and VM-globaldeclare global— each grounded in the emitted Lua. - Vector math — the method-form arithmetic surface (
add,sub,mul,div,unm) onVector3,Vector4,Quaternion, andMatrix4, plus why you cannot writev3 + v3.
- init — scaffold a new Defold project with a TypeScript surface, or add TypeScript to an existing project; the two modes, the
--template/--forceflags, and the starter templates. - watch — the incremental rebuild loop: recompile Lua on every save beside the Defold editor, and re-resolve the extension surface on
game.projectchanges. - build — one-shot transpile of every
src/TypeScript file to Lua, plus the headlessdefoldsubcommand that drivesbobto build and bundle the project. - wall — opt-in per-directory API walls that narrow a single-kind source directory to its script-kind surface, in interactive and flag forms.
- resolve — generate ambient TypeScript namespaces from your
game.projectnative-extension dependencies, with pin/drift detection and a--frozenlockfile mode.
- Transpile diagnostics — the scaffolded
@defold-typescript/tstl-pluginlanguage-service plugin that surfaces TypeScript-to-Lua transpile errors live in the editor, advisory-only and never blockingtsc --noEmit. - Debugging — step through
.tssource with breakpoints via the Local Lua Debugger and the scaffolded Bun launch path (no shell, Windows-native), resolving through the emitted<name>.ts.script.map. - Agent runbooks — harness-neutral procedures for driving the CLI from an automated agent: scaffold a project, install the agent contract, regenerate extension types, add and attach a script (build, wire the compiled component, verify), and fix the Lua output over the
--jsonenvelope, gating onok. - Helper scripts — where build, codegen, and maintenance scripts live: a project-root
/scriptsfolder run with Bun, typed by their ownscripts/tsconfig.json, kept off the Lua build path and out of the Defold-typedsrc/surface.
- Pinning the Defold version — keep the default latest surface, or pin an older Defold version whose API surface is generated on the fly and materialized into a project-local
.defold-types/<version>/. - Native extensions — declare an extension in
game.project[dependencies], then runresolveto generate an ambient namespace per.script_apiinto a gitignored.defold-types/extensions/surface, and consume it with no import.
- API docs vs
ts-defold-types— a factual, dimension-by-dimension comparison of the JSDoc that@defold-typescript/typesandts-defold-typesemit (Markdown conversion, dash params, grid-aligned multi-line docs, branded constants, the@exampletrade-off), with a picker for which surface fits your project. - Migrating from
ts-defold— move a project off the@ts-defold/*stack: the package/tooling map, the step-by-step port viainitadd-TypeScript mode and atsconfig.jsonreconcile, and the type-surface differences you will hit.
- API — the generated
@defold-typescript/typesreference: every documented Defold namespace, grouped alphabetically as cards (site-only; built from the typed surface the toolchain ships). - Lua standard library — the pure-Lua / LuaJIT reference category (
base,bit, …). Types are owned by thelua-typesdependency thelua-stdlib-globalsgoal adopted;@defold-typescript/typesdoes not re-emit them as generated namespaces. - For AI agents — machine-readable docs per llmstxt.org:
llms.txtis the map (start here)llms-full.txtis the full corpus (grep it, never read it whole). The same pair ships into a consumer'snode_modules/@defold-typescript/docs/on install.
