Usamos cookies para mejorar tu experiencia en el sitio
CodeWorlds
Volver a colecciones
Guide18 min read

Flowbite - Kompletny Przewodnik po UI Toolkit dla Tailwind CSS

Flowbite is an open-source Tailwind CSS component library with 450+ ready blocks. Available for React, Vue, Svelte, Angular and vanilla JavaScript.

Flowbite - Complete Guide to the UI Toolkit for Tailwind CSS

What is Flowbite?

Flowbite is an open-source component library built on Tailwind CSS, offering over 50 ready-to-use UI components and 450+ page blocks (ready-made page sections). Unlike many libraries, Flowbite is available for virtually every JavaScript framework - React, Vue, Svelte, Angular, as well as vanilla JavaScript and pure HTML.

Flowbite was created with development acceleration in mind - instead of building each component from scratch, you can copy ready-made code or install a package and have a working navbar, modal, or datepicker in minutes. All components are fully responsive, support dark mode, and are optimized for accessibility.

Flowbite's Philosophy

Flowbite offers two approaches:

  1. Copy-paste HTML/CSS - Each component has code to copy that works with pure Tailwind CSS
  2. JavaScript Packages - For interactive components (dropdown, modal, datepicker) you need JS

This makes Flowbite extremely flexible - you can use just a few components or build an entire application on this library.

Flowbite vs other libraries

FeatureFlowbiteDaisyUITailwind UIshadcn/ui
PriceFree + ProFree$299+Free
FrameworksAllTailwind onlyReactReact
Section Blocks450+None500+~50
FigmaYes (Pro)YesYesNo
Dark modeBuilt-inBuilt-inBuilt-inManual
LicenseMITMITCommercialMIT
JavaScriptOptionalCSS onlyReactReact
TypeScriptFullN/AFullFull

When to choose Flowbite?

Choose Flowbite when:

  • You need support for multiple frameworks
  • You want ready-made blocks (hero, pricing, features)
  • You're looking for a free alternative to Tailwind UI
  • You're building a dashboard or admin panel
  • You need a datepicker, carousel, drawer

Consider alternatives when:

  • You need CSS only without JS (DaisyUI)
  • You want full control over code (shadcn/ui)
  • Budget allows for a paid solution (Tailwind UI)

Installation

Vanilla JavaScript / HTML

Code
Bash
# npm
npm install flowbite

# yarn
yarn add flowbite

# pnpm
pnpm add flowbite
JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  content: [
    "./node_modules/flowbite/**/*.js"
  ],
  plugins: [
    require('flowbite/plugin')
  ]
}
Code
HTML
<!-- Add script before </body> -->
<script src="../path/to/flowbite/dist/flowbite.min.js"></script>

<!-- Or from CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.1/flowbite.min.js"></script>

React

Code
Bash
npm install flowbite flowbite-react
JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  content: [
    './node_modules/flowbite-react/lib/**/*.js',
  ],
  plugins: [
    require('flowbite/plugin')
  ],
}

Vue 3

Code
Bash
npm install flowbite flowbite-vue
JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  content: [
    './node_modules/flowbite-vue/**/*.{js,jsx,ts,tsx}',
    './node_modules/flowbite/**/*.js'
  ],
  plugins: [
    require('flowbite/plugin')
  ],
}

Svelte

Code
Bash
npm install flowbite flowbite-svelte
JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  content: [
    './node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'
  ],
  plugins: [
    require('flowbite/plugin')
  ],
}

Angular

Code
Bash
npm install flowbite
JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  content: [
    "./node_modules/flowbite/**/*.js"
  ],
  plugins: [
    require('flowbite/plugin')
  ]
}
angular.json
JSON
// angular.json - add script
"scripts": [
  "node_modules/flowbite/dist/flowbite.min.js"
]

React components

Alert

Code
TypeScript
import { Alert } from 'flowbite-react'
import { HiInformationCircle, HiX } from 'react-icons/hi'

function AlertExamples() {
  return (
    <div className="flex flex-col gap-4">
      {/* Basic */}
      <Alert color="info">
        <span className="font-medium">Info alert!</span> Change a few things up and try submitting again.
      </Alert>

      {/* Different colors */}
      <Alert color="failure">
        <span className="font-medium">Danger alert!</span> Something went wrong.
      </Alert>

      <Alert color="success">
        <span className="font-medium">Success alert!</span> Your purchase is complete.
      </Alert>

      <Alert color="warning">
        <span className="font-medium">Warning alert!</span> Please check your input.
      </Alert>

      {/* With icon */}
      <Alert color="info" icon={HiInformationCircle}>
        <span className="font-medium">Info!</span> This is an informational alert.
      </Alert>

      {/* With dismiss button */}
      <Alert
        color="success"
        onDismiss={() => console.log('Alert dismissed!')}
      >
        <span className="font-medium">Success!</span> You can dismiss this alert.
      </Alert>

      {/* With border */}
      <Alert color="info" withBorderAccent>
        <span className="font-medium">Info!</span> Alert with border accent.
      </Alert>

      {/* With additional content */}
      <Alert
        color="info"
        additionalContent={
          <div className="mt-2 mb-4 text-sm text-cyan-700 dark:text-cyan-800">
            More info about this alert goes here. This example text is going to run a bit longer
            so that you can see how spacing works.
          </div>
        }
        icon={HiInformationCircle}
      >
        <span className="font-medium">More information</span>
      </Alert>

      {/* Rounded */}
      <Alert color="info" rounded>
        Rounded alert!
      </Alert>
    </div>
  )
}

Navbar

Code
TypeScript
import { Navbar, Button } from 'flowbite-react'

function NavbarExample() {
  return (
    <Navbar fluid rounded>
      <Navbar.Brand href="https://flowbite.com/">
        <img
          src="/logo.svg"
          className="mr-3 h-6 sm:h-9"
          alt="Flowbite Logo"
        />
        <span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
          Flowbite
        </span>
      </Navbar.Brand>

      <div className="flex md:order-2">
        <Button>Get started</Button>
        <Navbar.Toggle />
      </div>

      <Navbar.Collapse>
        <Navbar.Link href="/" active>
          Home
        </Navbar.Link>
        <Navbar.Link href="/about">About</Navbar.Link>
        <Navbar.Link href="/services">Services</Navbar.Link>
        <Navbar.Link href="/pricing">Pricing</Navbar.Link>
        <Navbar.Link href="/contact">Contact</Navbar.Link>
      </Navbar.Collapse>
    </Navbar>
  )
}

// With dropdown
import { Dropdown, Avatar } from 'flowbite-react'

function NavbarWithDropdown() {
  return (
    <Navbar fluid rounded>
      <Navbar.Brand href="/">
        <span className="self-center whitespace-nowrap text-xl font-semibold dark:text-white">
          Brand
        </span>
      </Navbar.Brand>

      <div className="flex md:order-2">
        <Dropdown
          arrowIcon={false}
          inline
          label={
            <Avatar
              alt="User settings"
              img="/avatar.png"
              rounded
            />
          }
        >
          <Dropdown.Header>
            <span className="block text-sm">John Doe</span>
            <span className="block truncate text-sm font-medium">
              john@example.com
            </span>
          </Dropdown.Header>
          <Dropdown.Item>Dashboard</Dropdown.Item>
          <Dropdown.Item>Settings</Dropdown.Item>
          <Dropdown.Divider />
          <Dropdown.Item>Sign out</Dropdown.Item>
        </Dropdown>
        <Navbar.Toggle />
      </div>

      <Navbar.Collapse>
        <Navbar.Link href="/" active>Home</Navbar.Link>
        <Navbar.Link href="/about">About</Navbar.Link>
        <Navbar.Link href="/services">Services</Navbar.Link>
      </Navbar.Collapse>
    </Navbar>
  )
}

Modal

Code
TypeScript
import { useState } from 'react'
import { Button, Modal } from 'flowbite-react'
import { HiOutlineExclamationCircle } from 'react-icons/hi'

function ModalExample() {
  const [openModal, setOpenModal] = useState(false)

  return (
    <>
      <Button onClick={() => setOpenModal(true)}>Open modal</Button>

      <Modal show={openModal} onClose={() => setOpenModal(false)}>
        <Modal.Header>Terms of Service</Modal.Header>
        <Modal.Body>
          <div className="space-y-6">
            <p className="text-base leading-relaxed text-gray-500 dark:text-gray-400">
              With less than a month to go before the European Union enacts new consumer privacy laws
              for its citizens, companies around the world are updating their terms of service.
            </p>
            <p className="text-base leading-relaxed text-gray-500 dark:text-gray-400">
              The European Union's General Data Protection Regulation (G.D.P.R.) goes into effect on
              May 25 and is meant to ensure a common set of data rights.
            </p>
          </div>
        </Modal.Body>
        <Modal.Footer>
          <Button onClick={() => setOpenModal(false)}>I accept</Button>
          <Button color="gray" onClick={() => setOpenModal(false)}>
            Decline
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  )
}

// Confirmation Modal
function DeleteConfirmModal() {
  const [openModal, setOpenModal] = useState(false)

  return (
    <>
      <Button color="failure" onClick={() => setOpenModal(true)}>
        Delete account
      </Button>

      <Modal show={openModal} size="md" onClose={() => setOpenModal(false)} popup>
        <Modal.Header />
        <Modal.Body>
          <div className="text-center">
            <HiOutlineExclamationCircle className="mx-auto mb-4 h-14 w-14 text-gray-400 dark:text-gray-200" />
            <h3 className="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">
              Are you sure you want to delete this product?
            </h3>
            <div className="flex justify-center gap-4">
              <Button color="failure" onClick={() => setOpenModal(false)}>
                Yes, I'm sure
              </Button>
              <Button color="gray" onClick={() => setOpenModal(false)}>
                No, cancel
              </Button>
            </div>
          </div>
        </Modal.Body>
      </Modal>
    </>
  )
}

// Different sizes
function SizedModals() {
  const [size, setSize] = useState('md')
  const [openModal, setOpenModal] = useState(false)

  return (
    <>
      <div className="flex flex-wrap gap-4">
        {['sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl', '6xl', '7xl'].map((s) => (
          <Button
            key={s}
            onClick={() => {
              setSize(s)
              setOpenModal(true)
            }}
          >
            {s}
          </Button>
        ))}
      </div>

      <Modal show={openModal} size={size} onClose={() => setOpenModal(false)}>
        <Modal.Header>Modal {size}</Modal.Header>
        <Modal.Body>
          <p>This is a {size} modal.</p>
        </Modal.Body>
      </Modal>
    </>
  )
}

Carousel

Code
TypeScript
import { Carousel } from 'flowbite-react'

function CarouselExample() {
  return (
    <div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
      <Carousel>
        <img src="/carousel-1.svg" alt="Slide 1" />
        <img src="/carousel-2.svg" alt="Slide 2" />
        <img src="/carousel-3.svg" alt="Slide 3" />
        <img src="/carousel-4.svg" alt="Slide 4" />
        <img src="/carousel-5.svg" alt="Slide 5" />
      </Carousel>
    </div>
  )
}

// Without controls
function CarouselWithoutControls() {
  return (
    <div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
      <Carousel slide={false}>
        <img src="/carousel-1.svg" alt="Slide 1" />
        <img src="/carousel-2.svg" alt="Slide 2" />
        <img src="/carousel-3.svg" alt="Slide 3" />
      </Carousel>
    </div>
  )
}

// With custom indicators
function CarouselCustomIndicators() {
  return (
    <div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
      <Carousel
        indicators={false}
        leftControl={
          <span className="group-hover:bg-white/50 group-focus:outline-none group-focus:ring-4 group-focus:ring-white">
          </span>
        }
        rightControl={
          <span className="group-hover:bg-white/50 group-focus:outline-none group-focus:ring-4 group-focus:ring-white">
          </span>
        }
      >
        <img src="/carousel-1.svg" alt="Slide 1" />
        <img src="/carousel-2.svg" alt="Slide 2" />
      </Carousel>
    </div>
  )
}

// Auto-slide
function AutoSlideCarousel() {
  return (
    <div className="h-56 sm:h-64 xl:h-80 2xl:h-96">
      <Carousel slideInterval={3000}>
        <img src="/carousel-1.svg" alt="Slide 1" />
        <img src="/carousel-2.svg" alt="Slide 2" />
        <img src="/carousel-3.svg" alt="Slide 3" />
      </Carousel>
    </div>
  )
}

Sidebar

Code
TypeScript
import { Sidebar } from 'flowbite-react'
import {
  HiArrowSmRight,
  HiChartPie,
  HiInbox,
  HiShoppingBag,
  HiTable,
  HiUser,
} from 'react-icons/hi'

function SidebarExample() {
  return (
    <Sidebar aria-label="Default sidebar example">
      <Sidebar.Items>
        <Sidebar.ItemGroup>
          <Sidebar.Item href="#" icon={HiChartPie}>
            Dashboard
          </Sidebar.Item>
          <Sidebar.Item href="#" icon={HiInbox} label="3">
            Inbox
          </Sidebar.Item>
          <Sidebar.Item href="#" icon={HiUser}>
            Users
          </Sidebar.Item>
          <Sidebar.Item href="#" icon={HiShoppingBag}>
            Products
          </Sidebar.Item>
          <Sidebar.Item href="#" icon={HiArrowSmRight}>
            Sign In
          </Sidebar.Item>
          <Sidebar.Item href="#" icon={HiTable}>
            Sign Up
          </Sidebar.Item>
        </Sidebar.ItemGroup>
      </Sidebar.Items>
    </Sidebar>
  )
}

// With collapse (submenu)
function SidebarWithCollapse() {
  return (
    <Sidebar aria-label="Sidebar with multi-level dropdown">
      <Sidebar.Items>
        <Sidebar.ItemGroup>
          <Sidebar.Item href="#" icon={HiChartPie}>
            Dashboard
          </Sidebar.Item>
          <Sidebar.Collapse icon={HiShoppingBag} label="E-commerce">
            <Sidebar.Item href="#">Products</Sidebar.Item>
            <Sidebar.Item href="#">Billing</Sidebar.Item>
            <Sidebar.Item href="#">Invoice</Sidebar.Item>
          </Sidebar.Collapse>
          <Sidebar.Item href="#" icon={HiInbox}>
            Inbox
          </Sidebar.Item>
          <Sidebar.Item href="#" icon={HiUser}>
            Users
          </Sidebar.Item>
        </Sidebar.ItemGroup>
      </Sidebar.Items>
    </Sidebar>
  )
}

// With logo
function SidebarWithLogo() {
  return (
    <Sidebar aria-label="Sidebar with logo">
      <Sidebar.Logo href="#" img="/logo.svg" imgAlt="Flowbite logo">
        Flowbite
      </Sidebar.Logo>
      <Sidebar.Items>
        <Sidebar.ItemGroup>
          <Sidebar.Item href="#" icon={HiChartPie}>
            Dashboard
          </Sidebar.Item>
          <Sidebar.Item href="#" icon={HiUser}>
            Users
          </Sidebar.Item>
        </Sidebar.ItemGroup>
      </Sidebar.Items>
    </Sidebar>
  )
}

Drawer (Offcanvas)

Code
TypeScript
import { useState } from 'react'
import { Button, Drawer } from 'flowbite-react'

function DrawerExample() {
  const [isOpen, setIsOpen] = useState(false)

  return (
    <>
      <Button onClick={() => setIsOpen(true)}>Open drawer</Button>

      <Drawer open={isOpen} onClose={() => setIsOpen(false)}>
        <Drawer.Header title="Drawer" />
        <Drawer.Items>
          <p className="mb-6 text-sm text-gray-500 dark:text-gray-400">
            Supercharge your hiring by taking advantage of our limited-time sale.
          </p>
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            <Button>Learn more</Button>
            <Button color="gray" outline>
              Get access
            </Button>
          </div>
        </Drawer.Items>
      </Drawer>
    </>
  )
}

// Drawer from different positions
function DrawerPositions() {
  const [leftOpen, setLeftOpen] = useState(false)
  const [rightOpen, setRightOpen] = useState(false)
  const [topOpen, setTopOpen] = useState(false)
  const [bottomOpen, setBottomOpen] = useState(false)

  return (
    <div className="flex gap-4">
      <Button onClick={() => setLeftOpen(true)}>Left</Button>
      <Drawer open={leftOpen} onClose={() => setLeftOpen(false)} position="left">
        <Drawer.Header title="Left Drawer" />
        <Drawer.Items>
          <p>Content from the left</p>
        </Drawer.Items>
      </Drawer>

      <Button onClick={() => setRightOpen(true)}>Right</Button>
      <Drawer open={rightOpen} onClose={() => setRightOpen(false)} position="right">
        <Drawer.Header title="Right Drawer" />
        <Drawer.Items>
          <p>Content from the right</p>
        </Drawer.Items>
      </Drawer>

      <Button onClick={() => setTopOpen(true)}>Top</Button>
      <Drawer open={topOpen} onClose={() => setTopOpen(false)} position="top">
        <Drawer.Header title="Top Drawer" />
        <Drawer.Items>
          <p>Content from the top</p>
        </Drawer.Items>
      </Drawer>

      <Button onClick={() => setBottomOpen(true)}>Bottom</Button>
      <Drawer open={bottomOpen} onClose={() => setBottomOpen(false)} position="bottom">
        <Drawer.Header title="Bottom Drawer" />
        <Drawer.Items>
          <p>Content from the bottom</p>
        </Drawer.Items>
      </Drawer>
    </div>
  )
}

Datepicker

Code
TypeScript
import { Datepicker } from 'flowbite-react'

function DatepickerExamples() {
  return (
    <div className="flex flex-col gap-4">
      {/* Basic */}
      <Datepicker />

      {/* With default date */}
      <Datepicker defaultDate={new Date(2024, 0, 15)} />

      {/* With min and max date */}
      <Datepicker
        minDate={new Date(2024, 0, 1)}
        maxDate={new Date(2024, 11, 31)}
      />

      {/* Inline */}
      <Datepicker inline />

      {/* With title */}
      <Datepicker title="Select Date" />

      {/* Auto hide */}
      <Datepicker autoHide={false} />

      {/* Controlled */}
      <Datepicker
        onSelectedDateChanged={(date) => console.log(date)}
      />

      {/* With labels */}
      <Datepicker
        showClearButton
        showTodayButton
        labelClearButton="Clear"
        labelTodayButton="Today"
      />

      {/* Different languages */}
      <Datepicker language="en-US" />

      {/* Week starts on Monday */}
      <Datepicker weekStart={1} />
    </div>
  )
}

Dropdown

Code
TypeScript
import { Dropdown, Button } from 'flowbite-react'

function DropdownExamples() {
  return (
    <div className="flex gap-4">
      {/* Basic */}
      <Dropdown label="Dropdown">
        <Dropdown.Item>Dashboard</Dropdown.Item>
        <Dropdown.Item>Settings</Dropdown.Item>
        <Dropdown.Item>Earnings</Dropdown.Item>
        <Dropdown.Item>Sign out</Dropdown.Item>
      </Dropdown>

      {/* With divider */}
      <Dropdown label="Actions">
        <Dropdown.Item>Edit</Dropdown.Item>
        <Dropdown.Item>Export</Dropdown.Item>
        <Dropdown.Divider />
        <Dropdown.Item>Delete</Dropdown.Item>
      </Dropdown>

      {/* With header */}
      <Dropdown label="User menu">
        <Dropdown.Header>
          <span className="block text-sm">John Doe</span>
          <span className="block truncate text-sm font-medium">
            john@example.com
          </span>
        </Dropdown.Header>
        <Dropdown.Item>Profile</Dropdown.Item>
        <Dropdown.Item>Settings</Dropdown.Item>
        <Dropdown.Divider />
        <Dropdown.Item>Sign out</Dropdown.Item>
      </Dropdown>

      {/* With icons */}
      <Dropdown label="Options">
        <Dropdown.Item icon={HiViewGrid}>Dashboard</Dropdown.Item>
        <Dropdown.Item icon={HiCog}>Settings</Dropdown.Item>
        <Dropdown.Item icon={HiCurrencyDollar}>Earnings</Dropdown.Item>
        <Dropdown.Divider />
        <Dropdown.Item icon={HiLogout}>Sign out</Dropdown.Item>
      </Dropdown>

      {/* Inline (no border) */}
      <Dropdown inline label="Inline dropdown">
        <Dropdown.Item>Item 1</Dropdown.Item>
        <Dropdown.Item>Item 2</Dropdown.Item>
      </Dropdown>

      {/* Different sizes */}
      <Dropdown label="Small" size="sm">
        <Dropdown.Item>Item</Dropdown.Item>
      </Dropdown>

      <Dropdown label="Large" size="lg">
        <Dropdown.Item>Item</Dropdown.Item>
      </Dropdown>

      {/* Different placements */}
      <Dropdown label="Top" placement="top">
        <Dropdown.Item>Opens at top</Dropdown.Item>
      </Dropdown>

      <Dropdown label="Left" placement="left">
        <Dropdown.Item>Opens at left</Dropdown.Item>
      </Dropdown>
    </div>
  )
}

Accordion

Code
TypeScript
import { Accordion } from 'flowbite-react'

function AccordionExample() {
  return (
    <Accordion>
      <Accordion.Panel>
        <Accordion.Title>What is Flowbite?</Accordion.Title>
        <Accordion.Content>
          <p className="mb-2 text-gray-500 dark:text-gray-400">
            Flowbite is an open-source library of interactive components built on top of Tailwind CSS.
          </p>
          <p className="text-gray-500 dark:text-gray-400">
            Check out the{' '}
            <a
              href="https://flowbite.com/docs/getting-started/introduction/"
              className="text-cyan-600 hover:underline dark:text-cyan-500"
            >
              getting started guide
            </a>{' '}
            and start building websites.
          </p>
        </Accordion.Content>
      </Accordion.Panel>
      <Accordion.Panel>
        <Accordion.Title>Is there a Figma file?</Accordion.Title>
        <Accordion.Content>
          <p className="mb-2 text-gray-500 dark:text-gray-400">
            Yes! You can get the Figma file in Flowbite Pro.
          </p>
        </Accordion.Content>
      </Accordion.Panel>
      <Accordion.Panel>
        <Accordion.Title>What frameworks are supported?</Accordion.Title>
        <Accordion.Content>
          <p className="mb-2 text-gray-500 dark:text-gray-400">
            React, Vue, Svelte, Angular, and vanilla JavaScript.
          </p>
        </Accordion.Content>
      </Accordion.Panel>
    </Accordion>
  )
}

// Always open (all panels)
function AccordionAlwaysOpen() {
  return (
    <Accordion alwaysOpen>
      <Accordion.Panel>
        <Accordion.Title>Panel 1</Accordion.Title>
        <Accordion.Content>
          <p>Content 1</p>
        </Accordion.Content>
      </Accordion.Panel>
      <Accordion.Panel>
        <Accordion.Title>Panel 2</Accordion.Title>
        <Accordion.Content>
          <p>Content 2</p>
        </Accordion.Content>
      </Accordion.Panel>
    </Accordion>
  )
}

// Without border
function AccordionFlush() {
  return (
    <Accordion flush>
      <Accordion.Panel>
        <Accordion.Title>Panel without borders</Accordion.Title>
        <Accordion.Content>
          <p>Cleaner look</p>
        </Accordion.Content>
      </Accordion.Panel>
    </Accordion>
  )
}

Table

Code
TypeScript
import { Table, Checkbox, Button } from 'flowbite-react'

function TableExample() {
  return (
    <div className="overflow-x-auto">
      <Table>
        <Table.Head>
          <Table.HeadCell className="p-4">
            <Checkbox />
          </Table.HeadCell>
          <Table.HeadCell>Product name</Table.HeadCell>
          <Table.HeadCell>Color</Table.HeadCell>
          <Table.HeadCell>Category</Table.HeadCell>
          <Table.HeadCell>Price</Table.HeadCell>
          <Table.HeadCell>
            <span className="sr-only">Edit</span>
          </Table.HeadCell>
        </Table.Head>
        <Table.Body className="divide-y">
          <Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
            <Table.Cell className="p-4">
              <Checkbox />
            </Table.Cell>
            <Table.Cell className="whitespace-nowrap font-medium text-gray-900 dark:text-white">
              Apple MacBook Pro 17"
            </Table.Cell>
            <Table.Cell>Silver</Table.Cell>
            <Table.Cell>Laptop</Table.Cell>
            <Table.Cell>$2999</Table.Cell>
            <Table.Cell>
              <a href="#" className="font-medium text-cyan-600 hover:underline dark:text-cyan-500">
                Edit
              </a>
            </Table.Cell>
          </Table.Row>
          <Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
            <Table.Cell className="p-4">
              <Checkbox />
            </Table.Cell>
            <Table.Cell className="whitespace-nowrap font-medium text-gray-900 dark:text-white">
              Microsoft Surface Pro
            </Table.Cell>
            <Table.Cell>White</Table.Cell>
            <Table.Cell>Laptop PC</Table.Cell>
            <Table.Cell>$1999</Table.Cell>
            <Table.Cell>
              <a href="#" className="font-medium text-cyan-600 hover:underline dark:text-cyan-500">
                Edit
              </a>
            </Table.Cell>
          </Table.Row>
        </Table.Body>
      </Table>
    </div>
  )
}

// Striped
function StripedTable() {
  return (
    <Table striped>
      <Table.Head>
        <Table.HeadCell>Name</Table.HeadCell>
        <Table.HeadCell>Email</Table.HeadCell>
      </Table.Head>
      <Table.Body className="divide-y">
        <Table.Row>
          <Table.Cell>John Doe</Table.Cell>
          <Table.Cell>john@example.com</Table.Cell>
        </Table.Row>
        <Table.Row>
          <Table.Cell>Jane Smith</Table.Cell>
          <Table.Cell>jane@example.com</Table.Cell>
        </Table.Row>
      </Table.Body>
    </Table>
  )
}

// Hoverable
function HoverableTable() {
  return (
    <Table hoverable>
      <Table.Head>
        <Table.HeadCell>Product</Table.HeadCell>
        <Table.HeadCell>Price</Table.HeadCell>
      </Table.Head>
      <Table.Body className="divide-y">
        <Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
          <Table.Cell>Product 1</Table.Cell>
          <Table.Cell>$99</Table.Cell>
        </Table.Row>
        <Table.Row className="bg-white dark:border-gray-700 dark:bg-gray-800">
          <Table.Cell>Product 2</Table.Cell>
          <Table.Cell>$149</Table.Cell>
        </Table.Row>
      </Table.Body>
    </Table>
  )
}

Forms

Code
TypeScript
import { Label, TextInput, Textarea, Select, Checkbox, Radio, FileInput, ToggleSwitch, RangeSlider, Button } from 'flowbite-react'
import { HiMail, HiLockClosed } from 'react-icons/hi'

function FormExamples() {
  return (
    <form className="flex max-w-md flex-col gap-4">
      {/* Text Input */}
      <div>
        <div className="mb-2 block">
          <Label htmlFor="email" value="Your email" />
        </div>
        <TextInput
          id="email"
          type="email"
          placeholder="name@flowbite.com"
          required
          icon={HiMail}
        />
      </div>

      {/* Password */}
      <div>
        <div className="mb-2 block">
          <Label htmlFor="password" value="Your password" />
        </div>
        <TextInput
          id="password"
          type="password"
          required
          icon={HiLockClosed}
        />
      </div>

      {/* Input sizes */}
      <TextInput sizing="sm" placeholder="Small" />
      <TextInput sizing="md" placeholder="Medium (default)" />
      <TextInput sizing="lg" placeholder="Large" />

      {/* Textarea */}
      <div>
        <div className="mb-2 block">
          <Label htmlFor="comment" value="Your message" />
        </div>
        <Textarea
          id="comment"
          placeholder="Leave a comment..."
          rows={4}
        />
      </div>

      {/* Select */}
      <div>
        <div className="mb-2 block">
          <Label htmlFor="countries" value="Select your country" />
        </div>
        <Select id="countries" required>
          <option>United States</option>
          <option>Canada</option>
          <option>France</option>
          <option>Germany</option>
        </Select>
      </div>

      {/* Checkbox */}
      <div className="flex items-center gap-2">
        <Checkbox id="remember" />
        <Label htmlFor="remember">Remember me</Label>
      </div>

      {/* Radio */}
      <fieldset className="flex max-w-md flex-col gap-4">
        <legend className="mb-4">Choose your delivery</legend>
        <div className="flex items-center gap-2">
          <Radio id="standard" name="delivery" value="standard" defaultChecked />
          <Label htmlFor="standard">Standard (5-7 days)</Label>
        </div>
        <div className="flex items-center gap-2">
          <Radio id="express" name="delivery" value="express" />
          <Label htmlFor="express">Express (1-2 days)</Label>
        </div>
      </fieldset>

      {/* File Input */}
      <div>
        <div className="mb-2 block">
          <Label htmlFor="file" value="Upload file" />
        </div>
        <FileInput id="file" />
      </div>

      {/* Toggle Switch */}
      <ToggleSwitch
        checked={true}
        label="Enable notifications"
        onChange={() => {}}
      />

      {/* Range Slider */}
      <div>
        <div className="mb-2 block">
          <Label htmlFor="default-range" value="Default range" />
        </div>
        <RangeSlider id="default-range" />
      </div>

      <Button type="submit">Submit</Button>
    </form>
  )
}

Card

Code
TypeScript
import { Card, Button } from 'flowbite-react'

function CardExamples() {
  return (
    <div className="flex flex-wrap gap-4">
      {/* Basic card */}
      <Card className="max-w-sm">
        <h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
          Noteworthy technology acquisitions 2021
        </h5>
        <p className="font-normal text-gray-700 dark:text-gray-400">
          Here are the biggest enterprise technology acquisitions of 2021.
        </p>
      </Card>

      {/* Card with button */}
      <Card className="max-w-sm">
        <h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
          Noteworthy technology acquisitions 2021
        </h5>
        <p className="font-normal text-gray-700 dark:text-gray-400">
          Here are the biggest enterprise technology acquisitions.
        </p>
        <Button>
          Read more
          <svg
            className="-mr-1 ml-2 h-4 w-4"
            fill="currentColor"
            viewBox="0 0 20 20"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              fillRule="evenodd"
              d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z"
              clipRule="evenodd"
            />
          </svg>
        </Button>
      </Card>

      {/* Card with image */}
      <Card
        className="max-w-sm"
        imgAlt="Meaningful alt text"
        imgSrc="/card-image.jpg"
      >
        <h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
          Noteworthy technology acquisitions 2021
        </h5>
        <p className="font-normal text-gray-700 dark:text-gray-400">
          Here are the biggest enterprise technology acquisitions.
        </p>
      </Card>

      {/* Horizontal card */}
      <Card
        className="max-w-sm"
        imgAlt="Meaningful alt text"
        imgSrc="/card-image.jpg"
        horizontal
      >
        <h5 className="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
          Horizontal card
        </h5>
        <p className="font-normal text-gray-700 dark:text-gray-400">
          This is a horizontal card layout.
        </p>
      </Card>
    </div>
  )
}

Toast

Code
TypeScript
import { Toast } from 'flowbite-react'
import { HiCheck, HiExclamation, HiX, HiFire } from 'react-icons/hi'

function ToastExamples() {
  return (
    <div className="flex flex-col gap-4">
      {/* Success toast */}
      <Toast>
        <div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-green-100 text-green-500 dark:bg-green-800 dark:text-green-200">
          <HiCheck className="h-5 w-5" />
        </div>
        <div className="ml-3 text-sm font-normal">Item moved successfully.</div>
        <Toast.Toggle />
      </Toast>

      {/* Error toast */}
      <Toast>
        <div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-red-100 text-red-500 dark:bg-red-800 dark:text-red-200">
          <HiX className="h-5 w-5" />
        </div>
        <div className="ml-3 text-sm font-normal">Item has been deleted.</div>
        <Toast.Toggle />
      </Toast>

      {/* Warning toast */}
      <Toast>
        <div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-orange-100 text-orange-500 dark:bg-orange-700 dark:text-orange-200">
          <HiExclamation className="h-5 w-5" />
        </div>
        <div className="ml-3 text-sm font-normal">Improve password difficulty.</div>
        <Toast.Toggle />
      </Toast>

      {/* Custom icon */}
      <Toast>
        <div className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-cyan-100 text-cyan-500 dark:bg-cyan-800 dark:text-cyan-200">
          <HiFire className="h-5 w-5" />
        </div>
        <div className="ml-3 text-sm font-normal">
          Set yourself free.
        </div>
        <Toast.Toggle />
      </Toast>
    </div>
  )
}

Flowbite blocks

Flowbite offers 450+ ready-made blocks (page sections) that you can copy and use. Here are the categories:

Available categories:

  • Marketing: Hero, Feature, CTA, Content, Testimonial, Blog, Newsletter, Contact
  • Application: Sidebar, Navbar, Footer, CRUD tables, User cards
  • Publisher: Article, Blog post, Comment sections
  • E-commerce: Product cards, Cart, Checkout, Pricing

Hero Block Example (Copy-paste HTML)

Code
HTML
<section class="bg-white dark:bg-gray-900">
    <div class="grid max-w-screen-xl px-4 py-8 mx-auto lg:gap-8 xl:gap-0 lg:py-16 lg:grid-cols-12">
        <div class="mr-auto place-self-center lg:col-span-7">
            <h1 class="max-w-2xl mb-4 text-4xl font-extrabold tracking-tight leading-none md:text-5xl xl:text-6xl dark:text-white">
                Payments tool for software companies
            </h1>
            <p class="max-w-2xl mb-6 font-light text-gray-500 lg:mb-8 md:text-lg lg:text-xl dark:text-gray-400">
                From checkout to global sales tax compliance, companies around the world use Flowbite to simplify their payment stack.
            </p>
            <a href="#" class="inline-flex items-center justify-center px-5 py-3 mr-3 text-base font-medium text-center text-white rounded-lg bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 dark:focus:ring-primary-900">
                Get started
            </a>
            <a href="#" class="inline-flex items-center justify-center px-5 py-3 text-base font-medium text-center text-gray-900 border border-gray-300 rounded-lg hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 dark:text-white dark:border-gray-700 dark:hover:bg-gray-700 dark:focus:ring-gray-800">
                Speak to Sales
            </a>
        </div>
        <div class="hidden lg:mt-0 lg:col-span-5 lg:flex">
            <img src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/hero/phone-mockup.png" alt="mockup">
        </div>
    </div>
</section>

Dark mode

Flowbite fully supports dark mode through the dark: class:

JStailwind.config.js
JavaScript
// tailwind.config.js
module.exports = {
  darkMode: 'class',
  // ...
}
Code
TypeScript
// Dark mode toggle
import { useState, useEffect } from 'react'
import { DarkThemeToggle } from 'flowbite-react'

function DarkModeToggle() {
  return (
    <DarkThemeToggle />
  )
}

// Or custom implementation
function CustomDarkModeToggle() {
  const [isDark, setIsDark] = useState(false)

  useEffect(() => {
    if (isDark) {
      document.documentElement.classList.add('dark')
    } else {
      document.documentElement.classList.remove('dark')
    }
  }, [isDark])

  return (
    <button onClick={() => setIsDark(!isDark)}>
      {isDark ? '🌙' : '☀️'}
    </button>
  )
}

Flowbite icons

Flowbite also offers a set of 500+ free SVG icons:

Code
Bash
npm install flowbite-icons
Code
TypeScript
import { HiOutlineSearch, HiOutlineMenu, HiOutlineUser } from 'flowbite-icons-react/outline'
import { HiSearch, HiMenu, HiUser } from 'flowbite-icons-react/solid'

function IconsExample() {
  return (
    <div className="flex gap-4">
      {/* Outline icons */}
      <HiOutlineSearch className="w-6 h-6" />
      <HiOutlineMenu className="w-6 h-6" />
      <HiOutlineUser className="w-6 h-6" />

      {/* Solid icons */}
      <HiSearch className="w-6 h-6" />
      <HiMenu className="w-6 h-6" />
      <HiUser className="w-6 h-6" />
    </div>
  )
}

Pricing

Open Source (Free)

  • 50+ components
  • Basic blocks
  • Full framework support
  • Documentation
  • MIT License

Flowbite Pro ($149+)

  • 450+ premium blocks
  • Complete Figma set
  • Admin dashboard
  • E-commerce templates
  • CRM templates
  • Priority support
  • Lifetime updates

FAQ - frequently asked questions

Does Flowbite require JavaScript?

For static components (buttons, cards, typography) - no. For interactive ones (dropdown, modal, datepicker) - yes.

Does Flowbite work with Next.js?

Yes! flowbite-react is fully compatible with Next.js App Router.

How do I add custom styles to components?

Use the className or theme prop:

Code
TypeScript
<Button className="my-custom-class">
  Custom styled
</Button>

// Or with theme
<Button theme={{ base: "my-custom-base-class" }}>
  Theme styled
</Button>

Can I use Flowbite with Vite?

Yes, Flowbite works with all bundlers - Vite, Webpack, esbuild, etc.

What's the difference between Flowbite and DaisyUI?

Flowbite offers JavaScript components for interactivity (modal, dropdown), DaisyUI is CSS only. Flowbite supports multiple frameworks, DaisyUI works everywhere Tailwind does.

Summary

Flowbite is a versatile UI toolkit for Tailwind CSS offering:

  • 50+ free components
  • 450+ blocks in Pro version
  • Support for React, Vue, Svelte, Angular and vanilla JS
  • Built-in dark mode
  • Full responsiveness
  • Excellent documentation

It's an excellent choice for developers looking for ready-made components who don't want to build everything from scratch.