The best approach for adopting composability is starting to create new features in Bit while leveraging 100% of your existing codebase. You can either leverage your existing code using existing packages, backend APIs or by packaging your existing app codebase for reuse in Bit components.
The recommended steps for accessing and leveraging existing code while building new composable features:
- Create the application shell.
- Create new features.
- Compose existing micro services, micro frontends and apps into aspects.
- As needed, reuse new UI components, entities and hooks directly in existing projects, modernizing your existing tech stack.
This approach lets you gradually introduce composability into your tech stack without a disruptive rewrite or breaking changes. Below are specific techniques and references for using app code, micro services and micro frontends in composable features.
To leverage a monolithic codebase in a composable features, follow the next steps:
- Publish your app as package
- Create the application shell
- Create new features as needed
- Create a dev environment, set your app as a peer dependency in env.jsonc and adjust dev tools configuration files as needed.
- Reuse specific app files as building new components.
Once publishing your package, use the internal files directly from new features and components:
import Homepage from 'my-app-package/components/Homepage.js';
This will allow to start building new features in Bit while reusing your existing app code in Bit components.
To leverage micro services or frontends, simply consume them in runtime, or gradually move them to build time as needed to optimize for end-user experience.
Here's an example method using an existing micro service from a new aspect:
// people.node.runtime.ts import { SymphonyPlatformAspect type SymphonyPlatformNode } from '@bitdev/symphony.symphony-platform'; import { User, createUserMock } from '@pied/people.entities.user'; import { peopleGqlSchema } from './people.graphql.js'; export class PeopleNode { constructor( readonly config: PeopleConfig ) {} /** * Define the API to list users and use throughout new features. **/ async listUsers(): Promise<User[]> { const objects = await fetch(`${this.config.legacyUserService}/users/list'`); return objects.map((plainUser) => { return User.from(plainUser); }); } static defaultConfig = { legacyUserService: 'https://api.user-service.com' }; static async provider(_, config) { return new PeopleNode(config); } }
Of course, the frontend can also directly use the existing server if permitted by the cors and security policies.
Use the index.html file or the webpack app configuration to load existing micro frontends and stitch them into the platform. Find more information about using Microfrontends in Bit apps in the Microfrontends docs section.
For a multi app architecture, sitting behind a proxy server, we recommend following the next steps:
- Create the application shell
- Create new features in Harmony aspects
- Deploy the Harmony platform
- Gradually transition the proxy to point new routes to new Harmony routes
Optionally, publish your existing apps as packages to reuse in new routes.
Use standard package managers to install components in your existing project:
npm install @pied/people.ui.user-profile
Learn about reusing Bit components in existing projects.