Do you use Bootstrap’s JavaScript components? Do you like Vanilla JavaScript? Then you might be interested in the Native JavaScript for Bootstrap project (Bootstrap Native), which aims to remove the jQuery dependency required by the components by porting them to plain JavaScript.

Why use Bootstrap Native?

The motivations of such a port are mostly related to performance.

One benefit is the potential performance gain that can come from the superior execution speed of plain JavaScript over jQuery, as reported in many benchmarks.

Another performance advantage is the reduced page weight. Let’s make a quick comparison. All the numbers below refer to minified gzipped files and are expressed in KBs. bootstrap.js refers to the original Bootstrap scripts, bsn.js to the Bootstrap Native scripts, and jq to jQuery. Here we’re looking at the bundled files that gather together all the components, but it should be noted that both libraries have a modular structure that allows the loading of only the needed components and their dependencies.

Bootstrap.js:

jQuery 3.3.1 + Bootstrap.js = 30.0 + 12.9 = 42.9

jQuery 3.1.0 slim + bootstrap.js = 23.6 + 12.9 = 36.5

jQuery 2.2.4 + bootstrap.js = 34.3 + 11.2 = 45.5

jQuery 1.12.4 + bootstrap.js = 38.8 + 11.2 = 50.0

Bootstrap Native JavaScript:

minifill + bsn.js = 2.4 + 7.8 = 10.2

polyfill.io(on chrome 54) + bsn.js = 1.1 + 7.8 = 8.9

polyfill.io(on IE 8) + bsn.js = 12.1 + 7.8 = 19.9

(The polyfill.io size for IE8 was taken from here. These polyfills are discussed in the next sections.)

So, with the Bootstrap components the size varies over the range 36.5 to 50.0 KB, while with Bootstrap Native the range shrinks to 8.9 to 19.9 KB.

Bootstrap Native Browser Support

Regarding browser support, it’s comparable to the original Bootstrap jQuery-based script. That is, it supports the latest browsers on the major mobile and desktop platforms and IE8+. This is accomplished by means of two polyfill strategies.

The first revolves around the use of the Polyfill.io service. All you have to do is insert the relative script tag in the document to get a set of polyfills tailored to each browser:

< script src = " https://cdn.polyfill.io/v2/polyfill.js " > </ script >

The service can be configured to customize its response based on the features really used on the site. See the Pollyfill.io documentation for details.

Alternatively, it’s possible to use minifill, a potentially lighter custom polyfill supplied by the project author itself.

Bootstrap Native Usage

The usage is similar to the original Bootstrap scripts, except we’ll remove jQuery, replace the Bootstrap scripts with the ones supplied by the Bootstrap Native project, and, if necessary, include the polyfills.

So, before the end </body> tag we include the script for the Bootstrap Native components:

< script src = " https://cdn.jsdelivr.net/npm/bootstrap.native@2.0.15/dist/bootstrap-native-v4.min.js " > </ script >

Other CDN URLs are available and listed on the Bootstrap Native documentation page. Alternatively, the file can be downloaded and served locally.

If the polyfills are needed, they should be included in the <head> tag:

< script src = " text/javascript " src = " https://cdn.jsdelivr.net/gh/thednp/minifill@0.0.4/dist/minifill.min.js " > </ script >

This snippet employs the minifill polyfill.

See the Bootstrap Native project documentation page for more detailed usage instructions.

A Port?

To be precise, it’s not a literal port that replicates all the features of the original scripts. The Bootstrap Native author deliberately chose to leave out some slight functionality, particularly lesser-used features, mainly for performance reasons and to simplify the development.

Let’s take a look at some of these issues.

The Custom Events

These are the events triggered by many Bootstrap components during their life cycle. For example, a Modal fires two events — one when it’s opened and the other when it’s closed. (Actually, two events are fired in each case, one before ( 'show' ) and the other ( 'shown' ) after the action.)

Similar events are employed by a Tab to notify its observers when there’s a tab switch: a hide event is dispatched for the current tab and a show event for the tab that has to be shown.

Bootstrap Native, instead, provides these events only for the Carousel and the Button. The original Carousel triggers a couple of custom events when there’s a transition between two slides. The first event, 'slide' , is fired just before the transition begins, while the other one, 'slid' , is fired after the transition has completed. The event object passed to the handlers has two properties that supply information about the transition, direction , and relatedTarget .

The following jQuery snippet illustrates:

$carousel . on ( 'slide.bs.carousel' , function ( e ) { var caption = $ ( e . relatedTarget ) . find ( '.carousel-caption' ) . text ( ) ; console . log ( 'About to slide to the ' + e . direction + ' to slide ' + caption ) ; } ) . on ( 'slid.bs.carousel' , function ( e ) { var caption = $ ( e . relatedTarget ) . find ( '.carousel-caption' ) . text ( ) ; console . log ( 'Slid to the ' + e . direction + ' to slide ' + caption ) ; } ) ;

Bootstrap Native supports both events, but the event object doesn’t have the direction and relatedTarget properties. We can translate the previous snippet into vanilla JS in this way:

carousel . addEventListener ( 'slide.bs.carousel' , function ( e ) { console . log ( 'About to slide' ) ; } ) ; carousel . addEventListener ( 'slid.bs.carousel' , function ( e ) { console . log ( 'Slid' ) ; } ) ;

What about if we need the custom events for some other component? It’s not too difficult to implement them ourselves. We can refer to the Bootstrap Native Carousel code and use the CustomEvent API.

First create the event objects:

if ( ( 'CustomEvent' in window ) && window . dispatchEvent ) { slid = new CustomEvent ( "slid.bs.carousel" ) ; slide = new CustomEvent ( "slide.bs.carousel" ) ; }

When a slide transition is about to start, the 'slide' event is fired:

if ( slide ) { this . carousel . dispatchEvent ( slide ) ; }

And, finally, when the transition has finished, the 'slid' event is triggered:

if ( slid ) { self . carousel . dispatchEvent ( slid ) ; }

Based on this model, similar code can be easily added to other components.

The CustomEvent API is not readily available on every browser, but the aforementioned polyfills cover it.

The Programmatic API

This is the API Bootstrap components expose to allow their initialization and control with JavaScript. For example, on a Modal element three methods can be invoked to control its visibility:

$ ( '#mymodal' ) . modal ( 'show' ) $ ( '#mymodal' ) . modal ( 'hide' ) $ ( '#mymodal' ) . modal ( 'toggle' )

Bootstrap Native, instead, often doesn’t provide this type of programmatic control. The above methods are not available for the Modal, nor for the Dropdown, Tab, Alert, or Carousel.

Other Differences

If we perform a side-by-side comparison of the components, it’s clear how Bootstrap Native is not a literal port, and in some cases removes functionality, while in others it adds something new.

In the Tooltip, for instance, with Bootstrap we have to explicitly init them, because, for performance reasons, the relative data-api is opt-in. In Bootstrap Native, as long as the DATA API attributes are properly set, the initialization is automatic. Additionally, the Native version can automatically place the tooltip, without any additional options. But it doesn’t cover a template system like the one provided by Bootstrap.

The dropdown furnishes another example of a slight difference with respect to the relative Bootstrap component due to a deliberate implementation choice. The jQuery dropdown menu closes after a click on a menu item, while the Native menu remains open.

Keyboard input handling is also incomplete. The tab navigation works, but other operations are partially implemented.

Regarding the Carousel, the jQuery component responds to keyboard inputs by default, while in the vanilla version this behavior must be enabled using the data-keyboard attribute:

< div id = "carousel" class = "carousel slide" ... data - keyboard = "true" >

Another difference for this component is in how the duration option can be customized. This is the value used to determine how long the time interval of the transition between an existing slide and an entering slide must be. Both libraries define the same default value of 600ms , a reasonably acceptable value that should be fine for the majority of use cases.

If we want to change this value, given that in both libraries the animation is performed with CSS, first we must add some CSS rules to override the default duration value.

In Bootstrap, we need to use some jQuery code to modify the value hardcoded in the JavaScript:

$carousel . data ( ) [ 'bs.carousel' ] . constructor . TRANSITION_DURATION = 2000 ;

Bootstrap Native, on the other hand, exposes a data-duration attribute on the component root element and so the process is easier:

< div id = "carousel" class = "carousel slide" data - ride = "carousel" data - interval = "false" data - duration = "2000" >

An identical option is available for other components (e.g. the Modal and the Tooltip) to change the transition duration.

Other issues are listed and explained on the documentation page and on the project issue tracker.

Conclusion

In my opinion, the project is very interesting, but I wouldn’t throw away the original jQuery version so quickly. In fact, as in other “jQuery Vs Vanilla JS” comparisons, the winner often depends on the specific use case.

The issues examined in the previous section should not be major hurdles, so if you’re not searching for a perfect literal conversion of the Bootstrap JavaScript components and you’re ready to cope with some slight differences, this could be the right solution.

Also, it has to be mentioned that the project is under active development, and fast feedback to issues opened on the GitHub tracker is provided.

So, are you going to give it a try in your next Bootstrap project? Feel free to share your thoughts in the comments.

This article was peer reviewed by Joan Yin. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

If you’ve got the basics of Bootstrap under your belt but are wondering how to take your Bootstrap skills to the next level, check out our Building Your First Website with Bootstrap 4 course for a quick and fun introduction to the power of Bootstrap.