How To Create React Components That Run On Every React Framework?

Building React Components that are compatible across any React Framework — Next.js, Gatsby, React Native and more!

Lakindu Hewawasam
Bits and Pieces

--

React is used by over 1.8 million websites (as of 2023). This includes using plain React.js or even more complex frameworks like Next.js, React Native, and Gatsby.

So, if you’re part of an organization that leverages such frameworks across different projects, you’d likely need a usable design system across all these frameworks. You don’t want to face performance or compatibility issues when using React components across different frameworks.

Well, this is where my article fits in. I will show you how to maintain one React design system that fits all React frameworks!

Pst: if you wish to skip this article and jump straight to the demo, please check out the code.

Building a React Component To Support Any Framework

To accomplish this task, we’re going to be leveraging Bit.

If you’re unfamiliar with Bit, it’s a next-generation build system that lets you build composable software. It lets you design, develop, and build components in an independent environment that can be used anywhere across any project!

Yes, you heard right! These components aren’t tied to any React project.

This makes Bit the perfect candidate for building components you expect to run on any framework.

Step 01: Pre-requisites

Let’s first install Bit. To do so, run the following command:

npx @teambit/bvm install

To verify your installation, run the following command:

bit --version

If you’ve installed Bit successfully, you should see the output shown below:

Next, you’ll have to create an account on Bit Cloud. Bit Cloud will let you host your components in a remote scope that allows other projects consume the component library that you’re building.

After you’ve created an account on Bit Cloud, you can create a scope.

The scope is where all of your components will be hosted. This lets other developers consume and collaborate on it.

For this article, I’ve created a scope — react-component-library. After you've created the scope, we can start building the library.

Step 02: Setting up a Bit Workspace

Let’s create a workspace in the developer machine to build the library. To do so, run the following command:

mkdir workspace && cd workspace && bit init

You should see the following output:

Next, open the workspace in your IDE and update the workspace.jsonc file as follows:

"defaultScope": <<BIT_USERNAME>>.<<SCOPE_NAME>>,

Make this change to your workspace configuration file. This will ensure that all components created will be hosted on the scope you define. In this article, I’ve updated the defaultScope to:

"defaultScope": dummyorg.react-component-library

You can update it with the scope you created earlier and your Bit username.

Next, we’re going to do something special. We’re going to create an “environment”. This environment is what enables independent development. Currently, your workspace isn’t tied to any framework. In your workspace, you can build Node.js, Angular, Vue.js, Stencil, React.js, and many more components.

The runtime for your component is provided by the environment.

So, let’s create a React environment. To do so, run the following command:

bit create react-env envs/react-18 --aspect teambit.react/react-env

After you’ve created your environment, you can ensure that every component you create relies on this new environment.

This will let you control how each component functions and the libraries each component will use.

Step 03: Building a React Component to be used across any framework

Next, let’s create a React component running on any framework! To showcase this, let’s build an image component that can run on Next.js and React environments.

If our image component is launched in a Next.js environment, it’ll automatically use the optimization features of the image component in Next.js. If not, it’ll fall back as a regular image component.

For this, let’s use the package — next/image. We’ll have to install the Next.js library set onto our component to do so. This can be done by running the command:

bit install next  --add-missing-deps  --type peer

This will install the library as a peer dependency in your workspace. Any component that uses the next library will automatically have it bundled.

Next, let’s create a React component:

bit create react elements/image --env envs/react-18

This command will create a component called “image” and use the new environment we created earlier. Now that we have a React component, let’s see the component. To do so, let’s launch the Bit server using the command:

bit start

You can visit localhost:3000 and see the component:

Next, let’s start building the component. Open the image.tsx file and add the following snippet:

import React from 'react';
import NextImage from 'next/image';
export type ImageProps = {
isNextJs?: boolean
source: string
name: string
};
export function Image({ isNextJs = false, source, name }: ImageProps) {
return (
<NextImage
src={source}
alt={name}
fill
unoptimized={!isNextJs}
/>
);
}

As you can see, we’ve utilized the Image component by Next.js, and we’ve utilized its unoptimized prop to control the rendering strategy for different frameworks.

If it’s launched inside Next.js it’ll use the optimized version; if not, it’ll work as a regular image.

Afterward, you can create your composition to create a preview for your component.

import React from 'react';
import { Image } from './image';
export const BasicImage = () => {
return (
<Image
name='Sample Image'
source='https://fujifilm-x.com/wp-content/uploads/2021/01/gfx100s_sample_04_thum-1.jpg'
isNextJs={false}
/>
);
}

Afterward, head back to the development server and you should see the output as shown below:

And it’s as simple as that. Next you can share it to the remote scope using the commands:

bit tag && bit export

This will trigger a build in Bit’s Ripple CI and will build the component for public use. You can see the build here:

Afterward, this will be available use within Bit itself, or even as a NPM package:

You can checkout the component here.

Step 04: Consuming the component in any framework

Next, to test this out, let’s create two apps:

  1. A React App
  2. A Next.js App

Luckily for us, Bit supports both Next.js and React apps. You can build App components for each of these apps. To do so, run the commands:

// create react app
bit create react-app apps/my-app --aspect bitdev.react/react-env
// create nextjs app
bit create nextjs apps/my-nextjs-app --aspect frontend.nextjs/nextjs-env

Next, let’s make the apps runnable using the command:

bit use apps/my-app && bit use apps/my-nextjs-app

This command will ensure that your apps can run outside of the Bit workspace. Next, run bit app list to view the apps:

Next, open the page.tsx on your Next.js app and update the code:

import { Image } from '@dummyorg/react-component-library.elements.image';
import React from 'react';
export default function Home() {
return (
<Image
name='Sample Image'
source='https://fujifilm-x.com/wp-content/uploads/2021/01/gfx100s_sample_04_thum-1.jpg'
isNextJs={true}
/>
)
}

Next, launch the app using the command:

bit run my-nextjs-app

You’ll see the output shown below:

And that’s it! You’ve built yourself a component that can run on any framework!

Wrapping Up

That was easy. With Bit, you can create components that can run on any framework! And, it doesn’t end with React. Bit lets you build Node.js, Angular, Vue.js, and many more components that you can share across any framework.

For example, if you’re looking into full-stack development, you can seamlessly share entities and util functions using Bit across the front and backend.

If you like what you see, make sure to give this demo a try on your own!

Thank you for reading!

Learn More

--

--