How to Integrate Bootstrap 4 Datepicker with Tailwind CSS: Proper Initialization Guide

Load Bootstrap 4 CSS after Tailwind, include jQuery and Bootstrap JS before initializing the datepicker on DOMContentLoaded, and ensure your tailwind.config.js content array scans all template files where the datepicker markup appears.

Tailwind CSS is a utility-first framework that generates CSS at build time by scanning files specified in the content configuration. Because Tailwind only touches CSS, you can safely combine it with third-party JavaScript widgets like the Bootstrap 4 Datepicker. This guide walks through the proper initialization steps using examples from the tailwindlabs/tailwindcss repository.

Understanding the Architecture

Tailwind operates as a config-driven compiler. The build process extracts class names from your templates and generates the final CSS bundle. Key files in the tailwindlabs/tailwindcss repository that enable this extensibility include:

  • tailwind.config.js – Declares the content paths Tailwind should scan and allows theme extensions【/cache/repos/github.com/tailwindlabs/tailwindcss/main/playgrounds/v3/tailwind.config.js】.
  • packages/tailwindcss/src/plugin.ts – Core plugin factory that powers Tailwind’s extensibility【/cache/repos/github.com/tailwindlabs/tailwindcss/main/packages/tailwindcss/src/plugin.ts】.
  • packages/tailwindcss/src/plugin.cts – CJS/ESM compatibility shim for the plugin API【/cache/repos/github.com/tailwindlabs/tailwindcss/main/packages/tailwindcss/src/plugin.cts】.

Because Tailwind is distributed as a PostCSS plugin, it integrates seamlessly with Vite, Webpack, and other modern bundlers via the adapters in integrations/vite/ and integrations/webpack/【/cache/repos/github.com/tailwindlabs/tailwindcss/main/integrations/vite/index.test.ts】【/cache/repos/github.com/tailwindlabs/tailwindcss/main/integrations/webpack/index.test.ts】.

Prerequisites for Proper Initialization

To successfully integrate Bootstrap 4 Datepicker with Tailwind CSS, ensure you satisfy these three requirements:

  1. Load Bootstrap CSS after Tailwind – Place the Bootstrap 4 stylesheet link after your generated Tailwind CSS to prevent utility classes from overriding the datepicker’s internal styles.
  2. Include jQuery and Bootstrap JS – The datepicker depends on jQuery and Bootstrap’s JavaScript. Load these before your initialization script.
  3. Initialize after DOM ready – Call $('#datepicker').datepicker() inside a DOMContentLoaded event listener or within your framework’s mount lifecycle.

Step-by-Step Implementation

Basic HTML Setup

The following example demonstrates the correct load order and initialization pattern:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Tailwind + Bootstrap 4 Datepicker</title>

  <!-- 1. Tailwind CSS (generated) -->
  <link href="/dist/tailwind.css" rel="stylesheet" />

  <!-- 2. Bootstrap 4 CSS (required for datepicker styling) -->
  <link
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
    rel="stylesheet"
  />
  <!-- 3. Datepicker CSS -->
  <link
    href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css"
    rel="stylesheet"
  />
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">

  <div class="p-6 bg-white rounded shadow">
    <label class="block text-sm font-medium text-gray-700 mb-2">
      Choose a date
    </label>

    <div class="input-group date" id="datepicker">
      <input
        type="text"
        class="form-control border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"
        placeholder="MM/DD/YYYY"
      />
      <div class="input-group-append">
        <span class="input-group-text bg-gray-200 border-gray-300 rounded-r-md">
          <svg
            class="w-5 h-5 text-gray-500"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path
              stroke-linecap="round"
              stroke-linejoin="round"
              stroke-width="2"
              d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
            />
          </svg>
        </span>
      </div>
    </div>
  </div>

  <!-- 4. jQuery (required by Bootstrap 4) -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
  <!-- 5. Bootstrap 4 JS -->
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
  <!-- 6. Datepicker JS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>

  <script>
    document.addEventListener('DOMContentLoaded', () => {
      // Initialise the Bootstrap‑4 datepicker
      $('#datepicker').datepicker({
        autoclose: true,
        todayHighlight: true,
        format: 'mm/dd/yyyy',
      });
    });
  </script>
</body>
</html>

Notice how Tailwind utilities (bg-gray-100, rounded-md, focus:ring-indigo-500) style the container and input while the datepicker retains its Bootstrap-specific behavior.

Vite Integration for Modern Projects

For projects using Vite (as configured in playgrounds/vite/vite.config.ts【/cache/repos/github.com/tailwindlabs/tailwindcss/main/playgrounds/vite/vite.config.ts】), install the dependencies and configure PostCSS:

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npm install bootstrap@4 jquery

postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

tailwind.config.js – Ensure the datepicker markup is scanned:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './index.html',
    './src/**/*.{js,ts,jsx,tsx}',
    // Include paths where datepicker markup might appear
    './node_modules/bootstrap-datepicker/**/*.js',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

src/main.tsx (React example):

import React, { useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css';
import $ from 'jquery';
import 'bootstrap';
import 'bootstrap-datepicker';

export default function App() {
  useEffect(() => {
    // Initialise after component mount
    $('#datepicker').datepicker({
      autoclose: true,
      format: 'mm/dd/yyyy',
    });
  }, []);

  return (
    <div className="flex items-center justify-center min-h-screen bg-gray-100">
      <div className="p-6 bg-white rounded shadow">
        <label className="block text-sm font-medium text-gray-700 mb-2">
          Pick a date
        </label>
        <div className="input-group date" id="datepicker">
          <input
            type="text"
            className="form-control border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"
            placeholder="MM/DD/YYYY"
          />
          <div className="input-group-append">
            <span className="input-group-text bg-gray-200 border-gray-300 rounded-r-md">
              📅
            </span>
          </div>
        </div>
      </div>
    </div>
  );
}

This setup leverages the Tailwind Vite integration (integrations/vite/index.test.ts) to process utilities while preserving the Bootstrap datepicker’s JavaScript functionality.

Troubleshooting Common Initialization Issues

If the datepicker fails to appear or throws errors, verify these specific points:

  • jQuery is not loaded: The Bootstrap 4 Datepicker requires jQuery. Ensure the script tag loads before Bootstrap’s JS and the initialization code.
  • Incorrect load order: Tailwind CSS must come before Bootstrap CSS in the <head>. If Bootstrap loads first, Tailwind’s preflight might override critical widget styles.
  • Missing content paths: If using Tailwind v3+, ensure tailwind.config.js includes paths to files containing the datepicker markup. The compiler only generates utilities for classes it finds in scanned files.
  • Initialization timing: Always wrap $('#datepicker').datepicker() inside DOMContentLoaded or your framework’s mount hook. Calling it before the DOM element exists results in silent failures.

Summary

  • Tailwind CSS is a CSS-only framework that generates utilities based on scanned content paths in tailwind.config.js.
  • To integrate Bootstrap 4 Datepicker with Tailwind CSS, load Bootstrap’s CSS after Tailwind, include jQuery and Bootstrap JS, and initialize the widget after DOM ready.
  • In modern Vite projects, configure Tailwind via postcss.config.js and ensure your content array includes paths to datepicker markup to prevent missing utility classes.
  • The tailwindlabs/tailwindcss repository provides official integrations for Vite and Webpack under integrations/, making it straightforward to combine Tailwind with legacy jQuery plugins.

Frequently Asked Questions

Why does my Bootstrap 4 Datepicker lose its styling when I add Tailwind CSS?

Tailwind’s Preflight (a modern CSS reset) can override Bootstrap’s base styles if Bootstrap CSS loads first. To fix this, ensure your HTML loads Tailwind’s generated CSS before Bootstrap’s CSS. This allows Bootstrap’s more specific component styles to take precedence over Tailwind’s reset.

Can I use Bootstrap 4 Datepicker with Tailwind CSS in a React or Vue project?

Yes. Since Tailwind is CSS-only and the datepicker is a jQuery plugin, you can combine them in any framework. Import Bootstrap and datepicker CSS in your entry file, ensure jQuery is available (or imported), and initialize the datepicker inside useEffect (React) or onMounted (Vue). The Tailwind Vite integration (integrations/vite/index.test.ts) handles the CSS processing automatically.

Do I need to modify tailwind.config.js to use Bootstrap components?

You do not need to modify the theme, but you must ensure the content array includes paths to files containing Bootstrap class names (like form-control or input-group) if you want Tailwind to scan them. However, since Bootstrap provides its own CSS for those classes, the critical requirement is simply that Tailwind’s content scans your HTML/JSX files so your utility classes are generated.

Why is my datepicker not initializing even though I included all scripts?

The most common cause is initialization timing. The Bootstrap 4 Datepicker requires the DOM element to exist before calling $('#datepicker').datepicker(). If your script runs before the HTML renders, or if jQuery is loaded after your initialization code, the plugin will fail silently. Always wrap initialization in document.addEventListener('DOMContentLoaded', ...) or your framework’s equivalent mount hook.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →