bootstrap.native - Bootstrap without jQuery
Bootstrap 5 will remove jQuery as a dependency. That's good news ! But if you want to drop the dependency right now, you can accomplish it with bootstrap.native.
bootstrap.native is a third-party plugin that perfectly mimics Bootstrap with vanilla JavaScript. It's lightweight, robust, and comes with some sweet enhancements too.
Get Started with bootstrap.native
Install via yarn:
yarn add bootstrap.native
yarn add -D bootstrap.native-loader
As you've guessed, bootstrap.native-loader is the Webpack loader.
Back to the code, let's configure the loader in Webpacker - specify components you want to use and the version. bootstrap.native supports both V3 and V4.
const { environment } = require("@rails/webpacker")
const webpack = require("webpack")
environment.loaders.append("bootstrap.native", {
test: /bootstrap\.native/,
use: {
loader: "bootstrap.native-loader",
options: {
only: ["alert", "button", "dropdown", "modal", "tooltip"],
bsVersion: 4
}
}
})
module.exports = environment
Then, import it in Webpack entry file.
import "bootstrap.native"
It's important to note that all components are initialized right away. Meaning that it'll scan through the data-*
attributes and initialize dropdowns, tooltips, etc. If you've had the correct Bootstrap HTML markup, you don't have to do anything else.
But, if you're using Turbolinks...
bootstrap.native with Turbolinks
You'll need this:
import "bootstrap.native"
document.addEventListener("turbolinks:load", () => {
BSN.initCallback(document.body)
})
As explained in its FAQ, dynamically added elements will not work.
Does it work with later added elements?
...the event listeners used by the components are not bound to the document and delegated to specific elements like jQuery plugins do, rather we took a more performance oriented approach and decided to bind events to elements themselves, for performance reasons.
Since Turbolinks is fetching a new page and replacing the body, the events will not work after clicking a link powered by Turbolink.
So we'll need to tell bootstrap.native (BSN
global var) to re-initialize events after a turbolinks:load
event. You can learn more about this part from the official wiki and this Stackoverflow.
The sweet data-persist
Compare to the official JavaScript, bootstrap.native comes with some sweet improvements.
My favorite is data-persist
option that keeps the dropdown menu open, a perfect use case for having a form within a dropdown. (Previously I had to add a little hack to make Bootstrap work that way.)
The markup is straightforward - add data-persist="true"
to the dropdown button.
<button class="dropdown-toggle" data-toggle="dropdown" data-persist="true">
Read more: Some features are even better.
Misc: ESLint, Cleanup
In case you're using ESLint, be sure to add that BSN
to the globals:
{
"globals": {
"BSN": false,
// ...
}
}
Lastly, happily say goodbye to these old pals (or even jQuery if Bootstrap is the last dependent of it!).
yarn remove bootstrap popper.js
Conclusion
Let's get down to the pros and cons.
Pros
- works great as it advertised
- lightweight, 5kb
- well maintained
- fast to catch up upstream (e.g. Toast feature)
- almost a drop-in solution
The open-close ratio of Github issues is 1/205!
Cons
Being a third-party craft, it unavoidably introduces..
- some learning curves and gotchas
- delays of catching up upstream
At last, I highly recommend you check out its Wiki first to understand the motivation of the project, acknowledgments, and FAQs.
I'm pretty happy after switching to bootstrap.native. Overall, less code, smaller bundle size, and one big step towards fully dropping jQuery dependency.
p.s. If you're using React, there is a wonderful solution as well: React Bootstrap.
p.p.s. If you want to know how to use Toast component with bootstrap.native, check out the followup post.
Clap to support the author, help others find it, and make your opinion count.