2018 25th Asia-Pacific Software Engineering Conference (APSEC)

unjQuerify
Migration of jQuery Snippets to Modern Vanilla JavaScript APIs
Dereck J. Bridie

Shinsuke Matsumoto and Shinji Kusumoto

Delft University of Technology
Delft, The Netherlands
D.J.Bridie@student.tudelft.nl

Graduate School of Information Science and Technology
Osaka University, Osaka, Japan{shinsuke, kusumoto}@ist.osaka-u.ac.jp

This verbose instantiation process can be encapsulated byjQuery. The $ identiﬁer is an entry point to use all jQueryfunctions.

Abstract—jQuery is a JavaScript library which can be usedby developers when creating webpages. It gained popularity
among web developers for normalizing web APIs in a time whenbrowser incompatibilities were more common. However, modernbrowser vendors have adopted API standards which diminish
the need for such a library. When these modern API standards
are used instead of jQuery, page size is lowered, causing an
improvement in page performance. This paper introduces a tool
called unjQuerify which can transform snippets that make useof jQuery’s functionalities into equivalent code that uses modern
web API standards. unjQuerify also aids developers by displaying
relevant documentation and the steps taken to transform thecode, increasing developer familiarity with modern APIs.
Index Terms—jQuery, JavaScript, browser incompatibility,
vanilla, abstract syntax tree

1
2
3
4
5

Listing 2. Instantiation of Ajax object with jQuery

Over the years, browsers have evolved to take World
Wide Web Consortium’s standards into consideration andhave become largely standards-compliant. A large majorityof users make use of such a standards-compliant browser[9], meaning that the need for jQuery to bridge functional
incompatibilities has been diminished. Despite this, more than
73.3% of websites [8] continue to make use of the library.
Using jQuery can come with undesirable costs. Unnecessary
usage of jQuery can lead to performance penalties [10] dueto transfer speeds and parsing. These penalties are often not
mitigated by the usage of Content Delivery Networks due
to fragmentation of network providers and jQuery versions[6]. Furthermore, the weight of jQuery also has an impact
on the loading times of a website. The size of version 3.3.1
of jQuery is 35kb (miniﬁed and gzipped). This is 10% of
the median transfer size of JavaScript and JSON data usedin webpages [1]. When uncompressed, this rises to a size of
87 kB, which may be order of magnitudes larger than thecode written by a developer. Aside from the costs of the datatransfer, parsing and executing the code of jQuery also takes
extra time, whereas modern vanilla JavaScript APIs are alreadypresent in the browser and therefore carry no extra costs.
As the popularity of smartphones increase, we must consider
the high performance impact [11] on constrained computing
devices as well. Also, reliance on any framework can introduce
technical debt [2], [7].
For these reasons, it can be useful for a developer toconsider removing their reliance on jQuery in their webpages.
However, given the popularity of jQuery, it is possible thata developer is unfamiliar with modern API standards. In
addition, maintaining and repairing steady JavaScript resources
may need to be decisive because of the difﬁculty of equivalence checking [3]. Developers should be assisted in thismigration from code using jQuery to code without it.

I. I NTRODUCTIONJavaScript programmers often make use of libraries thatprovide convenient functionality as a layer above existingbrowser built-in APIs. An example of such a library is jQuery1 ,a popular JavaScript library that boasts 97.0% market share[8]. It was created in 2006 by John Resig [5] to simplify web
APIs such as HTML document traversal and manipulation
in a time when browser incompatibilitiy problems [4] werecommon [5]. The most well-known browser incompatibility
problem concerns the instantiation of Ajax request objects.
An example of how it was constructed so that the Ajax object
could work across different browsers is illustrated as below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

var xhr;
if (window.XMLHttpRequest){// If Chrome, Firefox, IE7+, Opera, Safari
xhr = new XMLHttpRequest();}// otherwise, use ActiveX for IE5.x and IE6
else if (window.ActiveXObject) {try {xhr = new ActiveXObject("MSXML2.XMLHTTP");} catch (e) {xhr = new ActiveXObject("Microsoft.XMLHTTP");}}// Initialize request
xhr.open("GET", "http://example.com");...

Listing 1. Instantiation of Ajax object without jQuery
1 jQuery: https://jquery.com/

978-1-7281-1970-0/18/$31.00 ©2018 IEEE
DOI 10.1109/APSEC.2018.00077$.ajax({type: "GET",
url: "http://example.com",
...
)};

618

In this paper, we introduce a tool called unjQuerify that canremove jQuery usages from snippets using AST transformations. Given a snippet of JavaScript that makes use of jQueryfunctionality, a translation is given that have near-equivalentfunctionality, but make use of modern vanilla JavaScript APIs
instead of jQuery functionality. Furthermore, in the interest ofdeveloper education, documentation is given that is relevant
to each transformation.

Furthermore, not all jQuery features can be transformed tomodern idiomatic vanilla JavaScript alone. An example of thisis fade, which should be implemented as a CSS transition
in webpages following best practices. These features will not
be transformed by this tool; instead, migration documentation
will be shown.
III. T OOL OVERVIEW
unjQuerify is a command-line tool that makes use of static
analysis to transform a given source ﬁle that uses jQuery to
DOM APIs using a set of rules. An abstract syntax tree (AST)
is built, and registered rules are used to transform expression
nodes to new nodes that use DOM standards. The tool isalso publicly available on https://www.unjquerify.com througha web interface.

II. M OTIVATING E XAMPLE
To explore the feasibility of such transformations, an sample
will be given of jQuery code:
1
2
3
4
5

$("#btn").click(function() {$("#result").addClass("important").text("The button was clicked.");$("#btn").hide();});

A. Architectural design
Figure 1 depicts a high-level overview of unjQuerify. unjQuerify uses babel2 to construct ASTs from JavaScript
source snippets and apply AST transformations.
The tool provides tree transformations that convert jQuery
expressions to vanilla DOM expressions. Each transformation
is annotated with documentation from the jQuery API guidebook, documentation from Mozilla’s Web Docs3 , and information from Can I Use? browser compatibility information4 .
Then, babel is used again to generate JavaScript source codefrom the modiﬁed AST.
In the web presentation of the tool, each transformation isdisplayed separately. For each transformation that was applied,the documentation information is displayed along with the
chunks that were affected by a transformation.

Listing 3. Sample jQuery snippet

This snippet deﬁnes a click event listener for the element#btn using the click(fn) function. When the button isclicked, the class "important" is added to the #result
element using the addClass(class) function. Also, its
inner-text is changed. Finally, the button is hidden usinghide() function to prevent multiple clicking.
For these expressions, vanilla DOM APIs exist that matchthese functionalities almost precisely. Examples of such expressions are:• click(fn): Adds a function that should be applied when the selected element is clicked. In modern vanilla APIs, this has the same functionality as
Element.addEventListener("click",function).
• addClass(class): Adds the class(es) given in
the ﬁrst parameter to the selected elements. Using DOM APIs, this functionality is related to
Element.classList.add(name).
• hide(): Hides a element. In modern vanilla APIs, this issimilar to Element.style.display = "none".
Equivalent code can be expressed as the following:
1
2
3
4
5
6
7

B. Implementation
The following sections detail the steps taken by unjQuerify
after the input source code is converted to an AST.
1) Finding jQuery usages: jQuery deﬁnes two identicalentrypoints into the library: jQuery and $. From there, thisentry point can be used as a function (e.g. $("#btn")) or asa member property of the identiﬁer (e.g. $.isArray(id)).
Where applicable, function call chains are then dismantled
into links, which are then seperately processed by unjQuerify’s
plugins.
2) Plugins: An unjQuerify plugin deﬁnes a node searchstrategy and a node replacement strategy. In the interest of
expandability, to eventually be able to transform the entiretyof jQuery’s functionality, plugins can be deﬁned and added to
unjQuerify. These plugins are used when visiting each nodein the input tree, and the given replacement is executed whena match is found.
3) Source generation and display: Each mutation to thesource tree made by the tool is tracked. This information isused in the user interface as shown in Section III-C. The output
code is generated by converting the mutated AST back into
JavaScript code.

const button = document.getElementById("btn");
button.addEventListener("click", function() {const res = document.getElementById("result");
res.classList.add("important");
res.textContent = "The button was clicked.";button.style.display = "none";});
Listing 4. Sample manual conversion

However, some jQuery features must be taken into accountwhen converting such code, as not all expression trees can beeasily mapped to vanilla code. One example of this is jQuery’s
method chaining, which allows methods calls to follow eachother without needing new statements. An example of this is
the expression $("div").filter(".post").hide(),which has the same functionality as let x = $("div");x = x.filter(".post"); x = x.hide();.

2 https://babeljs.io/
3 https://developer.mozilla.org/en-US/
4 https://caniuse.com/619

$("...").hide();$("...").text("...");

node.style.display = "none";node.classList.add("...");

unjQuerify

Browser

Input Snippet

Developer.text(String)
Parse
AST

Find
jQueryAST.click(fn).hide()···

Applytransformations

Generate
AST
New AST

PluginsFig. 1. unjQuerify architecture

this case, creating a new temporary assignment creates
unnecessary clutter for a user to read.

C. User presentation
Another component of unjQuerify is its web interface. An
actual screenshot of web interface is shown in Figure 2. The
snippet on the left side is unjQuerify input that uses jQueryfunctions. The snippet on the right side shows the transformed(i.e., vanilla) snippet. Input can be supplied from a variety ofsources, as well as from samples. These samples aim to easea developer into the usage of unjQuerify before use with theirown code. The modiﬁed code is displayed at the top. Underit, each transformation step taken to arrive at this result isshown. For each step, before and after snippets are shown,
and relevant documentation can be found that elaborates upon
the vanilla APIs which were used. Figure 3 shows an example
of such documentation.

unjQuerify adheres to the above rules when unchaining
expressions.
2) Collections: Generally, jQuery methods that mutate document state operate on all elements in a selection. However, there are other methods that do not: an example isis(String), which checks each element in a collection tosee if at least one element matches a selector. Conversely,css(String) retrieves the value of an element collection’s
style property, but only using its ﬁrst element. Each pluginin unjQuerify is aware of which elements a function operates
upon.
3) Parameter Ambiguity: Some jQuery functions exist that
accept multiple types within a given argument. An example ofthis is $.each(Object|Array, callbackFn), whichloops over the entries of an array when given an array, andloops over the keys and values in an object when given an
object. An idiomatic transformation does not exist that accepts
both objects and arrays in vanilla APIs. Therefore, when thetype of this parameter cannot trivially be statically inferred
to distinguish between these cases, a satisfactory idiomatictransformation cannot be given. In these cases, the tool must
give a longer, non-idiomatic transformation.

D. Challenges in transformations
1) Method Call Chains: As mentioned before, jQuery
methods can be chained for ease of use. However, since vanilla
APIs do not support such a style of calling functions, chained
methods must be converted to support such expressions. Whenunchaining, intermediate results are assigned to temporary
variables. However, this brings a set of challenges:• Chains do not always operate upon the same collection.
An example of this is filter(String), which can
reduce the number of matched elements in a collections.
This means the new reduced collection must be assigned
to a new variable in order to continue the chain on thecorrect set of elements.
• If a chain is on the right-side of a variable assignment,
the last temporary variable should match the assignmentof the original assignment.
• Unnecessary temporary variables should be avoided. An
example of this is hide(), which can be used in a chain
and does not cause a mutation of the original object. In4) Non-similarity: There are methods in jQuery that do nothave a direct one-to-one mapping with vanilla functions. For
example, $element.parentsUntil(selector) ﬁnds
the ancestors of each element in the current set of matchedelements up until the element matched in selector. Though
this is one function call in jQuery, the equivalent function invanilla APIs requires a helper function which is comparatively
very verbose.

620

Fig. 2. Screenshot of unjQuerify web interface.

the transformation by applying selective mutations to the tested
jQuery code. An example of a unit test in jQuery can be foundin code sample 5.
1
2
3$("#nothidden").css("margin-top", "-10px");var val = $("#nothidden").css("margin-top");assert.equal(val, "-10px");
Listing 5. Sample jQuery test

When a transformation is known for the mutator of a CSS
property $element.css(property, value), its accessor $element.css(property) can be used to conﬁrm
that the mutator works as expected. unjQuerify’s correctness
tests use this property by, in the example, running one testwith line 1 transformed but not line 2, and another test withline 2 transformed but not line 1. In this manner, both theaccessor and the mutator have been veriﬁed.
This manner of transforming tests can be automated. Sucha modiﬁed test has been used to test the functionality ofthe mutators and accessors of CSS properties, and should be
extended to other functionalities in the future.

Fig. 3. Example of documentation given for a .click() transformation.

IV. P RELIMINARY E VALUATION
unjQuerify’s transformations should not introduce unsuspected behavioral changes, preventing code breakage after
transformation. A transformation that introduces a behavioral
change can cause bugs which do not become apparent fromvisually inspecting the transformed code. Therefore, it isimportant to verify that unjQuerify’s transformations result incode that is functionally equivalent to the input code. Work
has been started to attempt to verify this property, describedin the following sections.

B. Application to small code sample set
For transformations that have been implemented, snippetsfrom QuackIt jQuery Examples5 have been collected and haveinformally been used to verify that these samples behave
the same before and after transformations. These samples
have been grouped into 12 groups, each covering an aspectof jQuery’s functionality. For 8 of these groups, unjQuerify
provides transformation plugins. Within these 8 groups, 32

A. jQuery unit tests
jQuery uses a test-suite to verify the functionality of its
features. We modify these tests to verify the correctness of

5 https://www.quackit.com/jquery/examples/621

of the 49 given examples appear to work correctly after
unjQuerify’s transformations.
Using these tests, it has become clear that there are stillsome difﬁcult constructions that must be addressed. For example, jQuery’s .click(fn) function also supplies the element
which was clicked in the implicit this context, whereas thevanilla JavaScript equivalent does not. This causes a runtime
error in the output code. Future work should consider thesecases.

C. Increase compatibility
The compatibility of the given transformations can varyfrom browser to browser. Developers may want to target otherbrowsers than only the newest set of ”evergreen” browsers,
which boast the highest compatibility with browser standards.
In this case, some of the given transformations might not
be compliant with older browsers. It could be useful for
unjQuerify to be able to suggest transformations that arecompatible with such browsers as well.
Furthermore, unjQuerify has only been used with a single
version of jQuery (v3.3.1). Since older versions of jQuery canbe used within a production environment, the effects of theversion changes should be evaluated and adjustments should
be made to unjQuerify to account for this.

V. F UTURE W ORKAs this tool is still a work-in-progress, unjQuerify can still
be improved. The following subsections elaborate upon several
ways in which the tool can be extended.
A. Introduction of types

VI. C ONCLUSION
In this paper, a tool was presented to offer suggestions totransform jQuery code snippets into modern vanilla JavaScript
code based on AST transformations. By using this tool,
developers can migrate their code so that it does not dependon this library. Furthermore, developers can use the references
provided to increase their familiarity with modern documentation resources. Testing has been done with jQuery’s unit
tests and small sample code sets. In the future, more progressshould be made to increase the accuracy and applicability ofthe transformations provided by unjQuerify.

unjQuerify does not attempt to statically infer the types ofidentiﬁers. Therefore, each identiﬁer which uses known jQuery
methods assumed to be a reference to a jQuery collection.
Code sample 6 illustrates a trival example of a heuristic
possibly being used incorrectly.
1
2
3
4
5

const a = { hide() { console.log("Hidden"); }};const b = $(".post");function hide(element) {element.hide();}Listing 6. Example of unveriﬁable heuristic use

ACKNOWLEDGEMENTS
This work was supported by JSPS/MEXT KAKENHI Grant
Number 16H02908 and 18H03222. It could not have beenpossible without JASSO scholarship funding and Osaka University’s FrontierLab program.

Without type information, it is not known if element usedin the function parameter is a jQuery object or some other kindof object. In the given example, unjQuerify will incorrectly
apply a transformation which assumes that element is ajQuery object that refers to HTML elements, resulting in aruntime error.
Projects exist that aim to improve tooling on JavaScript
projects by introducing types, such as Microsoft’s TypeScript6
and Facebook’s Flow7 . Using type annotations would allow
unjQuerify to be able to distinguish between these cases andapply transformations only when the type is correct.

R EFERENCES[1] HTTP Archive.
Page weight.
https://httparchive.org/reports/
page-weight#bytesJs. Accessed: 20 June 2018.
[2] Philippe Kruchten, Robert L. Nord, and Ipek Ozkaya. Technical debt:
From metaphor to theory and practice. IEEE Software, 29(6):18–21,
Nov 2012.
[3] Nuno P. Lopes and José Monteiro. Automatic equivalence checking of
programs with uninterpreted functions and integer arithmetic. International Journal on Software Tools for Technology Transfer, 18(4):359–
374, Aug 2016.
[4] Ali Mesbah and Mukul R. Prasad. Automated cross-browser compatibility testing. In Proceedings of the 33rd International Conference on
Software Engineering, ICSE ’11, pages 561–570, New York, NY, USA,2011. ACM.
[5] Charles Severance. John Resig: building JQuery. Computer, 48(5):7–8,
2015.
[6] Steve Souders. HTTP archive: jQuery. http://www.stevesouders.com/
blog/2013/03/18/http-archive-jquery/. Accessed: 20 June 2018.
[7] Edith Tom, AybüKe Aurum, and Richard Vidgen. An exploration oftechnical debt. J. Syst. Softw., 86(6):1498–1516, June 2013.
[8] Usage statistics and market share of JavaScript libraries for websites, june 2018. https://w3techs.com/technologies/overview/javascript
library/all. Accessed: 20 June 2018.
[9] Can I Use? Browser usage table. https://caniuse.com/usage-table.
Accessed: 20 June 2018.
[10] TJ VanToll. Is jQuery too big for mobile? https://modernweb.com/
is-jquery-too-big-for-mobile/. Accessed: 20 June 2018.
[11] Bo Zhao, Byung Chul Tak, and Guohong Cao. Reducing the delay andpower consumption of web browsing on smartphones in 3g networks.
In Distributed Computing Systems (ICDCS), 2011 31st International
Conference on, pages 413–422. IEEE, 2011.

B. Improve evaluation
In order to check the applicability and validity of unjQuerify for all jQuery snippets, using longer snippets could
be valuable. For this, manual veriﬁcation of small snippetsand mutated jQuery unit tests have been used. However, thisevaluation could be expanded upon by using large software
repositories that are dependent upon jQuery and manually
verifying the results of unjQuerify’s transformations.
One dataset that could be used is NPM’s list of jQuery’s
dependents8 . NPM is a software package manager that canshow which projects are dependent upon jQuery. Then, thisdependent code can be transformed with unjQuerify, thenmanually veriﬁed or automatically veriﬁed using the project’s
own tests.
6 https://www.typescriptlang.org/
7 https://ﬂow.org/
8 https://www.npmjs.com/browse/depended/jquery622