Unpack. Unminify. Understand.
Fast JavaScript decompiler and bundle splitter for modern frontend.
npx @wakaru/cli input.js -o output.js # decompile a file
npx @wakaru/cli bundle.js --unpack -o out/ # unpack and decompile a bundle
npx @wakaru/cli dist/ --unpack -o out/ # scan a bundle output directory- β Bundle splitting β webpack 4/5, esbuild, Bun, Browserify
- β Transpiler & minifier recovery β Terser, Babel, SWC, TypeScript
- β Source map support for better names & import deduplication
- β
Rewrite levels:
minimal|standard|aggressive
Production JavaScript is hard to read because multiple tools have transformed it:
- Bundlers collapse many modules into one file and inject runtime wrappers
- Transpilers downgrade modern syntax and insert helper functions
- Minifiers erase names, fold constants, and compress control flow
Wakaru handles all three in a single command β feed it a bundle, get back readable modules.
npm install -g @wakaru/cli@latestOr pre-built binaries from GitHub Releases.
wakaru input.js -o output.jsWithout -o, output goes to stdout. Stdin is also supported:
cat input.js | wakaru > output.jswakaru bundle.js --unpack -o out/
wakaru bundle.js --unpack --raw -o out/ # raw split, no readability transforms
wakaru entry.js chunk.js --unpack -o out/ # unpack multiple explicit files
wakaru dist/ --unpack -o out/ # recursively scan a directoryDirectory inputs are supported only with --unpack. Wakaru recursively scans
.js, .mjs, and .cjs files, skips hidden files/directories and
node_modules, and includes only files detected as bundles or chunks. Skipped
files are not copied or decompiled. Explicit file inputs keep the normal
fallback behavior when no bundle format is detected.
wakaru input.js --formatter -o output.js
wakaru bundle.js --unpack --formatter -o out/--formatter runs a final formatting pass after decompilation. Off by default.
wakaru input.js --source-map input.js.map -o output.jsSource maps enable identifier recovery and import deduplication. They are currently supported only with a single input file.
wakaru extract input.js.map -o src/Writes files embedded in the source map's sourcesContent to disk.
Wakaru offers three rewrite levels so you can choose the right tradeoff for your use case:
| Level | When to use |
|---|---|
minimal |
You need near-zero semantic changes β only safe, obvious transforms. Good for auditing or diffing where behavioral fidelity matters most. |
standard |
Default. Balanced readability and correctness for most use cases. |
aggressive |
You just want to read the code. Enables stronger intent-recovery heuristics that produce cleaner output but may alter edge-case behavior. |
wakaru input.js --level minimal
wakaru input.js --level standard # default
wakaru input.js --level aggressiveWakaru refuses to overwrite existing files unless --force is passed.
Every kind of contribution is welcome.
Some areas where help is especially useful:
- Share real-world bundles that Wakaru doesn't handle well
- Report missing helper detection or false positives
- Report semantic or correctness issues
When reporting a bug, please include: the input code, the command you ran, the current output, and what you expected instead.
Development setup
- Fork the repo and create your branch from
main - Install a stable Rust toolchain
- Run
cargo testto verify everything passes - Make your changes and add tests
Before submitting a PR:
cargo test
cargo clippy -- -D warningsThis project uses Conventional Commits. Please mention the issue number in the commit message or PR description.
Docs: architecture.md | testing.md | helper-detection.md
Usage of wakaru for attacking targets without prior mutual consent is illegal. End users are responsible for complying with all applicable laws.