Bootstrap 2,007 is a CSS toolkit plus a JavaScript bundle that makes its interactive pieces work. That JavaScript is the problem in React 7,897 : Bootstrap's plugins find elements with querySelector, toggle classes on them and keep state in DOM attributes — exactly the mutations React assumes nobody else is making. React Bootstrap 126 rebuilds every widget as a real component whose state lives in React, with no jQuery 561 . You keep the stylesheet, imported once at the entry point.
import 'bootstrap/dist/css/bootstrap.min.css'; // npm install react-bootstrap bootstrap
import { Card, Button, Badge } from 'react-bootstrap';
export default function ProductCard({ product, onAdd }) {
return (
<Card style={{ width: '18rem' }}>
<Card.Body>
<Card.Title>{product.name} <Badge bg="success">new</Badge></Card.Title>
<Card.Text className="text-muted">${product.price.toFixed(2)}</Card.Text>
<Button variant="primary" size="sm" onClick={() => onAdd(product.id)}>
Add to cart</Button>
</Card.Body>
</Card>
);
}Three conventions carry across the library. Compound components use dot notation (Card.Body, Card.Title), keeping the JSX shaped like the markup Bootstrap expects. Class-name choices become props: variant="primary" and size="sm" produce btn btn-primary btn-sm. Unrecognized props — className, id, data-*, aria-*, ref — are forwarded to the DOM element underneath, the escape hatch for whatever the API did not anticipate.
Version 2.10.10 targets Bootstrap 5.3 and runs against React 19.3.0, as the next subsection's demo shows; 3.0.0-beta.5 sits on the next tag, so read the v3 migration notes before starting something large. Bigger styled kits exist — MUI 9.4.0 55,831 at 7.2 M weekly downloads, Ant Design 6.6.4 67,083 at 2.7 M, Mantine 9.6.1 623,377 at 1.8 M — but this is the shortest step from the Bootstrap you know.