Mitosis

repository·main·Indexed 11 days ago

https://github.com/builderio/mitosis

A framework for writing components in a single codebase that can be compiled into multiple target frameworks, including React, Vue, Qwik, Angular, Solid, and Svelte. It includes a CLI for transforming source files and an ESLint plugin to maintain code quality and idiomatic patterns for cross-framework compilation.

Tokens
51.9K
Snippets
195
Records
245
Agent score
95%

What's inside Mitosis

  1. What is Mitosis?

    main

    Mitosis is a tool that allows you to write components once in a single codebase and compile them to multiple web frameworks, including React, Vue, Angular, Svelte, Solid, Alpine, and Qwik.

    Key benefits include:

    • Consistent Design Systems: Maintain a single source of truth across different framework ecosystems.
    • Figma Sync: Synchronize design systems from Figma directly to code and publish them to npm for various frameworks.
    • Native Framework Code: Unlike Web Components, Mitosis compiles to native framework code, avoiding common interoperability pitfalls.
  2. Overview of the E2E App and Specification

    main
    The e2e-app package provides a functional Mitosis application and a corresponding set of Playwright specifications. This package is designed to verify that Mitosis components behave consistently across different target frameworks. If Mitosis is functioning correctly, the application should pass the same suite of tests regardless of the framework (e.g., React, Vue, Angular, etc.) used for the build.
  3. Understand the Mitosis Mono-repo structure

    main

    The Mitosis mono-repo is organized into two primary workspaces to facilitate component development and testing:

    • library/: The core workspace for your Mitosis project.
      • library/src/: Contains the Mitosis source code for your components.
      • library/packages/: Contains the individual framework-specific outputs generated by Mitosis (e.g., React, Vue, Qwik).
    • test-apps/: Contains development servers that import your Mitosis components, allowing you to verify your library in real-world scenarios.
  4. View the Mitosis feature support matrix

    main

    The feature matrix indicates the current level of support for various language features (HTML, JSX, CSS, JS, State) across different target frameworks.

    Support levels are denoted by:

    • ✅ implemented
    • 🏗 in-progress/partially implemented
    • ❌ not implemented

    Note: The current matrix draft specifically highlights support for the React scope.

  5. Understand the Mitosis compilation pipeline

    main

    The Mitosis engine follows this workflow:

    1. Input: You write a .lite.jsx or .lite.tsx component.
    2. Parsing: The Mitosis JSX parser converts the component into a MitosisComponent JSON object.
    3. Transformation: The JSON is fed to the chosen generator(s), which pass it through the configured plugins.

    Key data structures:

    • MitosisComponent: The root JSON object representing the component.
    • MitosisNode: Individual nodes found under component.children representing DOM/JSX elements.
  6. Avoid framework-specific libraries in Mitosis

    main

    Because Mitosis components are designed to be cross-framework, you should avoid using libraries that are tied to a specific framework (e.g., a React-only form library). Using framework-specific code directly in your Mitosis source will prevent the component from being successfully compiled for other targets like Vue or Svelte.

    Instead, focus on using web fundamentals and native browser APIs (like FormData, HTMLFormElement, or SubmitEvent) to ensure compatibility across all output targets.

    export default function MyComponent() {
      function handleSubmit(event: SubmitEvent) {
        event.preventDefault();
    
        const form = event.target as HTMLFormElement;
        if (!form.checkValidity()) {
          alert('Form is invalid');
          return;
        }
        const data = new FormData(form);
        const email = data.get('email');
        console.log(email);
      }
    
      return (
        <form onSubmit={(event) => handleSubmit(event)}>
          <input type="email" name="email" required />
          <button type="submit">Submit</button>
        </form>
      );
    }
  7. Handle children and slots

    main

    Mitosis uses props.children for standard child passing.

    Warning: You cannot directly iterate over or manipulate props.children because many target frameworks do not support it. Treat it as a special property intended only for rendering.

    To implement named slots, use the <Slot /> component. This allows you to register specific content areas (e.g., top, left, center) that can be projected into a layout component.

    import { Slot } from '@builder.io/mitosis';
    
    export default function Layout(props) {
      return (
        <div className="layout">
          <div className="top"><Slot name="top" /></div>
          <div className="left"><Slot name="left" /></div>
          <div className="center"><Slot name="center" /></div>
          <Slot />
        </div>
      );
    }
  8. The lifecycle of `componentTo<framework>`

    main

    The componentTo<framework> function follows a strict execution order. Because functions that access json or component data often mutate it, the order of operations is critical to avoid side effects.

    The execution pipeline is:

    1. preJsonPlugins: Initial processing before any manipulations.
    2. Data Extraction: Core operations like getProps to retrieve component data.
    3. postJsonPlugins: Processing after data manipulation or extraction.
    4. Initial String Creation: Generating the base component structure.
    5. PreCodePlugins: Processing via options.plugins before code generation.
    6. Formatting: Applying Prettier to the generated code.
    7. PostCodePlugins: Final processing via options.plugins after code generation.
  9. How Mitosis generators are structured

    main

    Mitosis generators are responsible for converting Mitosis JSON components into target framework code. A generator is composed of two primary functions:

    1. componentTo<framework>: Handles the conversion of an entire JSON mitosis component into a complete component string for the target framework.
    2. blockTo<framework>: Handles the conversion of individual DOM nodes within the component.

    Generators are designed to mimic the structure of the target framework, injecting imports, component names, styles, render bodies, and lifecycle methods using Mitosis JSON data to produce valid code.