How to Convert React Component to Web Component

I have often faced a common challenge: sharing a UI library across different teams. One team might be using Vue, another Angular, and a third might be sticking to plain HTML and jQuery.

Rebuilding the same header or data table for every single framework is a massive waste of time and resources.

That is why I started converting my React components into Web Components, allowing them to run anywhere.

In this tutorial, I will show you exactly how to wrap your React code into a custom element that works in any browser.

Use Web Components in Your React Projects

Web Components are platform-agnostic, meaning they are not tied to the React lifecycle or its specific ecosystem.

If you are building a widget for a US-based fintech app, you want that widget to work on a partner’s site regardless of their tech stack.

By converting to a Web Component, you get encapsulation through the Shadow DOM, preventing CSS leaks.

Method 1: Use the @r2wc/react-to-web-component Library

This is my favorite “lightweight” method when I need to quickly export a single component without much overhead.

I recently used this to share a specialized “US Zip Code Validator” component across several legacy marketing pages.

First, you need to install the package in your React project:

npm install @r2wc/react-to-web-component

Now, let’s create a React component that calculates a simple Sales Tax based on a US state rate.

The React Component (SalesTaxCalculator.js):

import React from 'react';

const SalesTaxCalculator = ({ amount, stateName }) => {
  const taxRates = {
    'California': 0.0725,
    'New York': 0.04,
    'Texas': 0.0625,
    'Florida': 0.06
  };

  const rate = taxRates[stateName] || 0;
  const total = parseFloat(amount) + (amount * rate);

  return (
    <div style={{ padding: '20px', border: '1px solid #000', borderRadius: '8px', fontFamily: 'Arial' }}>
      <h3>Tax Estimate for {stateName}</h3>
      <p>Original Amount: ${amount}</p>
      <p>Tax Rate: {(rate * 100).toFixed(2)}%</p>
      <hr />
      <h4>Total: ${total.toFixed(2)}</h4>
    </div>
  );
};

export default SalesTaxCalculator;

The Conversion Logic (index.js):

import r2wc from "@r2wc/react-to-web-component";
import SalesTaxCalculator from "./SalesTaxCalculator";

const WebSalesTax = r2wc(SalesTaxCalculator, {
  props: {
    amount: "number",
    stateName: "string"
  },
});

customElements.define("us-sales-tax-calculator", WebSalesTax);

Once defined, you can use this in a standard index.html file like this:

<script src="path-to-your-bundle.js"></script>
<us-sales-tax-calculator amount="100" state-name="California"></us-sales-tax-calculator>

I executed the above example code and added the screenshot below.

React Component to Web Component

I find this method incredibly reliable because it handles the mapping of HTML attributes to React props automatically.

Method 2: Use Direflow for Complex Integrations

When I am working on a larger project that requires specialized styling or many dependencies, I turn to Direflow.

Direflow is a powerful framework that lets you build Web Components using React with a dedicated configuration.

It is particularly useful if you need to ensure your US-specific fonts or CSS frameworks like Tailwind stay scoped.

To start, you can use the Direflow CLI to create a new project:

npx direflow-cli create

Let’s build a “US Mortgage Interest Rate” tracker that updates based on a property value.

The Direflow Component (MortgageTracker.js):

import React, { useContext } from 'react';
import { Styled } from 'direflow-component';
import styles from './MortgageTracker.css';

const MortgageTracker = (props) => {
  const { propertyValue, downPayment } = props;
  const loanAmount = propertyValue - downPayment;

  return (
    <Styled styles={styles}>
      <div className="tracker-container">
        <h2>Mortgage Summary</h2>
        <div className="stats">
          <span>Loan Amount: <strong>${loanAmount.toLocaleString()}</strong></span>
          <span>Location: <strong>USA (National Average)</strong></span>
        </div>
        <p className="disclaimer">Rates are subject to credit approval.</p>
      </div>
    </Styled>
  );
};

export default MortgageTracker;

Registration in direflow-components/index.js:

import { DireflowComponent } from 'direflow-component';
import MortgageTracker from './MortgageTracker';

export default DireflowComponent.create({
  component: MortgageTracker,
  configuration: {
    tagname: 'us-mortgage-tracker',
    useShadowDom: true,
  },
  propShape: {
    propertyValue: 400000,
    downPayment: 80000,
  },
});

Using Direflow feels more like a “production-ready” setup for corporate environments in the US.

It handles the Shadow DOM perfectly, which ensures that your component’s styles don’t mess up the rest of the website.

Method 3: The Manual Wrapper Approach (No Libraries)

Sometimes, I don’t want to add another dependency to my package.json file. In these cases, I write a simple vanilla JavaScript wrapper using the HTMLElement class.

This gives me total control over when the React tree mounts and unmounts.

The Wrapper Code:

import React from 'react';
import ReactDOM from 'react-dom/client';
import MyReactComponent from './MyReactComponent';

class ReactWebComponent extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    this.render();
  }

  static get observedAttributes() {
    return ['user-name'];
  }

  attributeChangedCallback() {
    this.render();
  }

  render() {
    const name = this.getAttribute('user-name') || 'Guest';
    const root = ReactDOM.createRoot(this.shadowRoot);
    root.render(<MyReactComponent userName={name} />);
  }
}

customElements.define('custom-react-element', ReactWebComponent);

I executed the above example code and added the screenshot below.

Convert React Component to Web Component

I used this manual approach recently for a US Government project where we had strict security audits on external libraries.

It is clean, uses the native browser API, and shows exactly how the integration works under the hood.

Handle CSS in Web Components

One thing I learned the hard way is that global CSS does not work inside the Shadow DOM.

If you are using Bootstrap or Tailwind, those styles won’t automatically apply to your new Web Component.

You must either inject the styles into the Shadow Root or use CSS-in-JS libraries like Styled-components.

For my US-based clients, I usually recommend Styled-components because it handles the scoping naturally.

Pass Data and Events

Passing strings and numbers as attributes is easy, but passing objects or arrays can be tricky.

Attributes only support strings, so you often have to JSON.parse your data inside the component.

For events, I usually dispatch a CustomEvent from the React component so the parent app can listen to it.

// Inside React
const handleClick = () => {
  const event = new CustomEvent('onDataSubmit', {
    detail: { userId: 123 },
    bubbles: true,
    composed: true
  });
  elementRef.current.dispatchEvent(event);
};

This makes your React component behave exactly like a native HTML button or input field.

Test Your Web Component

Once you have converted your component, test it in a blank HTML file without any React loaded globally.

I always check for “FOUC” (Flash of Unstyled Content), which can happen if your JS bundle is large.

If the component is for the US market, ensure it meets ADA compliance and accessibility standards.

Web Components are great for accessibility because they allow you to use semantic HTML within the Shadow DOM.

Performance Considerations

Every time you wrap a React component, you are essentially shipping the React library with it.

If you have 10 different Web Components, each with its own version of React, your page will be very slow.

I recommend either bundling React as a “peer dependency” or using a single shared runtime bundle.

This keeps your load times fast for users on slower mobile connections across the US.

I hope this tutorial has been helpful and gives you the confidence to start using Web Components.

Converting React components to Web Components is a great way to future-proof your work and collaborate better.

You may also like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.