Wakaru, a Rust decompiler that undoes Babel and esbuild output
🔪📦 Javascript decompiler for modern frontend
At a glance
- What is it?
- Wakaru is a JavaScript decompiler that rewrites the AST to recover modern syntax and split production bundles into modules, built on swc and distributed as a CLI, an npm package and a Rust crate. What makes it credible is the test methodology rather than the feature list, with 62,171 Test262 round trips and a measured pattern recovery rate.
- Who is it for?
- Wakaru suits a developer or security reviewer who needs to read what a site or a dependency actually ships, since it handles the bundler outputs that are genuinely in production today and reports a measured recovery rate rather than a promise.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A decompiler that works by rewriting the AST
Wakaru is a JavaScript decompiler, and the description in one line is unpack, unminify, understand. It splits production bundles into modules and restores readable, modern syntax from minified and transpiled code.
The mechanism is AST rewriting rather than text manipulation. Wakaru rewrites the JavaScript AST to recover modern syntax, remove recognized runtime helpers, and split supported bundles into modules. That distinction matters, because a text based unminifier has to guess where the boundaries are, while an AST level tool knows that a function expression is a function expression and can rewrite the parent accordingly.
The example in the README makes the difference visible. The minified Babel input is a single line of CommonJS with a helper function that wraps another helper function to emulate generators, plus a null check written out longhand:
var loadProfile=function(){var e=_asyncToGenerator(function*(e){var t=yield _api.default.fetchUser(e),r=null!=t.name?t.name:"anonymous";return{name:r,avatar:null==t.profile?void 0:t.profile.avatar}});return function(t){return e.apply(this,arguments)}}();exports.loadProfile=loadProfile;And the output is:
import _api from "./api";
export const loadProfile = async (e)=>{
const t = await _api.fetchUser(e);
const name = t.name ?? "anonymous";
return {
name,
avatar: t.profile?.avatar
};
};The helpers become async and await, the null checks become ?? and ?., and the CommonJS imports and exports become ESM. The README is honest about the limit of this: some names, such as e and t, stay short because the input does not provide their original names. That is the fundamental constraint of decompilation, and a tool that pretends otherwise would be misleading.
The implementation is Rust, built on swc, and the version is 1.14.0 with a 2021 edition.
What it handles, and what it deliberately leaves to other tools
The supported inputs are grouped into three categories. For bundles, Wakaru splits webpack, esbuild and Bun, Browserify, and Metro output into readable modules. For transpiled code, it recovers modern syntax from Babel, TypeScript and SWC output. For minified code, it expands compact expressions and simplifies control flow.
The project is explicit about the boundary with obfuscation, and this is where the README earns trust. Wakaru focuses on minifier and transpiler recovery, and for supported obfuscation patterns a deobfuscator such as webcrack can prepare the input before Wakaru processes it. Heavy control-flow or VM-based obfuscation needs a dedicated approach.
That is an honest division of labour. A decompiler that understands what a minifier does is in a completely different position from one that has to model a virtual machine interpreter, and the README says which side of the line it is on.
The same clarity applies to naming. For AI-assisted identifier naming the README points at humanify, and it says plainly that inferred names are reading aids while source maps are the source of original names when available. So the tool does not invent variable names and does not pretend its inference is authoritative. There is a dedicated guide on source maps, and another on obfuscated code, and the CLI reference covers rewrite levels, source maps and more options.
The use cases are listed in three. Security and supply-chain review, meaning inspecting the JavaScript a site or dependency ships, with supported bundles split into modules. Debugging third-party SDKs, following the code behind a stack trace or investigating behaviour in a distributed build. And source recovery, recovering readable modules when only build artefacts remain, or extracting original files embedded in source maps.
That last one is worth pausing on, because it changes what the tool is for. If a source map is present, the original files can be extracted rather than reconstructed, and reconstruction is the fallback for when they are not.
The measurement behind the claims
The README has a section headed tested like a compiler, and it is the most persuasive part of the page because it describes a method rather than a feature list. The project tests both behavior and recovery against real compiler and minifier output, and it gives two numbers with links to the underlying data.
The first is 62,171 passing Test262 semantic round trips, with the methodology and a baseline documented in docs/test262-roundtrip.md. Test262 is the ECMAScript conformance test suite, and a round trip means taking a test case, running it through the tool's transformation and back, and checking the semantics are preserved. That is the right kind of test for a tool that rewrites code, because a decompiler that changes the meaning of a program is worse than useless, and a conformance suite is the closest available proxy for the language's whole semantics.
The second is 94.6% pattern recovery across 2,991 transpiler times minifier test shapes, with the per-matrix results in scripts/repro/stats.json. The phrase test shapes is the important word. A decompiler has to recognise the specific output patterns that Babel, TypeScript, SWC and the common minifiers produce, and the only meaningful way to claim coverage is to enumerate the cross product of transpiler and minifier and report how many of those patterns are recovered. 2,991 shapes is a matrix, and 94.6% is a measured rate with a known remainder.
That remainder is what a user should care about. Five and a half percent of patterns are not recovered, and the per-matrix file is where you would look to see whether the missing ones are in the combination you actually have.
The repository layout supports the claim. There is a testcases/ directory, a scripts/ directory with the reproduction tooling, examples/ with basic.js, and a design/ directory. The Cargo.toml also shows the dev profile being tuned around link cost, with a comment that full DWARF is the dominant link cost across the 90 or more swc_core-linked test binaries, and line-tables keeping panic backtraces with file and line while cutting debuginfo generation.
Packaging, the CLI, and the skill
The quick start shows the tool being run without a global install, and the three forms cover the three situations you meet:
npx wakaru input.js -o output.js # decompile a file
npx wakaru bundle.js --unpack -o out/ # unpack and decompile a bundle
npx wakaru dist/ --unpack -o out/ # scan a bundle output directoryThe third form is the one to note. Pointing it at a directory rather than a file means scanning a build output tree, which is what you have when the thing you want to read is a whole dist/ folder with chunks in it.
For regular use the CLI installs globally with npm install -g wakaru@latest, and standalone binaries are available from GitHub Releases. The npm package is published as @wakaru/cli.
There is also a playground at wakarujs.com/playground, which is the fastest way to see what the tool does without installing anything.
The most recent addition is the agent integration. The README explains the reasoning: give your coding agent readable modules to search and inspect, and with the Wakaru skill it can unpack a bundle and focus on the files relevant to your question, keeping unrelated code out of context. The install is:
npx skills add pionxzh/wakaruThat is a meaningful framing. An agent working on a minified bundle directly has to fit the whole thing into a context window, whereas an agent working on unpacked modules can be pointed at the module with the question in it. The skill makes the decompilation step part of the agent's toolchain rather than something you do by hand before handing over.
The repository has a skills/ directory for this, alongside crates/ for the Rust workspace, npm/ for the package, playground/ for the web version, docs/ and docs-site/ for documentation, and a rust-toolchain.toml pinning the compiler.
Where it stops, and the terms attached to it
The limits are stated in several places and they are consistent.
Obfuscation beyond the recognised patterns is out of scope, and the README says so directly. Original variable names are not recoverable without a source map, and the tool says so rather than guessing. And the package inventory feature, which would identify which npm packages and versions a production bundle contains, is under development and explicitly not part of the current release, with a template for sharing use cases and an address to shape its scope.
That last feature is the interesting gap, because a bundle's dependency list is often the most actionable thing about it for a reviewer, and shipping it would turn Wakaru from a reader into an inventory tool. The project is being careful about scope and priority for it, which is the right way to handle a feature that would need a dependency fingerprint database.
The licence is Apache-2.0. And there is a note at the end of the README that is worth quoting because it states the boundary the project draws: usage of Wakaru for attacking targets without prior mutual consent is illegal, and end users are responsible for complying with all applicable laws.
That note is consistent with the use cases as listed, which are review, debugging and source recovery. A reviewer looking at what a dependency ships, a developer following a stack trace into a third party SDK, or someone recovering source from their own build artefacts are all legitimate uses. The same command applied to someone else's production target without permission is not, and the project says so in one line rather than leaving it implied.
The maintenance signals are healthy. The last push was on 2026-10-13, the release tags are v1.14.0 from 2026-10-10, v1.13.0 from 2026-10-01 and v1.12.0 from 2026-09-13, and the version in Cargo.toml is 1.14.0 with a workspace layout of crates/* under resolver version 2. The project also maintains a CHANGELOG.md, a CONTRIBUTING.md that asks for bug reports to include the input, command, current output and expected behavior, a CLAUDE.md and an AGENTS.md, and there is a Telegram group linked from the README.
Editorial conclusion
Wakaru suits a developer or security reviewer who needs to read what a site or a dependency actually ships, since it handles the bundler outputs that are genuinely in production today and reports a measured recovery rate rather than a promise. It is the wrong tool for obfuscated code, because the README says heavy control-flow or VM-based obfuscation needs a dedicated approach and points at webcrack for the supported subset, and it is the wrong tool if you need the original variable names, since a source map is the only source of those. Before running it on something, check whether a source map exists, because the tool can extract the original files outright in that case, and read the rewrite level options in the CLI reference, since a higher rewrite level changes more than a lower one.
Frequently asked questions
How do I decompile a JavaScript file with Wakaru?
Run npx wakaru input.js -o output.js to decompile a file, npx wakaru bundle.js --unpack -o out/ to unpack and decompile a bundle, and npx wakaru dist/ --unpack -o out/ to scan a bundle output directory. For regular use the CLI installs globally with npm install -g wakaru@latest.
Which bundlers and transpilers does Wakaru support?
For bundles it splits webpack, esbuild and Bun, Browserify, and Metro output into modules. For transpiled code it recovers modern syntax from Babel, TypeScript and SWC output, and for minified code it expands compact expressions and simplifies control flow.
Can Wakaru recover the original variable names?
Not by itself. The README says some names stay short because the input does not provide their original names, and that inferred names from tools like humanify are reading aids, while source maps are the source of original names when available.
How is the project tested?
Against real compiler and minifier output, with 62,171 passing Test262 semantic round trips and 94.6% pattern recovery across 2,991 transpiler and minifier test shapes. The methodology is documented in docs/test262-roundtrip.md and the per-matrix results in scripts/repro/stats.json.
What does Wakaru do with obfuscated code?
It focuses on minifier and transpiler recovery. For supported obfuscation patterns the README suggests a deobfuscator such as webcrack can prepare the input first, and heavy control-flow or VM-based obfuscation needs a dedicated approach.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pionxzh-wakaru)Was this useful?