A browser-based tool that takes a single monolithic .js file and generates a modular ES Module structure (index.js, core, features, utils) as a downloadable ZIP.
This project uses local support libraries from vendor/: Tailwind CSS, Acorn, acorn-walk, and JSZip.
- Accepts one JavaScript input file.
- Parses source code into an AST.
- Detects functions, classes, top-level calls, and top-level state.
- Builds a function call graph.
- Groups functions into clusters (
utils+featureN). - Generates modular files with imports/exports resolved.
- Shows generated folders/files before download.
- Exports a ZIP manually (no automatic download).
-
Pre-validation
- Parses the file first.
- Blocks if syntax is invalid.
- Emits warnings for risky patterns.
-
AST analysis
- Extracts top-level declarations.
- Separates function/class declarations from generic top-level code.
- Detects DOM selector declarations and state declarations.
-
Mobility analysis
- Detects functions that depend on top-level scoped state/DOM and marks them as non-movable.
-
Call graph & clustering
- Builds caller/callee relationships between discovered functions.
- Functions with high in-degree (>=2) are grouped into
utils. - Remaining functions are grouped by connected components and split by max size.
-
Module generation
- Maps each entity to target module paths.
- Optionally creates hierarchical feature folders when dependency count crosses threshold.
- Computes cross-module dependencies and required exports.
-
Runtime consolidation
- Consolidates non-movable code into a runtime module.
- Generates entrypoint
index.jswith imports and top-level calls.
-
Output preview & ZIP
- Renders generated tree (folders/files).
- Allows manual ZIP download.
The pre-check warns about patterns that can reduce transformation accuracy:
- very large files
- many top-level statements
- CommonJS usage (
require,module.exports,exports.*) - dynamic
import() eval()withstatements
If syntax parsing fails, modularization stops immediately.
The analyzer scans top-level AST nodes and records:
functionSourcesclassSources- top-level callable entries
- top-level state (especially
let-based declarations) - DOM element selector declarations
- other top-level code fragments
A function is marked non-movable if it references scoped top-level variables in a way that is not shadowed in local scope.
Those functions are later merged into runtime to preserve behavior.
utilscluster: functions called by multiple functions (in-degree >= 2).- feature clusters: connected components from bidirectional call relationships (caller + callee graph), chunked by max functions per module.
For each generated module, identifier references are analyzed to build import lists.
Exports are calculated from:
- top-level calls from entrypoint
- cross-module symbol usage
- runtime-accessed symbols
- Runtime file receives non-movable logic + required imports/exports.
- Entry
index.jsimports runtime and calls top-level functions in order.
The UI allows customizing:
- ZIP file name
- output root folder
- features folder name
- core folder name
- file naming style (
kebab,snake,camel) - hierarchy threshold (0 disables nested feature grouping)
- max functions per cluster
Best suited for:
- plain JavaScript files with top-level functions/classes
- front-end scripts needing first-step modular decomposition
- educational/refactoring workflows where structure matters more than bundler integration
- Works on one input file at a time.
- Does not generate test files.
- Does not update external build tooling (Webpack/Vite/Rollup config).
- Highly dynamic patterns may require manual review.
- Output is ES Modules and may need small manual edits in edge cases.
Generated modularized files use ES modules and cannot be executed directly with file://.
Use a local/remote web server instead.
Examples:
python3 -m http.server 8080npx serve .
This project uses local copies in vendor/:
| Library | Purpose | Local file |
|---|---|---|
| Tailwind CSS (browser build) | UI utility classes | vendor/tailwindcss.js |
| Acorn | JavaScript parser (AST) | vendor/acorn.min.js |
| acorn-walk | AST traversal helpers | vendor/acorn-walk.min.js |
| JSZip | ZIP generation in browser | vendor/jszip.min.js |
index.html— app shellassets/css/styles.css— UI stylessrc/core/runtime.js— UI logic + orchestration + pre-validationsrc/features/analyze-a-s-t.js— AST extraction & mobility analysissrc/features/create-clusters.js— call-graph clusteringsrc/features/generate-module-files.js— modular file synthesissrc/features/create-zip.js— ZIP generationsrc/utils.js— dependency/import utilities.github/workflows/deploy-pages.yml— GitHub Pages deployment workflow
Because this is a static app, no build is required.
- Serve the project directory with a local server.
- Open
index.htmlthrough HTTP (notfile://).
A workflow is already provided in .github/workflows/deploy-pages.yml.
- Push to
mainormaster. - In GitHub repository settings, set Pages source to GitHub Actions.
See LICENSE.