Using Bootstrap in ReactJS: reactstrap or react-bootstrap?

cassiolacerda

Cássio Lacerda

Posted on June 2, 2021

Using Bootstrap in ReactJS: reactstrap or react-bootstrap?

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, Foundation or Material 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:

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.


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
);



Enter fullscreen mode Exit fullscreen mode
  • 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



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;


Enter fullscreen mode Exit fullscreen mode

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

Alt Text

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



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"];


Enter fullscreen mode Exit fullscreen mode

Reactstrap



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);


Enter fullscreen mode Exit fullscreen mode

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

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!

💖 💪 🙅 🚩
cassiolacerda
Cássio Lacerda

Posted on June 2, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Starting the #100daysofcode challenge
undefined Starting the #100daysofcode challenge

March 12, 2024

Make Resume in 60 Seconds
beginners Make Resume in 60 Seconds

March 8, 2024

Project - MMO Games
javascript Project - MMO Games

June 30, 2023