VOOZH about

URL: https://blog.logrocket.com/creating-reusable-components-mitosis-builder-io/

⇱ Create reusable components with Mitosis and Builder.io - LogRocket Blog


2021-09-13
1339
Alex Merced
66073
👁 Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

A common challenge among development teams is using the same language; while one subteam is using Vue, another may be using React, causing redundant work and forcing you to create shared components twice.

👁 Reusable Components Mitosis

In this tutorial, we’ll explore Mitosis, a tool that can compile code to standard JavaScript in addition to frameworks and libraries like Angular, React, and Vue, allowing you to create reusable components.

We’ll review some background information to clarify when you should use Mitosis, then install Mitosis in a new project to see it in action. Let’s get started!

🚀 Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

Mitosis vs. web components

While some developers initially turned to web components to create reusable components, they encountered issues like web components’ browser compatibility and its lower-level approach, which made the creation of reusable components an intensive process.

Similarly, certain libraries like React had workflows that made incorporating web components difficult, leading to the creation of solutions like Google’s LitElement, Ionic, and Stencil.js.

Meanwhile, a parallel trend arose in Svelte and SolidJS. Intended for building applications, Svelte and SolidJS made huge performance gains by compiling the source code to standard JavaScript, creating bundles that were smaller and faster than web components.

Mitosis builds on the functionality of Svelte and SolidJS, employing the same compilation speed and allowing you to recompile a component into different frameworks and libraries from the same codebase. The compiled component operates like any other component in the framework.

Similar to SolidJS, Mitosis uses a version of JSX that compiles the components to JSON. Plugins then compile the components to different targets, allowing you to create tooling in two directions:

  • Code that can be converted into Mitosis JSON
  • Plugins that compile or serialize JSON to target frameworks

For these reasons, Mitosis supports no-code tools. For example, Builder.io allows you to create your website using a visual tool, then compile it to the framework of your choice. Builder.io acts as a CMS but is powered by Mitosis.

Mitosis uses WYSIWYG editing and a SPA framework for compilation. Now that we understand how Mitosis works, let’s create a component with Mitosis.

Getting started with Mitosis

First, we’ll install the Mitosis CLI:

npm install -g @builder.io/mitosis-cli

Create an empty folder on your computer. In your terminal, open the folder and create a new npm project:

npm init -y

Next, we’ll install Mitosis:

npm install @builder.io/mitosis

Create a file called component.lite.jsx. lite.jsx is the extension for Mitosis projects. Next, we’ll install the Builder.io VS Code extension, which provides syntax highlighting for lite.jsx files.

In the component.lite.jsx file, add the following code:

import { useState, Show, For } from "@builder.io/mitosis";
export default function Component(props){
const state = useState({count: 0})

In the code above, we declare state using the useState Hook. Now, when any property in the state object is changed, the UI will render.

Next, add the following code block to component.lite.jsx, which will return JSX like React or SolidJS:

 return (<div>
 {/* DISPLAY SOME JSX CONDITIONALLY */}
 <Show when={state.count > 10}>
 <h1>You Win!!!</h1> 
 </Show>

 {/* DISPLAY THE COUNT */}
 <h1>{state.count}</h1>

 {/* BUTTON TO ADD TO THE COUNT */}
 <button onClick={(event) => {state.count += 1}}>Click to Add One</button>
 </div>)
}

In the code above, the show component allows us to conditionally render the UI. Because state is updated with plain reassignments, there is no need to add the setState function, which we’d use in React. Lastly, notice that all our state can be bundled into one object.

Now that our component is built, let’s see some examples of our component compiled to different frameworks!

Compilation in Mitosis

React

Let’s use Mitosis to compile our component into a React component:

mitosis compile --to=react component.lite.jsx > component.jsx

The --to= flag lets us select the framework that we’ll compile our Mitosis component to. When compiled to React, we’ll get the following output:

import { useContext } from "react";
import { useLocalObservable } from "mobx-react-lite";
export default function Component(props) {
 const state = useLocalObservable(() => ({ count: 0 }));
 return (
 <div>
 {state.count > 10 && (
 <>
 <h1>You Win!!!</h1>
 </>
 )}
 <h1>{state.count}</h1>
 <button
 onClick={(event) => {
 state.count += 1;
 }}
 >
 Click to Add One
 </button>
 </div>
 );
}

Vue

--to=vue component.lite.jsx > component.vue

When compiled to Vue, our component will look like the code below:

<template>
 <div>
 {{/* DISPLAY SOME JSX CONDITIONALLY */}}
 <template v-if="count > 10">
 <h1>You Win!!!</h1>
 </template>

 {{/* DISPLAY THE COUNT */}}
 <h1>{{ count }}</h1>

 {{/* BUTTON TO ADD TO THE COUNT */}}
 <button @click="count += 1">Click to Add One</button>
 </div>
</template>
<script>
export default {
 name: "Component",

 data: () => ({ count: 0 }),
};
</script>

Svelte

--to=svelte component.lite.jsx > component.svelte

When we compile our Mitosis component to Svelte, we’ll get the following output:

<script>

 let count= 0

</script>

<div >

 {#if count > 10 } 
 <h1 >You Win!!!</h1>
 {/if}

 <h1 >{count}</h1>

 <button on:click="{event => 
 count += 1;
 }" >Click to Add One</button>

</div>

Angular

--to=angular component.lite.jsx > component.tsx

When we compile our Mitosis component to Angular, it will look like the code below:

import { Component } from "@angular/core";

@Component({
 selector: "component",
 template: 
 <div>
 <ng-container *ngIf="count > 10">
 <h1>You Win!!!</h1>
 </ng-container>

 <h1>{{count}}</h1>

 <button
 (click)="
 count += 1;
 "
 >
 Click to Add One
 </button>
 </div>
 ,
})
export default class Component {
 count = 0;
}

web components

--to=customElement component.lite.jsx > component.js

When compiled to web components, we’ll get the following output:

/**
 * Usage:
 *
 * <component></component>
 *
 */
class Component extends HTMLElement {
 constructor() {
 super();

 const self = this;
 this.state = { count: 0 };

 // Event handler for 'click' event on button-1
 this.onButton1Click = (event) => {
 this.state.count += 1;
 this.update();
 };
 }

 connectedCallback() {
 this.innerHTML = `
 <div>
 <span data-name="show">
 <h1>You Win!!!</h1>
 </span>

 <h1>
 <span data-name="div-1"><!-- state.count --></span>
 </h1>

 <button data-name="button-1">Click to Add One</button>
 </div>
 <style></style>`;
 this.update();
 }

 update() {
 this.querySelectorAll("[data-name='show']").forEach((el) => {
 el.style.display = this.state.count > 10 ? "inline" : "none";
 });

 this.querySelectorAll("[data-name='div-1']").forEach((el) => {
 el.innerText = this.state.count;
 });

 this.querySelectorAll("[data-name='button-1']").forEach((el) => {
 el.removeEventListener("click", this.onButton1Click);
 el.addEventListener("click", this.onButton1Click);
 });
 }
}

customElements.define("component", Component);

As you can see, it is straightforward to install Mitosis, create a component, and then compile it to the language, library, or framework of your choice. We covered several examples in this tutorial, but only scratched the surface; other compilation targets include Swift, Liquid.js, SolidJS, React Native, and more.


Over 200k developers use LogRocket to create better digital experiences

👁 Image
Learn more →

Conclusion

When it is impossible to use the same language as the rest of your team, Mitosis is a helpful tool that saves time by reducing redundant work. 

Mitosis allows you to write one codebase for an individual component then compile it to one of many targets. It facilitates low-code and no-code solutions for creating fast, reactive applications.

We explored the Builder.io plugin, but another popular plugin is the figma-html plugin, which allows you to turn your Figma design into code for any framework.

As you build your own reusable components, you can see the visual results using the JSX-lite fiddle from Builder.io. However, at the time of writing, this feature is still in an early preview stage. I hope you enjoyed this tutorial!

Get set up with LogRocket's modern error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side

    $ npm i --save logrocket 
    
    // Code:
    
    import LogRocket from 'logrocket'; 
    LogRocket.init('app/id');
     
    // Add to your HTML:
    
    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
     
  3. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • NgRx middleware
    • Vuex plugin
Get started now
👁 Image
👁 Image
👁 Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.

👁 Image
Ikeh Akinyemi
Jun 12, 2026 ⋅ 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo — with email/password login, Google OAuth, session persistence, and protected routes.

👁 Image
Chinwike Maduabuchi
Jun 9, 2026 ⋅ 13 min read

AI dev tool power rankings & comparison [June 2026]

Compare the top AI development tools and models of June 2026. View updated rankings, feature breakdowns, and find the best fit for you.

👁 Image
Chizaram Ken
Jun 8, 2026 ⋅ 11 min read

How to check username availability at scale with Bloom filters

Learn how Bloom filters reduce database lookups for username availability checks while preserving correctness at scale.

👁 Image
Rosario De Chiara
Jun 8, 2026 ⋅ 6 min read
View all posts

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now