Skip to Content

Debugging typia projects

typia runs at compile time. The debugger must start code that has already passed through the typia transform path, so use the same toolchain that you use for normal builds: ttsc / ttsx for TypeScript-Go, the patched TypeScript compiler from the legacy setup, a bundler plugin, or generated output from typia generate.

Build first

The most reliable VSCode setup is to build with source maps and debug the emitted JavaScript. Use this for Node.js and for any workflow where ttsc or the patched tsc emits the file you run from dist. Bun projects that rely on Bun.build should use the Bun section, because the debug build has to run the same Bun plugin path.

tsconfig.json
{ "compilerOptions": { "outDir": "dist", "sourceMap": true, "strict": true } }

Add a build script for your setup path:

package.json
{ "scripts": { "build:debug": "ttsc" } }

Then make VSCode run that script before starting the debugger. Use the Bun tab here only when Bun is the package manager for a build script that emits the JavaScript this Node.js launch configuration runs.

.vscode/tasks.json
{ "version": "2.0.0", "tasks": [ { "label": "build:debug", "type": "shell", "command": "npm run build:debug", "problemMatcher": "$tsc" } ] }
.vscode/launch.json
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Debug compiled app", "program": "${workspaceFolder}/dist/index.js", "preLaunchTask": "build:debug", "outFiles": ["${workspaceFolder}/dist/**/*.js"], "skipFiles": ["<node_internals>/**"] } ] }

The debugger opens the emitted .js file, but breakpoints bind back to the original .ts files through the source map.

Generation mode

Projects that use typia generate should debug the generated source or the JavaScript built from it. Point VSCode, Bun, or your bundler at the files under your --output directory, such as src/generated/**, instead of the template files that still contain raw typia.* calls.

When you pass file paths or globs to typia generate, each generated file is written as --output/<basename>, so point the debugger at those emitted basenames.

If you compile the generated TypeScript into dist, use the build first flow after running typia generate. If you run generated TypeScript directly, use the same runtime command that works outside the debugger.

Run through ttsx

For a quick TypeScript-Go debug session without a persistent dist directory, launch ttsx through a package script and let VSCode attach to the child Node process that executes your entrypoint.

package.json
{ "scripts": { "debug:ttsx": "ttsx --project tsconfig.json src/index.ts" } }
.vscode/launch.json
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Debug with ttsx", "runtimeExecutable": "npm", "runtimeArgs": ["run", "debug:ttsx"], "autoAttachChildProcesses": true, "skipFiles": ["<node_internals>/**"] } ] }

If Bun is your package manager, run the same debug:ttsx script from the terminal (bun run debug:ttsx) or use the Bun section for Bun inspector workflows. Do not switch this VSCode launch block to runtimeExecutable: "bun" unless your Bun debugger setup is already working independently of typia.

Put application arguments after the entry file:

package.json
{ "scripts": { "debug:ttsx": "ttsx --project tsconfig.json src/index.ts -- --port 3000" } }

Flags before the entry file are handled by ttsx and the TypeScript-Go compiler. Flags after -- are delivered to your program as process.argv.

Legacy ts-node

The legacy setup can debug directly through ts-node/register, because typia setup patched the TypeScript compiler that ts-node uses. Install ts-node first if your project only installed typia, typescript, and ts-patch.

Terminal
npm install -D ts-node
.vscode/launch.json
{ "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Debug legacy ts-node", "runtimeArgs": ["-r", "ts-node/register"], "args": ["${workspaceFolder}/src/index.ts"], "env": { "TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json" }, "skipFiles": ["<node_internals>/**"] } ] }

If your legacy project is ESM-only, use the same loader command that runs the app outside VSCode. The important part is unchanged: do not replace the patched compiler path with stock tsx or an SWC/Babel loader, because those runners cannot apply typiaโ€™s transformer.

Bun

Bun debugging has two separate requirements: typia must still run in the same build or preload path, and Bunโ€™s inspector must attach to the process. The examples below show the Bun commands that preserve typiaโ€™s transform path. Prefer Bunโ€™s web debuggerย  for the attach step. Treat Bunโ€™s VSCode debuggerย  as an experimental fallback after installing and validating the Bun extension.

Bun.build output

For TypeScript-Go Bun applications, debug generated JavaScript. @ttsc/unplugin/bun integrates with Bun.build, so keep typia in that build path, emit a bundle for the same runtime you attach to, then start Bunโ€™s inspector on the emitted entry. The same shape applies to legacy Bun.build projects that use @typia/unplugin/bun. Bunโ€™s bundler target defaults to browser output and its sourcemap option defaults to no source maps, so set target: "bun" for bun --inspect-brk and keep the generated .js.map files beside the emitted .js files.

build.ts
import ttsc from "@ttsc/unplugin/bun"; await Bun.build({ entrypoints: ["src/index.ts"], outdir: "dist", target: "bun", sourcemap: "linked", plugins: [ttsc()], });
package.json
{ "scripts": { "build:debug": "bun run build.ts", "debug:bun": "bun --inspect-brk dist/index.js" } }
Terminal
bun run build:debug bun run debug:bun

Bun runtime preload

Legacy Bun projects can also debug the raw .ts entry when @typia/unplugin/bun is registered through bunfig.toml preload.

package.json
{ "scripts": { "debug:bun": "bun --inspect-brk src/index.ts" } }
Terminal
bun run debug:bun

Do not point Bun or VSCode at the raw .ts entry unless the Bun plugin is already registered in that runtime. Without the plugin, the program can run with untransformed typia.* calls.

Verify the debugger path

Temporarily add a setup check to the entry file that your debug configuration already runs:

src/index.ts
import typia from "typia"; console.log(typia.is<{ id: string }>({ id: "ok" }));

If the debug console prints true, the debugger is running transformed code. If it throws Error on typia.<method>(): no transform has been configured., the launch configuration is bypassing ttsc, the legacy patched compiler, the bundler plugin, or is still pointed at the template files instead of the generated files from typia generate.

Last updated on