diff --git a/build/build-plugins.js b/build/build-plugins.js
index a5f95a9d15886efd7c037d54c82c25b4dbeb5451..cabd44e45592b13c61289d795afdc561920c161c 100644
--- a/build/build-plugins.js
+++ b/build/build-plugins.js
@@ -136,6 +136,23 @@ function getConfigByPluginKey(pluginKey) {
       }
     }
   }
+
+  if (pluginKey === 'Toast') {
+    return {
+      external: [
+        bsPlugins.Data,
+        bsPlugins.EventHandler,
+        bsPlugins.Manipulator,
+        bsPlugins.Util
+      ],
+      globals: {
+        [bsPlugins.Data]: 'Data',
+        [bsPlugins.EventHandler]: 'EventHandler',
+        [bsPlugins.Manipulator]: 'Manipulator',
+        [bsPlugins.Util]: 'Util'
+      }
+    }
+  }
 }
 
 function build(plugin) {
diff --git a/js/src/toast.js b/js/src/toast.js
index 4aef2d40c2a1b60d2ef899b0aabe88d26331ff1f..6e878e5c80677eec6ff51dc844aab460fadac4f4 100644
--- a/js/src/toast.js
+++ b/js/src/toast.js
@@ -5,7 +5,9 @@
  * --------------------------------------------------------------------------
  */
 
-import $ from 'jquery'
+import Data from './dom/data'
+import EventHandler from './dom/eventHandler'
+import Manipulator from './dom/manipulator'
 import Util from './util'
 
 /**
@@ -14,11 +16,10 @@ import Util from './util'
  * ------------------------------------------------------------------------
  */
 
-const NAME               = 'toast'
-const VERSION            = '4.3.1'
-const DATA_KEY           = 'bs.toast'
-const EVENT_KEY          = `.${DATA_KEY}`
-const JQUERY_NO_CONFLICT = $.fn[NAME]
+const NAME      = 'toast'
+const VERSION   = '4.3.1'
+const DATA_KEY  = 'bs.toast'
+const EVENT_KEY = `.${DATA_KEY}`
 
 const Event = {
   CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,
@@ -63,6 +64,7 @@ class Toast {
     this._config  = this._getConfig(config)
     this._timeout = null
     this._setListeners()
+    Data.setData(element, DATA_KEY, this)
   }
 
   // Getters
@@ -82,7 +84,7 @@ class Toast {
   // Public
 
   show() {
-    $(this._element).trigger(Event.SHOW)
+    EventHandler.trigger(this._element, Event.SHOW)
 
     if (this._config.animation) {
       this._element.classList.add(ClassName.FADE)
@@ -92,7 +94,7 @@ class Toast {
       this._element.classList.remove(ClassName.SHOWING)
       this._element.classList.add(ClassName.SHOW)
 
-      $(this._element).trigger(Event.SHOWN)
+      EventHandler.trigger(this._element, Event.SHOWN)
 
       if (this._config.autohide) {
         this.hide()
@@ -104,9 +106,8 @@ class Toast {
     if (this._config.animation) {
       const transitionDuration = Util.getTransitionDurationFromElement(this._element)
 
-      $(this._element)
-        .one(Util.TRANSITION_END, complete)
-        .emulateTransitionEnd(transitionDuration)
+      EventHandler.one(this._element, Util.TRANSITION_END, complete)
+      Util.emulateTransitionEnd(this._element, transitionDuration)
     } else {
       complete()
     }
@@ -117,7 +118,7 @@ class Toast {
       return
     }
 
-    $(this._element).trigger(Event.HIDE)
+    EventHandler.trigger(this._element, Event.HIDE)
 
     if (withoutTimeout) {
       this._close()
@@ -136,9 +137,9 @@ class Toast {
       this._element.classList.remove(ClassName.SHOW)
     }
 
-    $(this._element).off(Event.CLICK_DISMISS)
+    EventHandler.off(this._element, Event.CLICK_DISMISS)
+    Data.removeData(this._element, DATA_KEY)
 
-    $.removeData(this._element, DATA_KEY)
     this._element = null
     this._config  = null
   }
@@ -148,7 +149,7 @@ class Toast {
   _getConfig(config) {
     config = {
       ...Default,
-      ...$(this._element).data(),
+      ...Manipulator.getDataAttributes(this._element),
       ...typeof config === 'object' && config ? config : {}
     }
 
@@ -162,7 +163,8 @@ class Toast {
   }
 
   _setListeners() {
-    $(this._element).on(
+    EventHandler.on(
+      this._element,
       Event.CLICK_DISMISS,
       Selector.DATA_DISMISS,
       () => this.hide(true)
@@ -172,16 +174,15 @@ class Toast {
   _close() {
     const complete = () => {
       this._element.classList.add(ClassName.HIDE)
-      $(this._element).trigger(Event.HIDDEN)
+      EventHandler.trigger(this._element, Event.HIDDEN)
     }
 
     this._element.classList.remove(ClassName.SHOW)
     if (this._config.animation) {
       const transitionDuration = Util.getTransitionDurationFromElement(this._element)
 
-      $(this._element)
-        .one(Util.TRANSITION_END, complete)
-        .emulateTransitionEnd(transitionDuration)
+      EventHandler.one(this._element, Util.TRANSITION_END, complete)
+      Util.emulateTransitionEnd(this._element, transitionDuration)
     } else {
       complete()
     }
@@ -191,13 +192,11 @@ class Toast {
 
   static _jQueryInterface(config) {
     return this.each(function () {
-      const $element = $(this)
-      let data       = $element.data(DATA_KEY)
+      let data       = Data.getData(this, DATA_KEY)
       const _config  = typeof config === 'object' && config
 
       if (!data) {
         data = new Toast(this, _config)
-        $element.data(DATA_KEY, data)
       }
 
       if (typeof config === 'string') {
@@ -209,19 +208,28 @@ class Toast {
       }
     })
   }
+
+  static _getInstance(element) {
+    return Data.getData(element, DATA_KEY)
+  }
 }
 
 /**
  * ------------------------------------------------------------------------
  * jQuery
  * ------------------------------------------------------------------------
+ *  add .toast to jQuery only if jQuery is present
  */
 
-$.fn[NAME]             = Toast._jQueryInterface
-$.fn[NAME].Constructor = Toast
-$.fn[NAME].noConflict  = () => {
-  $.fn[NAME] = JQUERY_NO_CONFLICT
-  return Toast._jQueryInterface
+const $ = Util.jQuery
+if (typeof $ !== 'undefined') {
+  const JQUERY_NO_CONFLICT = $.fn[NAME]
+  $.fn[NAME]               = Toast._jQueryInterface
+  $.fn[NAME].Constructor   = Toast
+  $.fn[NAME].noConflict    = () => {
+    $.fn[NAME] = JQUERY_NO_CONFLICT
+    return Toast._jQueryInterface
+  }
 }
 
 export default Toast
diff --git a/js/tests/unit/toast.js b/js/tests/unit/toast.js
index 2081693ebce6aa83a1e17f9693bbbb3d541b02d7..07f659a8e8afe5facfb99fc8f0cd327f1064e701 100644
--- a/js/tests/unit/toast.js
+++ b/js/tests/unit/toast.js
@@ -146,11 +146,11 @@ $(function () {
       .bootstrapToast()
       .appendTo($('#qunit-fixture'))
 
-    assert.ok(typeof $toast.data('bs.toast') !== 'undefined')
+    assert.ok(typeof Toast._getInstance($toast[0]) !== 'undefined')
 
     $toast.bootstrapToast('dispose')
 
-    assert.ok(typeof $toast.data('bs.toast') === 'undefined')
+    assert.ok(Toast._getInstance($toast[0]) === null)
   })
 
   QUnit.test('should allow to destroy toast and hide it before that', function (assert) {
@@ -171,11 +171,11 @@ $(function () {
     $toast.one('shown.bs.toast', function () {
       setTimeout(function () {
         assert.ok($toast.hasClass('show'))
-        assert.ok(typeof $toast.data('bs.toast') !== 'undefined')
+        assert.ok(typeof Toast._getInstance($toast[0]) !== 'undefined')
 
         $toast.bootstrapToast('dispose')
 
-        assert.ok(typeof $toast.data('bs.toast') === 'undefined')
+        assert.ok(Toast._getInstance($toast[0]) === null)
         assert.ok($toast.hasClass('show') === false)
 
         done()
diff --git a/js/tests/visual/toast.html b/js/tests/visual/toast.html
index 93a627cc55e43b7c5ce6d2431f197fe36018a7b7..a527eab13da451e632850da79067ea66ff8bd8a2 100644
--- a/js/tests/visual/toast.html
+++ b/js/tests/visual/toast.html
@@ -52,19 +52,34 @@
       </div>
     </div>
 
+    <script src="../../dist/dom/polyfill.js"></script>
     <script src="../../dist/util.js"></script>
+    <script src="../../dist/dom/manipulator.js"></script>
+    <script src="../../dist/dom/data.js"></script>
+    <script src="../../dist/dom/eventHandler.js"></script>
     <script src="../../dist/toast.js"></script>
     <script>
-      $(function () {
-        $('.toast').toast()
+      window.addEventListener('load', function () {
+        Util.makeArray(document.querySelectorAll('.toast'))
+          .forEach(function (toastNode) {
+            new Toast(toastNode)
+          })
 
-        $('#btnShowToast').on('click', function () {
-          $('.toast').toast('show')
-        })
+          document.getElementById('btnShowToast').addEventListener('click', function () {
+            Util.makeArray(document.querySelectorAll('.toast'))
+              .forEach(function (toastNode) {
+                var toast = Toast._getInstance(toastNode)
+                toast.show()
+              })
+          })
 
-        $('#btnHideToast').on('click', function () {
-          $('.toast').toast('hide')
-        })
+          document.getElementById('btnHideToast').addEventListener('click', function () {
+            Util.makeArray(document.querySelectorAll('.toast'))
+              .forEach(function (toastNode) {
+                var toast = Toast._getInstance(toastNode)
+                toast.hide()
+              })
+          })
       })
     </script>
   </body>