Skip to main content

Crate wakaru

Crate wakaru 

Source
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; UnpackJob is 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§

DecompileOptions
Options for decompile.
DecompileOutput
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.
InputReceipt
Immediate result of UnpackJob::push, letting a walker report detection progress without waiting for finish.
InputReport
Per-input summary in UnpackOutput::inputs, in input order.
ModuleOutput
One output module artifact.
RewriteOptions
Rewrite pipeline options: RewriteLevel and DceMode.
Source
An owned input file: filename, code, and an optional input source map.
SourceParts
The owned fields of a Source, recovered via Source::into_parts.
SourceSpan
A byte range in one input source.
UnpackJob
Incremental intake form of unpack for directory walkers and other producers that should not retain every candidate source simultaneously.
UnpackOptions
Options for unpack and UnpackJob.
UnpackOutput
Result of unpack / UnpackJob::finish.

Enums§

BundleFormat
A structurally detected bundler format.
DceMode
Dead-code cleanup policy for the late pipeline phase.
DiagnosticCode
DiagnosticSeverity
EntryStatus
Whether a module is a bundle entry.
ErrorKind
The category of a fatal operation failure.
InputAction
What the operation did with one input.
InputDetection
What detection concluded about one input.
ModuleMode
How each selected module is processed.
ModuleStatus
How this module artifact was produced.
OutputSafety
Whether the output module graph is safe to execute.
RewriteLevel
Rewrite aggressiveness. Rules gate risky subpatterns internally rather than moving entire rules in or out of the pipeline; see docs/rewrite-assumptions.md for the named assumptions each level may rely on.
UnmatchedInput
Policy for inputs that are not recognized as a bundle.
UnpackMode

Functions§

decompile
Decompile exactly one source module into readable, modern JavaScript.
unpack
Split one or more bundle/chunk inputs into modules and process each.

Type Aliases§

Result