About This Space

:card_file_box: A javascript debundler. Takes a Browserify or Webpack bundle and recreates the initial, pre-bundled source.


Last updated on November 4, 2025

Forked from: /asdf/debundle-2/

Public Permissions:   View   Open/Fork   Run   Comment  

Debundle

A tool to extract and deobfuscate JavaScript bundles created with webpack.

Forked from mtgeee (@mtgeee)

This project is a fork of the original "debundle" by mtgeee. The upstream project provides a small CLI and library to parse webpack bundles, locate the module bootstrap, and extract individual module closures so bundles can be inspected and analyzed. See the original project page for background and examples: https://profoundjs.com/mtgeee/debundle/

This fork preserves the original extraction functionality while applying a few repository-specific adjustments:

  • Documentation and README cleanup to focus on the tools in this workspace
  • Removal of unrelated files found in the repository root
  • Addition of a heuristic renamer tool (creates dist-named/ and a mapping file) to produce friendlier filenames when original source maps are not available
  • Guidance to ignore generated outputs (dist/, dist-named/) in VCS

Features

  • Extracts individual modules from webpack bundles
  • Supports both array and object-based module collections
  • Provides AST manipulation utilities for bundle analysis
  • Error handling with detailed context information

Installation

npm install

Usage

Basic usage:

npx debundle path/to/your/bundle.js
~/Desktop/debundle$ npx debundle ../kgpckhbdfdhbkfkepcoebpabkmnbhoke/js/background.js
[LOG] Read bundle /home/rodriguesfa/Desktop/kgpckhbdfdhbkfkepcoebpabkmnbhoke/js/background.js (1133287 bytes)
[LOG] Looking for webpackBootstrap in bundle...
[LOG] Found webpackBootstrap!
[LOG] webpackBootstrap module call expression: r[e].call(t.exports, t, t.exports, a)
[LOG] Found 193 modules in main bundle
[LOG] Discovered module 0 (chunk ["default"])
[LOG] Discovered module 00ce (chunk ["default"], depends on a284, a645, 417f, and 22 more)
[LOG] Discovered module 04f8 (chunk ["default"], depends on 1212, d039, cfe9)
[LOG] Discovered module 057f (chunk ["default"], depends on c6b6, fc6a, 241c, and 1 more)
[LOG] Discovered module 06cf (chunk ["default"], depends on 83ab, c65b, d1e7, and 5 more)
[LOG] Discovered module 07bd (chunk ["default"], depends on f7b4)
[LOG] Discovered module 07fa (chunk ["default"], depends on 50c4)
[LOG] Discovered module 0a44 (chunk ["default"])
[LOG] Discovered module 0b16 (chunk ["default"], depends on 1985, 184d)
[LOG] Discovered module 0cfb (chunk ["default"], depends on 83ab, d039, cc12)
[LOG] Discovered module 0d25 (chunk ["default"])
[LOG] Discovered module 0d51 (chunk ["default"])
[LOG] Discovered module 0f7c (chunk ["default"], depends on 688e)
[LOG] Discovered module 1 (chunk ["default"])
[SNIP]
~/Desktop/debundle$ ls dist/ | tail 
default-f4e7.js
default-f772.js
default-f7b4.js
default-f9ae.js
default-faa1.js
default-fc6a.js
default-fdbf.js
default-fe77.js
default-fe92.js
default-ff5c.js

Renamer (heuristic) usage

If you used the renamer tool to produce friendlier filenames when source maps are unavailable, run the included script:

# run renamer on generated dist/ and write results to dist-named/
node tools/rename-dist.js dist
# optionally specify output directory:
node tools/rename-dist.js dist dist-named

The script copies files into the output folder and writes a mapping file:

  • <output-dir>/dist-name-map.json — JSON mapping original -> renamed filenames

The tool will:

  1. Read and parse the webpack bundle
  2. Extract individual modules
  3. Write deobfuscated files to dist/ directory
~/Desktop/debundle$ ls dist-named/ | tail 
default-f772_require.js
default-f7b4_Visitor.js
default-f9ae_require.js
default-faa1_once.js
default-fc6a_require.js
default-fdbf_require.js
default-fe77_x.js
default-fe92_i.js
default-ff5c_a.js
dist-name-map.json

Project Structure

  • src/utils.js - Core utilities for AST manipulation and error handling
  • dist/ - Output directory (auto-generated, should be git-ignored)

Development

Prerequisites

  • Node.js
  • npm/yarn

Important Notes

Generated files and directories that should be in .gitignore:

  • dist/
  • dist-named/
  • *.log

Library updates & code adaptation

This fork includes code and documentation updates to remain compatible with recent versions of the core libraries used for AST parsing, code generation and CLI output. Key notes and guidance for maintainers and contributors:

Vendored dependency replacement

The repository previously included a vendored copy of the small is-buffer module under is-buffer/. That vendored implementation has been removed in favor of the canonical npm package. Changes made:

  • package.json now includes a dependency on is-buffer.
  • The local is-buffer/index.js was replaced with a tiny shim (and then removed). You can install the dependency with npm install.

Why this change:

  • Keeps the repository smaller and avoids checked-in generated vendor code.
  • Lets npm manage updates and compatibility for the is-buffer package.

If you prefer the repository to be self-contained, you can re-vendor the package, but generally using the npm package is recommended.

  • Relevant libraries
    • espree (AST parsing)
    • escodegen (AST -> code generation)
    • cli-highlight (syntax highlighting for terminal output)
  • Compatibility
    • The codebase uses espree.parse with ecmaVersion: 'latest' and sourceType: 'script'. If you upgrade espree, confirm that the parse options and returned AST shapes are still compatible.
    • escodegen.generate is used to convert AST nodes back to code; newer versions remain mostly compatible but may change formatting or support additional node types.
    • cli-highlight options such as language and ignoreIllegals are passed directly; when updating, verify option names and behavior.
  • Recommended upgrade workflow
    1. Update package.json or run:
      npm install espree@latest escodegen@latest cli-highlight@latest --save
      
      or update via your package manager of choice.
    2. Reinstall deterministically:
      npm ci
      
    3. Run the test/usage flow:
      • Parse a representative bundle:
        npx debundle path/to/bundle.js
        
      • Run any existing unit tests or CLI usage scenarios you rely on.
    4. Inspect runtime behavior for edge cases (e.g., newer AST node types).
  • Code changes you may need to make after upgrades
    • espree: adjust parse options (e.g., ecmaVersion, sourceType, range, loc) if AST nodes differ.
    • escodegen: if newly supported node types are present, ensure generate() receives valid AST fragments; update cloneAst() patterns if necessary.
    • Highlighting: some terminals or library changes may require adjusting cli-highlight options.
  • Version pinning & reproducible installs
    • Pin major versions in package.json or keep lockfile (package-lock.json / yarn.lock) committed to ensure CI and collaborators reproduce the same behavior.
    • Run npm audit and npm audit fix as part of routine maintenance, but validate behavior after automated fixes.
  • Node.js compatibility
    • Test against the Node.js versions you intend to support. Some dependency upgrades may require newer Node releases.
  • Tests & validation
    • Add representative bundles to CI or local test scripts so upgrades are validated against real inputs.
    • Consider adding a small snapshot test that runs the renamer or parseBundleModules on sample bundles to detect regressions.

Error Handling

The tool uses ExtendedError class for detailed error reporting, providing:

  • Error name
  • Error message
  • Detailed description
  • Context information

Be the first to comment:      

Comments

Write Preview Markdown: bold italic code link
Post