pith. sign in

arxiv: 2107.10164 · v1 · submitted 2021-07-21 · 💻 cs.SE

Automated Refactoring of Legacy JavaScript Code to ES6 Modules

Pith reviewed 2026-05-24 13:20 UTC · model grok-4.3

classification 💻 cs.SE
keywords JavaScript refactoringES6 modulesstatic analysisModule Dependence Graphcode migrationfine-grained reusemodule coupling
0
0 comments X

The pith

Legacy JavaScript code can be automatically refactored to ES6 modules to support fine-grained reuse and lower module coupling.

A machine-rendered reading of the paper's core claim, the machinery that carries it, and where it could break.

The paper develops a method to migrate legacy ES5 JavaScript projects to native ES6 module syntax. It builds a Module Dependence Graph from static analysis of the code, then uses that graph to drive transformations that replace module objects with named imports and exports. The intent is to make individual module features directly reusable and to tighten the dependencies between modules. Evaluation across 19 open-source projects reports more reusable elements after refactoring, reduced coupling, and passing test suites with manual inspection confirming the changes.

Core claim

Using the Module Dependence Graph constructed by static analysis, the refactoring procedure migrates legacy modules to ES6 syntax, producing an increase in the number of reusable elements per project, a reduction in the coupling of refactored modules, and empirically validated soundness through code inspection and execution of the projects' test suites.

What carries the argument

The Module Dependence Graph (MDG), a model of modules and their dependencies built via static analysis, which drives the specification of the refactoring to ES6 named import/export constructs.

If this is right

  • Refactored modules exhibit lower coupling through destructuring of exported objects into named features.
  • Each project gains a larger number of directly reusable module elements.
  • Build configurations become simpler because native ES6 module syntax replaces earlier design patterns.
  • The refactoring preserves program behavior as confirmed by test-suite execution.

Where Pith is reading between the lines

These are editorial extensions of the paper, not claims the author makes directly.

  • Projects that adopt this migration could see easier long-term maintenance when new developers rely on standard module syntax.
  • The same dependence-graph technique might extend to other module-format migrations beyond ES6.
  • Tooling that automates the MDG construction step could be integrated into existing JavaScript build pipelines.

Load-bearing premise

Static analysis can accurately identify all module dependencies and usages even when JavaScript code uses dynamic features.

What would settle it

Execution of the original test suites on any of the 19 projects after refactoring produces failures that trace to missed dependencies in the Module Dependence Graph.

Figures

Figures reproduced from arXiv: 2107.10164 by E. A. Giakoumakis, Katerina Paltoglou, N. A. Diamantidis, Vassilis E. Zafeiris.

Figure 1
Figure 1. Figure 1: Declaration and access to global variables in ES5. [PITH_FULL_IMAGE:figures/full_fig_p005_1.png] view at source ↗
Figure 2
Figure 2. Figure 2: Module definition and loading using the CJS format. [PITH_FULL_IMAGE:figures/full_fig_p006_2.png] view at source ↗
Figure 3
Figure 3. Figure 3: Module definition and loading using the AMD format. [PITH_FULL_IMAGE:figures/full_fig_p008_3.png] view at source ↗
Figure 4
Figure 4. Figure 4: Module definition of Fig [PITH_FULL_IMAGE:figures/full_fig_p009_4.png] view at source ↗
Figure 5
Figure 5. Figure 5: Motivating example from the project planck.js. fragments from the Solver.js module and its dependencies. Solver.js is a core module of planck.js and uses declarations from 9 modules of the same project, e.g. it reads configuration properties from the Settings.js module and uses utility functions for vector calculations from the Vec2.js module. The code is based on the CJS module format, where the reusable … view at source ↗
Figure 6
Figure 6. Figure 6: Namespace object variants for MathUtils module in goojs project. Let ei be the module object of a module mi and Fi the identified module features. The module object destructuring algorithm computes the set Fi for a module mi and can be summarized as following: Step 1. Evaluate module object destructuring preconditions (see Section 4.1.4). If any precondition fails then return Fi = {ei}, i.e., the module ob… view at source ↗
Figure 7
Figure 7. Figure 7: presents a fragment of the MDG constructed during this stage for the project planck.js. The fragment focuses on module Math, its outgoing dependencies and a subset of its incoming dependencies from other modules. The module’s outgoing dependencies correspond to the module features that are imported and used in the module, while incoming dependencies correspond to the module’s features that are exported to … view at source ↗
Figure 8
Figure 8. Figure 8: Module definition and exported feature migration i [PITH_FULL_IMAGE:figures/full_fig_p018_8.png] view at source ↗
Figure 9
Figure 9. Figure 9: Migration of module exports syntax in CJS modules. [PITH_FULL_IMAGE:figures/full_fig_p018_9.png] view at source ↗
Figure 10
Figure 10. Figure 10: Factory object in Vec2 module of planck.js project. that serves a domain-specific functionality and does not include bindings to the this reference. Furthermore, its prototype object is not extended within the module scope. Bound properties to this module object are, also, extracted and exported as separate module features after refactoring. However, due to the generic structure of utility objects, we can… view at source ↗
read the original abstract

The JavaScript language did not specify, until ECMAScript 6 (ES6), native features for streamlining encapsulation and modularity. Developer community filled the gap with a proliferation of design patterns and module formats, with impact on code reusability, portability and complexity of build configurations. This work studies the automated refactoring of legacy ES5 code to ES6 modules with fine-grained reuse of module contents through the named import/export language constructs. The focus is on reducing the coupling of refactored modules through destructuring exported module objects to fine-grained module features and enhancing module dependencies by leveraging the ES6 syntax. We employ static analysis to construct a model of a JavaScript project, the Module Dependence Graph (MDG), that represents modules and their dependencies. On the basis of MDG we specify the refactoring procedure for module migration to ES6. A prototype implementation has been empirically evaluated on 19 open source projects. Results highlight the relevance of the refactoring with a developer intent for fine-grained reuse. The analysis of refactored code shows an increase in the number of reusable elements per project and reduction in the coupling of refactored modules. The soundness of the refactoring is empirically validated through code inspection and execution of projects' test suites.

Editorial analysis

A structured set of objections, weighed in public.

Desk editor's note, referee report, simulated authors' rebuttal, and a circularity audit. Tearing a paper down is the easy half of reading it; the pith above is the substance, this is the friction.

Referee Report

2 major / 2 minor

Summary. The paper claims that legacy ES5 JavaScript can be automatically refactored to ES6 modules via a statically constructed Module Dependence Graph (MDG) to enable fine-grained named imports/exports, thereby increasing the number of reusable elements per project and reducing module coupling. The refactoring procedure is defined on the MDG; soundness is asserted via code inspection and test-suite execution on 19 open-source projects.

Significance. If the empirical results hold under the stated conditions, the work supplies a concrete, tool-supported migration path for a large body of legacy JavaScript codebases, directly addressing modularity and reuse pain points that predate native ES6 modules. The evaluation on real projects with test validation is a positive indicator of practical utility.

major comments (2)
  1. [MDG construction and refactoring procedure (as described in the method and evaluation sections)] The refactoring procedure is defined on the MDG obtained by static analysis. Because JavaScript permits dynamic module resolution (variable require paths, computed property accesses, indirect exports via bracket notation or eval), the static MDG construction necessarily under-approximates dependencies. The soundness argument (code inspection plus test-suite runs on the 19 projects) therefore only validates the subset of behaviors captured by the static pass; untested dynamic paths remain a correctness risk.
  2. [Evaluation on 19 projects and analysis of refactored code] The central claim that the refactoring reduces coupling and increases reusable elements rests on the assumption that the MDG accurately models all relevant module usages. If the static analysis misses a dependency or usage, the subsequent destructuring of exported objects can silently change observable behavior, undermining the reported metric improvements.
minor comments (2)
  1. [Results and analysis of refactored code] Clarify the precise definitions and formulas used to compute 'number of reusable elements' and 'coupling' before and after refactoring; the current description leaves the metrics open to interpretation.
  2. [Threats to validity or limitations discussion] The paper should explicitly list the JavaScript dynamic features that were assumed absent or handled conservatively by the static analyzer.

Simulated Author's Rebuttal

2 responses · 0 unresolved

We thank the referee for the constructive feedback on the limitations of static analysis. We address each major comment below and indicate where revisions will be made.

read point-by-point responses
  1. Referee: [MDG construction and refactoring procedure (as described in the method and evaluation sections)] The refactoring procedure is defined on the MDG obtained by static analysis. Because JavaScript permits dynamic module resolution (variable require paths, computed property accesses, indirect exports via bracket notation or eval), the static MDG construction necessarily under-approximates dependencies. The soundness argument (code inspection plus test-suite runs on the 19 projects) therefore only validates the subset of behaviors captured by the static pass; untested dynamic paths remain a correctness risk.

    Authors: We agree that JavaScript's support for dynamic constructs means the static MDG necessarily under-approximates some dependencies. The refactoring and its validation are scoped to the statically analyzable portion of each project; test-suite execution and code inspection confirm preservation of observable behavior for those cases. We will revise the manuscript to add an explicit limitations subsection that enumerates the dynamic patterns not handled and clarifies the scope of the soundness argument. revision: yes

  2. Referee: [Evaluation on 19 projects and analysis of refactored code] The central claim that the refactoring reduces coupling and increases reusable elements rests on the assumption that the MDG accurately models all relevant module usages. If the static analysis misses a dependency or usage, the subsequent destructuring of exported objects can silently change observable behavior, undermining the reported metric improvements.

    Authors: The coupling and reusability metrics are computed directly from the MDG and the transformations applied to its edges and nodes. Any missed dynamic usage simply leaves the corresponding code unchanged, so the reported deltas reflect only the statically captured modules. We will revise the evaluation section to state this scope explicitly and to note that the test-suite results provide empirical support within the analyzed subset, while acknowledging that unmodeled dynamic behavior could affect metrics in other codebases. revision: yes

Circularity Check

0 steps flagged

No circularity detected in derivation or evaluation chain

full rationale

The paper defines a static-analysis-based MDG construction followed by a refactoring procedure to ES6 modules, then evaluates the resulting transformations empirically on 19 independent open-source projects via code inspection and test-suite execution. No equations, fitted parameters presented as predictions, self-definitional steps, or load-bearing self-citations appear in the described chain. The central claims rest on external project data rather than reducing to the method's own inputs by construction.

Axiom & Free-Parameter Ledger

0 free parameters · 1 axioms · 1 invented entities

The paper introduces the MDG as a central construct but relies on the domain assumption of static analyzability.

axioms (1)
  • domain assumption JavaScript code can be statically analyzed to build an accurate model of module dependencies for the purpose of refactoring.
    The entire approach depends on the MDG being a faithful representation, which is a standard but not always true assumption in dynamic languages like JS.
invented entities (1)
  • Module Dependence Graph (MDG) no independent evidence
    purpose: To represent modules and their dependencies for guiding the refactoring process.
    New model introduced in the paper for this task.

pith-pipeline@v0.9.0 · 5768 in / 1208 out tokens · 26539 ms · 2026-05-24T13:20:54.223536+00:00 · methodology

discussion (0)

Sign in with ORCID, Apple, or X to comment. Anyone can read and Pith papers without signing in.

Reference graph

Works this paper leans on

50 extracted references · 50 canonical work pages

  1. [1]

    Wirfs-Brock, B

    A. Wirfs-Brock, B. Eich, Javascript: The first 20 years, Proc. ACM Pro- gram. Lang. 4 (2020). doi: 10.1145/3386327

  2. [2]

    ECMAScript 2015 Language Specification, https://www.ecma- international.org/ecma-262/ 6.0/, June 2015

  3. [3]

    MDN Web Docs, Javascript reference, https://developer.mozilla .org/en- US/docs/Web/ JavaScript/Reference, 2020

  4. [4]

    Node.js v12.6.0 Documentation: ECMAScript Modules, https://nodejs.org/api/esm.html, Accessed: July 2020

  5. [5]

    Asynchronous Module Definition (AMD) API, https://github.com/amdjs/amdjs-api, Accessed: July 2020

  6. [6]

    Node.js Documentation: CommonJS Modules, https://nodejs.org/api/modules.html, 2019

  7. [7]

    Rauschmayer, Exploring ES6

    A. Rauschmayer, Exploring ES6. Upgrade to the next version of JavaScript, 2015

  8. [8]

    Shore, Fail fast, IEEE Software 21 (2004) 21–25

    J. Shore, Fail fast, IEEE Software 21 (2004) 21–25. doi:10.1109/MS.2004.1331296. 33

  9. [9]

    T. Mens, T. Tourw´ e, A survey of software refactoring, IEEE Transactions on software engineering 30 (2004) 126–139

  10. [10]

    Fowler, Refactoring: Improving the Design of Existing Code, 1st ed., Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA, 1999

    M. Fowler, Refactoring: Improving the Design of Existing Code, 1st ed., Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA, 1999

  11. [11]

    Fowler, Refactoring: Improving the Design of Existing Code, 2nd ed., Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA, 2018

    M. Fowler, Refactoring: Improving the Design of Existing Code, 2nd ed., Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA, 2018

  12. [12]

    Sousa, W

    L. Sousa, W. Oizumi, A. Garcia, A. Oliveira, D. Cedrim, C. Lucena, When are smells indicators of architectural refactoring opportunities: A study of 50 software projects, in: Proceedings of the 28th Internationa l Conference on Program Comprehension, 2020, pp. 354–365

  13. [13]

    Soares, M

    E. Soares, M. Ribeiro, G. Amaral, R. Gheyi, L. Fernandes, A. Ga rcia, B. Fonseca, A. Santos, Refactoring test smells: A perspective fr om open- source developers, in: Proceedings of the 5th Brazilian Symposium o n Systematic and Automated Software Testing, 2020, pp. 50–59

  14. [14]

    Bavota, A

    G. Bavota, A. De Lucia, M. Di Penta, R. Oliveto, F. Palomba, An e x- perimental investigation on the innate relationship between quality a nd refactoring, Journal of Systems and Software 107 (2015) 1–14

  15. [15]

    Lacerda, F

    G. Lacerda, F. Petrillo, M. Pimenta, Y. G. Gu´ eh´ eneuc, Code s mells and refactoring: A tertiary systematic review of challenges and obser vations, Journal of Systems and Software 167 (2020)

  16. [16]

    Fernandes, A

    E. Fernandes, A. Ch´ avez, A. Garcia, I. Ferreira, D. Cedrim, L. Sousa, W. Oizumi, Refactoring effect on internal quality attributes: What h aven’t they told you yet?, Information and Software Technology (2020) 106347

  17. [17]

    Agnihotri, A

    M. Agnihotri, A. Chug, A systematic literature survey of softw are metrics, code smells and refactoring techniques, Journal of Information P rocessing Systems 16 (2020) 915–934

  18. [18]

    A. A. B. Baqais, M. Alshayeb, Automatic software refactoring : a systematic literature review, Software Quality Journal 28 (2020) 459–502

  19. [19]

    C. Abid, V. Alizadeh, M. Kessentini, T. do Nascimento Ferreira, D . Dig, 30 years of software refactoring research:a systematic literature review, 2020. arXiv:2007.02194

  20. [20]

    R. S. Nasagh, M. Shahidi, M. Ashtiani, A fuzzy genetic automatic refac- toring approach to improve software maintainability and flexibility, So ft Computing (2020) 1–31

  21. [21]

    B. R. Bruce, T. Zhang, J. Arora, G. H. Xu, M. Kim, Jshrink: In- depth investigation into debloating modern java applications, in: Proceedin gs of the 28th ACM Joint Meeting on European Software Engineering Conf erence and Symposium on the Foundations of Software Engineering, ESEC/ FSE 2020, ACM, 2020, p. 135–146. 34

  22. [22]

    de Freitas Brito, A

    A. de Freitas Brito, A. C. Hora, M. T. Valente, Refactoring gra phs: As- sessing refactoring over time, 2020 IEEE 27th International Con ference on Software Analysis, Evolution and Reengineering (SANER) (2020) 36 7–377

  23. [23]

    D. M. B. Paiva, A. P. Freire, R. P. de Mattos Fortes, Accessibilit y and software engineering processes: A systematic literature review, Journal of Systems and Software (2020) 110819

  24. [24]

    Ivers, I

    J. Ivers, I. Ozkaya, R. L. Nord, C. Seifried, Next generation automated soft- ware evolution refactoring at scale, in: Proceedings of the 28th AC M Joint Meeting on European Software Engineering Conference and Sympo sium on the Foundations of Software Engineering, 2020, pp. 1521–1524

  25. [25]

    M. Ying, J. Miller, Refactoring legacy ajax applications to improve the efficiency of the data exchange component, Journal of Systems a nd Software 86 (2013) 72–88

  26. [26]

    N. G. Obbink, I. Malavolta, G. L. Scoccia, P. Lago, An extensible approach for taming the challenges of javascript dead code elimination, in: 201 8 IEEE 25th International Conference on Software Analysis, Evolu tion and Reengineering (SANER), 2018, pp. 291–401

  27. [27]

    Vazquez, A

    H. Vazquez, A. Bergel, S. Vidal, J. Pace, C. Marcos, Slimming jav ascript applications: an approach for removing unused functions from jav ascript libraries, Information and Software Technology (2018)

  28. [28]

    Feldthaus, T

    A. Feldthaus, T. Millstein, A. Møller, M. Sch¨ afer, F. Tip, Tool-su pported refactoring for javascript, in: Proceedings of the 2011 ACM Int. Conf. on Object Oriented Programming Systems Languages and Applicatio ns, OOPSLA ’11, ACM, 2011, pp. 119–138

  29. [29]

    Feldthaus, A

    A. Feldthaus, A. Møller, Semi-automatic rename refactoring fo r javascript, SIGPLAN Not. 48 (2013) 323–338

  30. [30]

    S. H. Jensen, P. A. Jonsson, A. Møller, Remedying the eval tha t men do, in: Proceedings of the 2012 Int. Symp. on Software Testing and An alysis, ISSTA 2012, ACM, 2012, pp. 34–44

  31. [31]

    Gallaba, A

    K. Gallaba, A. Mesbah, I. Beschastnikh, Don’t call us, we’ll call y ou: Characterizing callbacks in javascript, in: 2015 ACM/IEEE Int. Sym p. on Empirical Software Engineering and Measurement (ESEM), 2015

  32. [32]

    Brodu, S

    E. Brodu, S. Fr´ enot, F. Obl´ e, Toward automatic update fr om callbacks to promises, in: Proceedings of the 1st Workshop on All-Web Real-Tim e Systems, A WeS ’15, ACM, 2015

  33. [33]

    Gallaba, Q

    K. Gallaba, Q. Hanam, A. Mesbah, I. Beschastnikh, Refactorin g asyn- chrony in javascript, in: 2017 IEEE Int. Conf. on Software Mainte nance and Evolution (ICSME), 2017, pp. 353–363. 35

  34. [34]

    Rostami, L

    S. Rostami, L. Eshkevari, D. Mazinanian, N. Tsantalis, Detectin g Func- tion Constructors in JavaScript, in: 2016 IEEE Int. Conf. on Soft ware Maintenance and Evolution (ICSME), 2016, pp. 488–492

  35. [35]

    L. H. Silva, M. T. Valente, A. Bergel, Statically identifying class de pen- dencies in legacy javascript systems: First results, in: 2017 IEEE 2 4th Int. Conf. on Software Analysis, Evolution and Reengineering (SANER), 2017

  36. [36]

    L. H. Silva, M. T. Valente, A. Bergel, N. Anquetil, A. Etien, Ident ify- ing classes in legacy JavaScript code, Journal of Software: Evolut ion and Process 1 (2017) 1–37

  37. [37]

    L. H. Silva, M. T. Valente, A. Bergel, Refactoring legacy JavaSc ript code to use classes: The good, the bad and the ugly, in: 16th Int. Conf. on Software Reuse (ICSR), 2017, pp. 1–16

  38. [38]

    Paltoglou, V

    A. Paltoglou, V. E. Zafeiris, E. A. Giakoumakis, N. Diamantidis, Au to- mated refactoring of client-side javascript code to es6 modules, in : 2018 IEEE 25th Int. Conf. on Software Analysis, Evolution and Reengine ering (SANER), IEEE, 2018, pp. 402–412

  39. [39]

    Rauschmayer, Speaking JavaScript, 1st ed., O’Reilly Media, In c., 2014

    A. Rauschmayer, Speaking JavaScript, 1st ed., O’Reilly Media, In c., 2014

  40. [40]

    Osmani, Learning JavaScript Design Patterns, O’Reilly Media, I nc., 2012

    A. Osmani, Learning JavaScript Design Patterns, O’Reilly Media, I nc., 2012

  41. [41]

    Zakas, Maintainable JavaScript, O’Reilly Media, Inc., 2012

    N. Zakas, Maintainable JavaScript, O’Reilly Media, Inc., 2012

  42. [42]

    Crockford, JavaScript: The Good Parts, O’Reilly Media, Inc., 2008

    D. Crockford, JavaScript: The Good Parts, O’Reilly Media, Inc., 2008

  43. [43]

    Universal Module Definition (UMD) API, https://github.com/umd js/umd, Accessed: July 2020

  44. [44]

    RequireJS module loader, https://requirejs.org, Accessed: J uly 2020

  45. [45]

    Grover, H

    D. Grover, H. P. Kunduru, ES6 for Humans: The Latest Stand ard of JavaScript ES2015 and Beyond, 1st ed., Apress, USA, 2017

  46. [46]

    Rollup module bundler, https://rollupjs.org, Accessed: July 202 0

  47. [47]

    Tree Shaking, https://webpack.js.or g /guides/tree-shaking/, Accessed: Nov

    Webpack module bundler. Tree Shaking, https://webpack.js.or g /guides/tree-shaking/, Accessed: Nov. 2019

  48. [48]

    R. C. Martin, Agile Software Development: Principles, Patterns , and Prac- tices, Prentice Hall PTR, Upper Saddle River, NJ, USA, 2003

  49. [49]

    Gligoric, F

    M. Gligoric, F. Behrang, Y. Li, J. Overbey, M. Hafiz, D. Marinov, System- atic testing of refactoring engines on real software projects, in : Proceedings of the 27th European Conf. on Object-Oriented Programming, EC OOP’13, Springer-Verlag, 2013, pp. 629–653

  50. [50]

    Wohlin, P

    C. Wohlin, P. Runeson, M. H¨ ost, M. C. Ohlsson, B. Regnell, A. We ssl´ en, Experimentation in Software Engineering: An Introduction, Kluwer Aca- demic Publishers, Norwell, MA, USA, 2000. 36