Wakaru

CLI

Full reference for the Wakaru command line.

Edit on GitHub

Run Wakaru with npx wakaru or install it globally with npm i -g wakaru.

Decompile a single file

wakaru input.js -o output.js
cat input.js | wakaru > output.js    # stdin/stdout work too

Without -o, output goes to stdout.

Unpack bundles

wakaru bundle.js --unpack -o out/
wakaru entry.js chunk.js --unpack -o out/     # multiple explicit files
wakaru dist/ --unpack -o out/                 # recursively scan a directory
wakaru ./compiled-app --unpack -o out/        # Bun single-file executable

Variants:

OptionEffect
--unpackDetect the bundle format, split into modules, decompile each
--unpack --rawRaw split only: no readability transforms, provisional names, no module-graph promise
--unpack=strictStructural detection only, no heuristic fallback
--unpack=inspectFiner scope-hoist boundaries for static inspection. Always prints a warning. Not an executable reconstruction

Directory inputs scan .js, .mjs, and .cjs recursively, skipping hidden paths and node_modules. Input source maps (--source-map) are rejected with --unpack.

Bun single-file executables

--unpack on a bun build --compile binary (PE, Mach-O, ELF) validates Bun's embedded module graph and decompiles the JavaScript entries. It never executes the binary. To dump every embedded file, assets, WASM, and native add-ons included:

wakaru bun extract ./compiled-app -o extracted/
wakaru bun extract ./compiled-app -o extracted/ --json
wakaru bun extract ./compiled-app -o extracted/ --include-internals

bun extract is a byte-exact container operation. It writes every validated file record below extracted/files/ plus a manifest.json. It never parses or executes the contents. --include-internals also writes Bun's opaque source-map, bytecode, and module-info regions. Bun 1.3.3+ is supported.

Rewrite level

wakaru input.js --level minimal|standard|aggressive
wakaru input.js --dce                # full dead-code reachability sweep

See Rewrite levels.

Source maps

wakaru input.js --source-map input.js.map -o output.js
wakaru input.js --emit-source-map -o output.js
wakaru extract input.js.map -o src/
  • --source-map uses an input map for identifier recovery and import deduplication (single-file mode only).
  • --emit-source-map writes a .map alongside each output file, mapping output back to input. Works with --unpack.
  • wakaru extract writes the files embedded in a map's sourcesContent to disk. When the map carries original sources, this recovers them directly.

Vue SFC recovery (experimental)

wakaru input.js --vue-sfc                 # print .vue when recovery succeeds
wakaru input.js --vue-sfc -o App.vue      # Vue-only output; errors if recovery fails
wakaru bundle.js --unpack --vue-sfc -o out/   # additive .vue sidecars per recovered module

Best-effort Vue 3 render recovery. With a non-.vue output path, Wakaru writes normal JavaScript and adds a sibling .vue sidecar when recovery succeeds.

Output options

wakaru input.js --formatter -o output.js   # final formatting pass (off by default)
wakaru bundle.js --unpack --json -o out/   # machine-readable JSON to stdout

--json includes warnings and errors in the JSON object. In unpack mode, each module also gets an artifact kind and status. Useful for CI and tooling.

Diagnostics

wakaru input.js --diagnostics              # post-transform checks to stderr
wakaru input.js --profile trace.json       # Chrome trace; add --profile-rules for per-rule spans
wakaru debug validate out/                 # validate an unpacked output tree as one module graph
wakaru debug validate out/ --input bundle.js  # also report free identifiers that the input never left free

debug validate reports dangling references, broken imports/exports, duplicate declarations, writes to imported or const bindings, and free identifiers that exactly one other module declares at module scope. With --input, it also reports free identifiers that are not free anywhere in the original bundle. It exits nonzero when it finds anything. Validate normal output only: raw output has no module-graph contract.

Overwrite protection

Wakaru refuses to overwrite existing files or write into a non-empty output directory unless --force is passed.

On this page