# Bridge Overview

## Introduction

`Bridge` is a utility function provided by `Module Federation` for loading application-level modules.
"Application-level modules" are modules that can run like applications, with framework rendering capabilities and routing abilities.
With `Bridge`, you can render your application in different frameworks and ensure that routing between applications works collaboratively. This is particularly useful for micro-frontend applications.

:::tip
Before reading this chapter, it's assumed you're familiar with:

- [How to consume and export modules](../../guide/start/quick-start.mdx)
- [Module Federation Builder plugin](../../guide/basic/rspack.mdx)
- [Characteristics and capabilities of Module Federation Runtime](../../guide/basic/runtime.mdx)

:::

## Toolkits

### @module-federation/bridge-react

`@module-federation/bridge-react` is suitable for React framework types, currently supporting React v16, v17, and v18 versions.

This toolkit provides two APIs:

- createBridgeComponent

> Used to create React application-type module exports. If your application is React-based and you want it to be loaded as an application-type module by another MF application, you should use this to create standard-compliant exports for your application.

- createRemoteComponent

> Used to load application-type modules in a React application. The loaded module must be wrapped by `createBridgeComponent`. `createRemoteComponent` will automatically create a rendering context in your application to ensure the module works properly.

For usage of `@module-federation/bridge-react`, see [Host demo](https://github.com/module-federation/core/tree/main/apps/router-demo/router-host-2000) and [Remote demo](https://github.com/module-federation/core/tree/main/apps/router-demo/router-remote2-2002).

### @module-federation/bridge-vue3

`@module-federation/bridge-vue3` is suitable for Vue framework types, currently supporting Vue v3 version.

This toolkit provides two APIs:

- createBridgeComponent

> Used to create Vue application-type module exports. If your application is Vue v3-based and you want it to be loaded as an application-type module by another MF application, you should use this to create standard-compliant exports for your application.

- createRemoteComponent

> Used to load application-type modules in a Vue application. The loaded module must be wrapped by `createBridgeComponent`. `createRemoteComponent` will automatically create a rendering context in your application to ensure the module works properly.

## FAQ

### Why Bridge?

Bridge is mainly used to solve two problems:

* Cross-application framework (React, Vue) loading and rendering
* Support for loading modules with routing (routes can work well together)

These two issues are important features in "micro-frontend frameworks"

### How to solve if there's no bridge provided for a specific framework?

Currently, `Module Federation` provides official bridge toolkits. If you need bridge toolkits for other frameworks, you can provide feedback through [issues](https://github.com/module-federation/core/issues), or refer to the existing [`Bridge`](https://github.com/module-federation/core/blob/34ba220bcee3d032e4083aae37f802d1ed20d61b/packages/bridge/bridge-react) implementation.

The implementation of `Bridge` is very simple, with the core based on `DOM` rendering. Here's some pseudocode:

> Exporting module

```tsx
export default function () {
  const rootMap = new Map<any, ReactDOM.Root>();
  return {
    render(info: { dom: HTMLElement; basename?: string; memoryRoute?: { entryPath: string; } }) {
      const root = ReactDOM.createRoot(info.dom);
      rootMap.set(info.dom, root);
      root.render(
        <App />,
      );
    },
    destroy(info: { dom: HTMLElement }) {
      const root = rootMap.get(info.dom);
      root?.unmount();
    },
  }
}
```

> Loading module

```tsx
const LazyComponent =  React.lazy(async () => {
  const m = await loadRemote('remote1/export-app');
  const providerInfo = m.default;
  return {
    default: () => {
      const rootRef = useRef(null);
      const providerInfoRef = useRef<any>(null);

      useEffect(() => {
        const providerReturn = providerInfo();
        providerInfoRef.current = providerReturn;
        providerReturn.render(renderProps);

        return () => {
          providerInfoRef.current?.destroy({
            dom: renderDom.current,
          });
        };
      }, []);
      return <div ref={rootRef}></div>;
    }
  };
});

function Component () {
  return (<React.Suspense fallback={<div>loading</div>}>
  <LazyComponent />
</React.Suspense>)
}
```

