This content originally appeared on Bits and Pieces - Medium and was authored by Mike Chen
Using composable software framework to build composable frontends and backends

What is Bit Harmony?
Bit Harmony is a lightweight NodeJS framework that streamlines full-stack development using a dependency-injection model natively supporting components. It allows developers to build modular Aspects, which are self-contained, pluggable business features that can be reused across different applications.
Key Benefits of Bit Harmony
- Unified Development — Develop frontend and backend components in a single, composable environment supporting different runtimes (browser, node.js etc.)
- Maximum Code Reuse — Aspects can be shared, versioned, and repurposed across multiple applications.
- Standardized API Integration — Ensures all components follow a consistent API structure.
- Seamless Deployment — Works with Kubernetes and cloud-native environments for scalable app deployment.
Bit Harmony enables developers to build full-stack business capabilities that can be plugged into any application effortlessly.
At the heart of Bit Harmony is the Aspect model, which provides a structured way to create reusable frontend and backend components. Since Harmony is built also using aspects, you may find these constructs at its core.
Packaging Business Capabilities Using Aspects
An Aspect in Harmony is a self-contained unit of functionality that provides both frontend and backend services. Think of it as a modular building block that can be independently maintained, tested, and deployed.

We can start by creating a Harmony platform for the application. Then we can register the required runtimes (e.g BrowserRuntime , NodeJSRuntime ) which are directly supported by the platform.
export const MyApp = HarmonyPlatform.from({
name: 'my-app',
platform: [
SymphonyPlatformAspect,
{
name: 'MyApp',
slogan: 'Platform',
logo: 'https://static.bit.dev/extensions-icons/wayne.svg',
},
],
runtimes: [new BrowserRuntime(), new NodeJSRuntime()],
aspects: [MyAppAspect, KubernetesAspect],
});
Choosing runtimes is optional. For example, if you are building purely an API or a CLI application, you can opt-out the BrowserRuntime.
Symphony Platform Aspect: A ready-made aspect built by the Bit team. It acts as the platform’s foundation and gateway.
Then we can start building functional aspects and register them into the Harmony Platform.
Example: The “People” Aspect for Authentication
Let’s consider an authentication service built as a Harmony Aspect. Instead of having separate frontend and backend services, the People Aspect provides both:
- Frontend UI for login and user management
export class PeopleBrowser {
// ...
// Declare this aspect's dependencies (Harmony uses this to initialize the aspects at the right order)
static dependencies = [MyPlatformAspect];
// List the aspects to be injected into this aspect
static async provider([myPlatform]: [MyPlatformBrowser]) {
const people = new PeopleBrowser(config, menuItemSlot);
myPlatform.registerRoute([
{
path: 'people',
component: () => {
return <PeopleLobby />;
},
},
]);
// Registration via other aspects can be optional (depending on whether the aspect is part of the platform or not)
// Add a widget to the platform's homepage
myPlatform?.registerPanel([
{
category: 'People',
component: () => {
return <NewPeople />;
},
},
]);
// Register a top-level component to wrap the platform with the authentication context
myPlatform?.registerTopLevelComponents({
component: ({ children }) => {
return <AuthProvider>{children}</AuthProvider>;
},
});
// ...
return people;
}
}
- Backend API for authentication and user data storage
// ...
export class PeopleNode {
constructor(
private myPlatform: MyPlatformNode,
private userRepo: UserRepository
) {}
// ...
async getCurrentUser(req: any): Promise<User | null> {
// ...
return User.from(user);
}
static dependencies = [SymphonyPlatformAspect, MyPlatformAspect];
static async provider([symphonyPlatform, myPlatform]: [
SymphonyPlatformNode,
MyPlatformNode
]) {
const userRepo = new UserRepository();
const people = new PeopleNode(myPlatform, userRepo);
const gqlSchema = createPeopleGqlSchema(people);
/**
* Register a GraphQL schema to the platform's backend server.
*/
myPlatform.registerBackendServer([
{
routes: [],
gql: gqlSchema,
},
]);
/**
* Register to the platform's middleware to intercept requests to the backend
* and attach the user to the request.
*/
symphonyPlatform.registerMiddlewares([
(req, _, next) => {
const user = people.getCurrentUser(req);
req.user = user;
next();
},
]);
return people;
}
}
export default PeopleNode;
You can see how we can create the Browser-related functionality of the People aspects and Node-related functionality of the people aspects in unification and inject them into the Harmony platform using dependency injection.
Extending Aspects with “Slots”
If you look at the constructs of the harmony platform so far, you have seen how it helps to build unified modules (aspects) to abstract business capabilities that can be plugged into the platform.
And sometimes it's not viable to implement dependency injection all the way into a tiny bit of components. For example, if we are building a composable frontend using React.js, we are limited by the capabilities provided by React.js. The ability to use inversion of control is limited based on React.js constructs. This is where “Slots” comes in. Harmony provides a concept called “Slots” to further extend its aspects.
The best example of understanding slots is to look into the Symphony Platform aspect built by the Bit team.
The symphony platform provides the most fundamental APIs and slots for other aspects to register into the system. These include things like registering routes, services, middleware, graphql schemas, and more. Symphony leverages React, GraphQL, and Express.

Let’s use an example from the browser runtime to see how we can build aspects for further extension. Suppose we want “people” aspect to provide an API for other aspects to extend it.
In the ‘Step 2: Create the Aspect’ section, we created the ‘menu-list-items’ slot. This slot is used to register menu items in the user menu. The boilerplate code for the slot was already created, so we only need to add the missing details.
/**
* @filename menu-list-items.ts
*/
import { SlotRegistry } from '@bitdev/harmony.harmony';
export type MenuListItem = {
/**
* name of the list item.
*/
name: string;
/**
* link of the item.
*/
href: string;
};
export type MenuListItemSlot = SlotRegistry<MenuListItem[]>;
In the browser runtime we need to provide the API to register the menu items. We also need to pass the same instance of the slot to the aspect’s provider.
/**
* @filename people.browser.runtime.ts
*/
import { MenuListItem, MenuListItemSlot } from './menu-list-item.js';
// ...
export class PeopleBrowser {
constructor(
private config: PeopleConfig,
private menuItemSlot: MenuListItemSlot
) {}
/**
* Register a new menu item to the user bar.
* (the API for other aspects to register to the 'menu-item' slot)
*/
registerMenuItem(menuItems: MenuListItem[]) {
this.menuItemSlot.register(menuItems);
return this;
}
// Optional: Provide a default configuration for the aspect
static defaultConfig: PeopleConfig = {};
static async provider(
[symphonyPlatform, myPlatform]: [
SymphonyPlatformBrowser,
MyPlatformBrowser
],
config: PeopleConfig,
// Declare the slot to be injected into this aspect
[menuItemSlot]: [MenuListItemSlot]
) {
// ...
}
}
export default PeopleBrowser;
Built with Components

With Bit Harmony, every feature is an independently versioned, reusable component — no more fragmented frontend and backend teams.

This also applies to aspects, slots and anything that you see as a meaningful unit that has a unique functionality.
Therefore, the composability of the application is becoming more granular, uniform and automatically becomes reusable across teams, projects etc.
Conclusion
Bit Harmony provides a unified, composable architecture that simplifies full-stack development. By leveraging Aspects, developers can build modular business features that are reusable, scalable, and easy to integrate.
With Harmony, teams no longer have to juggle disconnected frontend and backend systems — they can focus on building applications faster, with more consistency, and reduce technical debt.
Next Steps
✅ Start building with Bit Harmony today!
✅ Explore the Harmony documentation for deeper insights.
✅ Try forking the Pied Piper platform and create your own Aspects.
With Bit Harmony, software is no longer just built — it’s composed.
Learn More
- Why You Should Build Your Platform with Harmony
- Pluggable PBCs with Bit Harmony
- Deployment Strategies for Composable Microfrontends
Introducing Harmony: Unified NodeJS Frameworks for Building Composable Frontends and Backends was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Mike Chen

Mike Chen | Sciencx (2025-02-27T09:53:24+00:00) Introducing Harmony: Unified NodeJS Frameworks for Building Composable Frontends and Backends. Retrieved from https://www.scien.cx/2025/02/27/introducing-harmony-unified-nodejs-frameworks-for-building-composable-frontends-and-backends/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.