Expand description
Wakaru: a JavaScript decompiler exposed as a compiler-like service.
The stable crate root offers two end-to-end operations:
decompile— rewrite one minified/transpiled source into readable, modern JavaScript.unpack— split one or more bundle/chunk inputs into modules and decompile each;UnpackJobis the incremental intake form of the same operation for directory walkers.
Optional workflows live in cohesive namespaces: bun (single-file
executable extraction), debug (normalization, rule tracing, rule
metadata), sourcemap (embedded-source extraction), and vue
(experimental standalone SFC recovery).
The API is deliberately not an SWC transformation toolkit: it never exposes
SWC AST types, individual rewrite visitors, detector objects, prepared
ASTs, or cross-module fact structures. Partial recovery is represented
structurally (ModuleStatus, Diagnostic) instead of being hidden in
warning strings.
Design decisions, compatibility boundaries, and the internal processing
invariants behind this surface are recorded in docs/public-api.md.
§Publishing model
The façade is published as wakaru. Cargo cannot package a façade with an
unpublished path dependency, so wakaru-core is also published as a
lockstep, exact-version implementation dependency. It remains explicitly
unsupported as an integration surface and may change whenever the façade
version changes.
§Examples
Single-file decompile:
use wakaru::{decompile, DecompileOptions, Source};
let minified = String::from("var a=!0;");
let output = decompile(Source::new("input.js", minified), DecompileOptions::default())?;
println!("{}", output.module.code);
for diagnostic in output.diagnostics {
eprintln!("{}", diagnostic.message);
}Bundle/chunk set:
use wakaru::{
unpack, DceMode, ModuleMode, RewriteLevel, RewriteOptions, Source, UnmatchedInput,
UnpackMode, UnpackOptions,
};
let output = unpack(
vec![Source::new("entry.js", entry), Source::new("chunk.js", chunk)],
UnpackOptions::default()
.with_modules(ModuleMode::Decompile(
RewriteOptions::default()
.with_level(RewriteLevel::Standard)
.with_dce(DceMode::TransformOnly),
))
.with_mode(UnpackMode::Auto)
.with_unmatched(UnmatchedInput::Process)
.with_diagnostics(true),
)?;
for module in output.modules {
println!("{}: {} bytes", module.filename, module.code.len());
}Directory-style detected-only processing with bounded intake memory:
use wakaru::{InputAction, Source, UnmatchedInput, UnpackJob, UnpackOptions};
let mut job = UnpackJob::new(UnpackOptions::default().with_unmatched(UnmatchedInput::Skip))?;
for path in javascript_candidate_paths {
let code = std::fs::read_to_string(&path)?;
job.push(Source::new(path.to_string_lossy(), code))?;
}
let output = job.finish()?;
let skipped = output
.inputs
.iter()
.filter(|input| input.action == InputAction::Skipped)
.count();Modules§
- bun
- Extraction of Bun standalone module graphs from compiled executables.
- debug
- Debug workflows: parse/print normalization, per-rule tracing, and stable rule metadata.
- sourcemap
- Source-map utilities that do not require running an operation.
- vue
- Experimental standalone Vue 3 SFC recovery from compiled render modules.
Structs§
- Decompile
Options - Options for
decompile. - Decompile
Output - Result of
decompile. - Diagnostic
- A recoverable problem associated with an operation, input, or module.
- Error
- A fatal operation failure: invalid options, an unusable top-level input, or a failure that prevents Wakaru from returning a coherent result.
- InputId
- Identifies one input of one operation call.
- Input
Receipt - Immediate result of
UnpackJob::push, letting a walker report detection progress without waiting forfinish. - Input
Report - Per-input summary in
UnpackOutput::inputs, in input order. - Module
Output - One output module artifact.
- Rewrite
Options - Rewrite pipeline options:
RewriteLevelandDceMode. - Source
- An owned input file: filename, code, and an optional input source map.
- Source
Parts - The owned fields of a
Source, recovered viaSource::into_parts. - Source
Span - A byte range in one input source.
- Unpack
Job - Incremental intake form of
unpackfor directory walkers and other producers that should not retain every candidate source simultaneously. - Unpack
Options - Options for
unpackandUnpackJob. - Unpack
Output - Result of
unpack/UnpackJob::finish.
Enums§
- Bundle
Format - A structurally detected bundler format.
- DceMode
- Dead-code cleanup policy for the late pipeline phase.
- Diagnostic
Code - Diagnostic
Severity - Entry
Status - Whether a module is a bundle entry.
- Error
Kind - The category of a fatal operation failure.
- Input
Action - What the operation did with one input.
- Input
Detection - What detection concluded about one input.
- Module
Mode - How each selected module is processed.
- Module
Status - How this module artifact was produced.
- Output
Safety - Whether the output module graph is safe to execute.
- Rewrite
Level - Rewrite aggressiveness. Rules gate risky subpatterns internally rather
than moving entire rules in or out of the pipeline; see
docs/rewrite-assumptions.mdfor the named assumptions each level may rely on. - Unmatched
Input - Policy for inputs that are not recognized as a bundle.
- Unpack
Mode
Functions§
- decompile
- Decompile exactly one source module into readable, modern JavaScript.
- unpack
- Split one or more bundle/chunk inputs into modules and process each.