Using Bootstrap in ReactJS: reactstrap or react-bootstrap?
Tags: javascript, react, bootstrap
Published: 2021-06-02 00:07:14

It's hard to find developers who have been working with client-side development in the last years, and who haven't at least once used frameworks like [Bootstrap](https://getbootstrap.com/), [Foundation](https://get.foundation/) or [Material Design](https://material.io/design) in your frontend projects, to be more productive and save time by reusing pre-made components with ease of customization.

For those who have specifically used Bootstrap for years in development with server-side rendered pages (SSR) and who are now using SPA frameworks like ReactJS, it's normal to start looking for alternative packages in the NPM directory that make it easier to use the built-in Bootstrap with ReactJS.

If you've arrived here, you've probably already researched that the two most popular alternatives within this scenario today are `React Bootstrap` and `Reactstrap`. But what's the difference between them? Are they significant?

Official documentations:

 - [React Bootstrap](https://react-bootstrap.github.io/)
 - [Reactstrap](https://reactstrap.github.io/)

Both work in the same way, from the perspective of use:

 - They need `npm install bootstrap` to import Bootstrap stylesheet file inside index.js or App.js to enable Bootstrap default styling with `import 'bootstrap/dist/css/bootstrap.min.css';`. ReactJS, by default, will append all Bootstrap CSS code in a style tag inside head of HTML page.

```jsx
import { StrictMode } from "react";
import ReactDOM from "react-dom";

import "bootstrap/dist/css/bootstrap.min.css";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

```
 - Give us ready-to-use Bootstrap Components redesigned internally as JSX, without the need to use JQuery or Javascript with direct DOM manipulation (using Virtual DOM, as React already works by default);
 - Behind the scenes, using `React.createElement` to render the components;

# Props

The props passed to the components can have different names depending on the package. See the Button color usage: https://codesandbox.io/s/reactbootstrapvsreactstrap-7y87c-7y87c?file=/src/App.js

```jsx
import React from "react";

import { Button as ReactBootstrapButton } from "react-bootstrap";
import { Button as ReactstrapButton } from "reactstrap";

const App = () => (
  <>
    <ReactBootstrapButton variant="danger">React BootStrap</ReactBootstrapButton>
    <ReactstrapButton color="danger">Reactstrap</ReactstrapButton>
  </>
);

export default App;
```

The props names are different `color` and `variant`, but rendered HTML is pretty much the same, as we can see in DevTools:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bsifuvk92buuk45w3wgb.jpg)

# Behind the scenes

You can view both implementations, comparing a basic component as `Button` in the packages source code:

 - node_modules\react-bootstrap\cjs\Button.js (React Bootstrap ^1.6.0);
 - node_modules\reactstrap\dist\reactstrap.cjs.js line:930 (Reactstrap v^8.9.0);

## React Bootstrap
```javascript
var Button = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref) {
  var bsPrefix = _ref.bsPrefix,
      variant = _ref.variant,
      size = _ref.size,
      active = _ref.active,
      className = _ref.className,
      block = _ref.block,
      type = _ref.type,
      as = _ref.as,
      props = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["bsPrefix", "variant", "size", "active", "className", "block", "type", "as"]);
  var prefix = (0, _ThemeProvider.useBootstrapPrefix)(bsPrefix, 'btn');
  var classes = (0, _classnames.default)(className, prefix, active && 'active', variant && prefix + "-" + variant, block && prefix + "-block", size && prefix + "-" + size);

  if (props.href) {
    return /*#__PURE__*/_react.default.createElement(_SafeAnchor.default, (0, _extends2.default)({}, props, {
      as: as,
      ref: ref,
      className: (0, _classnames.default)(classes, props.disabled && 'disabled')
    }));
  }

  if (ref) {
    props.ref = ref;
  }

  if (type) {
    props.type = type;
  } else if (!as) {
    props.type = 'button';
  }

  var Component = as || 'button';
  return /*#__PURE__*/_react.default.createElement(Component, (0, _extends2.default)({}, props, {
    className: classes
  }));
});

Button.displayName = 'Button';
Button.defaultProps = defaultProps;
var _default = Button;
exports.default = _default;
module.exports = exports["default"];
```

## Reactstrap
```javascript
var Button = /*#__PURE__*/function (_React$Component) {
  _inheritsLoose(Button, _React$Component);

  function Button(props) {
    var _this;

    _this = _React$Component.call(this, props) || this;
    _this.onClick = _this.onClick.bind(_assertThisInitialized(_this));
    return _this;
  }

  var _proto = Button.prototype;

  _proto.onClick = function onClick(e) {
    if (this.props.disabled) {
      e.preventDefault();
      return;
    }

    if (this.props.onClick) {
      return this.props.onClick(e);
    }
  };

  _proto.render = function render() {
    var _this$props = this.props,
        active = _this$props.active,
        ariaLabel = _this$props['aria-label'],
        block = _this$props.block,
        className = _this$props.className,
        close = _this$props.close,
        cssModule = _this$props.cssModule,
        color = _this$props.color,
        outline = _this$props.outline,
        size = _this$props.size,
        Tag = _this$props.tag,
        innerRef = _this$props.innerRef,
        attributes = _objectWithoutPropertiesLoose(_this$props, ["active", "aria-label", "block", "className", "close", "cssModule", "color", "outline", "size", "tag", "innerRef"]);

    if (close && typeof attributes.children === 'undefined') {
      attributes.children = /*#__PURE__*/React__default.createElement("span", {
        "aria-hidden": true
      }, "\xD7");
    }

    var btnOutlineColor = "btn" + (outline ? '-outline' : '') + "-" + color;
    var classes = mapToCssModules(classNames(className, {
      close: close
    }, close || 'btn', close || btnOutlineColor, size ? "btn-" + size : false, block ? 'btn-block' : false, {
      active: active,
      disabled: this.props.disabled
    }), cssModule);

    if (attributes.href && Tag === 'button') {
      Tag = 'a';
    }

    var defaultAriaLabel = close ? 'Close' : null;
    return /*#__PURE__*/React__default.createElement(Tag, _extends({
      type: Tag === 'button' && attributes.onClick ? 'button' : undefined
    }, attributes, {
      className: classes,
      ref: innerRef,
      onClick: this.onClick,
      "aria-label": ariaLabel || defaultAriaLabel
    }));
  };

  return Button;
}(React__default.Component);
```
Despite some differences such as the approach with the use of prototype that `reactstrap` implements, and specifically in this component, the handling of some additional props, in general, there are no significant differences between them.

# Components List

Available components are 80% to 90% the same, and some of them just have different names.

**React Bootstrap**: Alerts, Accordion, Badge, Breadcrumb, Buttons, Button Group, Cards, Carousel, Dropdowns, Figures, Forms, Input Group, Images, Jumbotron, List Group, Modal, Navs, Navbar, Overlays, Pagination, Popovers, Progress, Spinners, Table, Tabs, Tooltips, Toasts. 

**Reactstrap**: Alerts, Badge, Breadcrumbs, Button Dropdown, Button Group, Buttons, Card, Carousel, Collapse, Dropdowns, Fade, Form, Input Group, Jumbotron, Layout, List, List Group, Media, Modals, Navbar, Navs, Pagination, Popovers, Progress, Spinners, Tables, Tabs, Toasts, Tooltips.

You can find out how to use them all in the official documentations showed previously in this post. 

# Differences so far? Very few ... I'm still undecided ...

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwrk6ev1q8yk2zimeplt.gif)

You're not the only one. Relax!

To be honest, just the numbers show any significant difference here. Adoption of React Bootstrap is higher. 

https://www.npmtrends.com/react-bootstrap-vs-reactstrap

OK, it's older and it maybe makes the difference.

More numbers here:

https://npmcompare.com/compare/react-bootstrap,reactstrap

# And you?

I worked with both of them, but I particularly like to use React Bootstrap, but not because of a Reactstrap deficiency, but because I have been using it for a while and have always attended to my needs. Don't you like Bootstrap? Do you prefer another component library? Yes? I like another libraries too, but that is subject to another post.

If you have any special reasons for using **React Bootstrap** or **Reactstrap**, if you know any significant performance differences, help the Community and share in the comments!