Socket
Book a DemoInstallSign in
Socket

@qonto/react-migration-toolkit

Package Overview
Dependencies
Maintainers
2
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@qonto/react-migration-toolkit

A toolkit to help migrate Ember components to React

latest
Source
npmnpm
Version
4.0.0
Version published
Maintainers
2
Created
Source

ember-autofocus-modifier-illustration

react-migration-toolkit

A set of tools facilitating the migration of Ember components to React components:

  • Ember to React bridge component
  • React providers
  • React hooks
  • React components

Installation

ember install react-migration-toolkit

Configuration

⚠️ When using Webpack, your Ember apps need to compile jsx:

// webpack.config.js
rules: [
  // ...
  {
    test: /\.jsx/, // replace or add tsx if you use typescript
    use: {
      loader: 'babel-loader',
      options: {
        presets: [
          // Add other presets here if you need Typescript support for example
          ['@babel/preset-react', { runtime: 'automatic' }],
        ],
      },
    },
  },
];

Usage

The main component brought by this addon is the ReactBridge Ember component.

It renders React components within Ember templates, permitting progressive UI migration and preserving existing logics and tests.

The native Bridge can be used as is for simple components. Multiple bridges can be injected within a same template.

Basic Example

To inject a React component in Ember:

// app/react/components/example.tsx

export function Example({ userName }: ExampleProps) {
  return <h1>Hello {userName}!</h1>;
}
// app/components/my-ember-component.js

import Component from '@glimmer/component';
import { Example } from 'app/react/components/example.tsx';

export default class MyComponent extends Component {
  reactExample = Example;
}
{{! app/components/my-ember-component.hbs }}

<ReactBridge
  @reactComponent={{this.reactExample}}
  @props={{hash userName='John'}}
/>

Content projection -

The React Bridge accepts yielded values, which can be accessed via the children prop on the React side.

<ReactBridge
  @reactComponent="{{this.reactExample}}"
  @props={{hash text="this.props.text"}}
>
  <p>Hello World!</p>
</ReactBridge>
function ReactExample({ children, text }: ReactExampleProps) {
  return (
    <div>
      <h1>{text}</h1>
      {children} // <p>Hello World!</p>
    </div>
  );
}

⚠️ Using yielded values does come with some risks. What is supported so far:

✅ Passing Ember helpers works

<ReactBridge
  @reactComponent="{{this.reactExample}}"
  @props={{hash text="this.props.text"}}
>
  {{format/iban @iban}}
</ReactBridge>

❌ Directly nesting conditions cause an error:

Failed to execute 'removeChild' on 'Node'
<ReactBridge
  @reactComponent="{{this.reactExample}}"
  @props={{hash text="this.props.text"}}
>
  {{#if this.someCondition}}
    {{t "some-text"}} 
  {{else}} 
    {{t "some-other-text"}}
  {{/if}}
</ReactBridge>

✅ Wrap conditions in an html element

<ReactBridge
  @reactComponent={{this.reactExample}}
  @props={{hash text="this.props.text"}}
>
  <div>
    {{#if this.someCondition}}
      {{t "some-text"}} 
    {{else}} 
      {{t "some-other-text"}}
    {{/if}}
  </div>
</ReactBridge>

⚠️ Be careful with nesting Ember components in a ReactBridge. It's hard to debug when you have issues.

<ReactBridge
  @reactComponent={{this.reactExample}}
  @props={{hash text="this.props.text"}}
>
  <SomeEmberComponent />
</ReactBridge>

⚠️ Similarly, we recommend not nesting bridges.

<ReactBridge
  @reactComponent={{this.reactExample}}
  @props={{hash text="this.props.text"}}
>
  <ReactBridge
    @reactComponent={{this.someReactComponent}}
  />
</ReactBridge>

✅ Consider migrating both components at the same time, returning just a React component.

<ReactBridge
  @reactComponent={{this.reactExampleWithEmberComponent}}
  @props={{hash text="this.props.text"}}
/>

Sharing context between Ember and React

It is also flexible enough to allow custom providers when shared context is needed between Ember and React. In that situation, creating an adapter around the native Bridge is required.

It is as simple as passing providerOptions as an argument to the ReactBridge

An example is provided in the test app:

💡 In practice, you probably want to create a wrapper that hooks up your most common providers. For example, intl, common services, and routing.

How to test React components in Ember

Like any other Ember component, the ReactBridge can be rendered in QUnit and asserted on. This method is ideal to test React components in isolation.

import { WelcomeMessage } from 'qonto/react/component/welcome-message';

module('my component test', function () {
  test('It renders properly', async function (assert) {
    this.setProperties({ userName: 'Jane Doe' });
    this.reactWelcomeMessage = WelcomeMessage;

    await render(
      hbs`<ReactBridge
        @reactComponent={{this.reactWelcomeMessage}}
        @props={{hash
          cardLevel=this.userName
        }}
      />`,
    );

    assert.dom('h1').hasText('Welcome Jane Doe!');
  });
});

If you're using custom providers, they require the same setup as your Ember components:

import { WelcomeMessage } from 'qonto/react/component/welcome-message';
import { setupIntl } from 'ember-intl';
import { intlProvider } from 'qonto/react/providers/intl';

module('my component test', function (hooks) {
  setupIntl(hooks);
  test('It renders properly', async function (assert) {
    this.setProperties({ userName: 'Jane Doe' });
    this.reactWelcomeMessage = WelcomeMessage;

    await render(
      hbs`<ReactBridge
        @reactComponent={{this.reactWelcomeMessage}}
        @props={{hash
          cardLevel=this.userName
        }}
        customProviders={{this.intlProvider}}
      />`,
    );

    assert.dom('h1').hasText('Welcome Jane Doe!');
  });
});

Typescript Usage

The react-bridge has proper Glint types, which allow you when using TypeScript to get strict type checking in your templates.

Unless you are using strict mode templates (via first class component templates), you need to import the addon's Glint template registry and extend your app's registry declaration as described in the Using Addons documentation:

import '@glint/environment-ember-loose';

import type ReactMigrationToolkitRegistry from '@qonto/react-migration-toolkit/template-registry';

declare module '@glint/environment-ember-loose/registry' {
  export default interface Registry 
    extends ReactMigrationToolkitRegistry {}
}

Compatibility

  • Ember.js v4.12 or above
  • Embroider or ember-auto-import v2

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.

Keywords

ember-addon

FAQs

Package last updated on 31 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.