Standardized Module Federation configuration for remote microfrontend applications. This library provides opinionated defaults and type-safe utilities for building microfrontends with Vite and React.
npm install @grasp-labs/ds-web-microfrontends-common-libStandardized Module Federation configuration for remote microfrontend applications. This library provides opinionated defaults and type-safe utilities for building microfrontends with Vite and React.
``bash`
npm install @grasp-labs/ds-web-microfrontends-common-lib
Node.js: >= 22
This library requires compatible peer dependencies. Install them in your microfrontend project, for example:
`bash`
npm install -D react@19.2.3
Optionally, for Data Platform integration:
`bash`
npm install -D @grasp-labs/ds-microfrontends-integration
Version requirements are defined in this package's peerDependencies - check package.json for current version ranges.
Create or update your vite.config.ts:
`typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import {
createMicrofrontendsBase,
dsFederation,
} from "@grasp-labs/ds-web-microfrontends-common-lib";
import { name } from "./package.json";
const MICROFRONTENDS_BASE = createMicrofrontendsBase(name);
export default defineConfig(({ mode }) => ({
base: mode === "production" ? MICROFRONTENDS_BASE : "/",
plugins: [react(), dsFederation(name)],
}));
`
Your src/App.tsx should export a React component with Routes (not render it):
`tsx
// src/App.tsx
import { Routes, Route } from "react-router";
import { HomePage } from "./layouts/HomePage";
import { SettingsPage } from "./layouts/SettingsPage";
import { InternalPage } from "./layouts/InternalPage";
function App() {
return (
);
}
export default App;
`
Create src/navigationConfig.ts:
`typescript
import type { NavigationConfig } from "@grasp-labs/ds-web-microfrontends-common-lib";
export const navigationConfig = {
INDEX: {
label: "Home",
path: "/",
icon: "database",
type: "visible",
},
SETTINGS: {
label: "Settings",
path: "/settings",
icon: "cogWheel",
type: "visible",
},
INTERNAL: {
label: "Internal Page",
path: "/internal",
type: "hidden",
},
} satisfies NavigationConfig;
`
Important: The navigationConfig.ts file must remain a bare TypeScript file with no React imports or dependencies. This is critical because:
- The microfrontend app (src/App.tsx) is lazily loaded by the host application
- The host app needs immediate access to the routing configuration to build the navigation structure before any remote apps are loaded
- If navigationConfig imports React or other heavy dependencies, it would force those dependencies to load before navigation can be rendered, defeating the purpose of lazy loading
Keep this file lightweight - only export the configuration object with no side effects or dependencies.
The dsFederation plugin automatically configures:
Exposes:
- "." → "./src/App" - Your main React component"./navigationConfig"
- → "./src/navigationConfig" - Navigation configuration
Shared Dependencies:
- react (singleton)react-dom
- (singleton)react-router
- (singleton)
Public Path: microfrontends/${name}/
Override defaults by passing configuration to dsFederation:
`typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { dsFederation } from "@grasp-labs/ds-web-microfrontends-common-lib";
export default defineConfig({
plugins: [
react(),
dsFederation("your-microfrontend-name", {
exposes: {
".": "./src/App",
"./navigationConfig": "./src/navigationConfig",
"./CustomComponent": "./src/components/CustomComponent",
},
shared: {
lodash: {
singleton: true,
requiredVersion: "^4.17.21",
},
},
}),
],
});
`
For microfrontends that integrate with @grasp-labs/ds-microfrontends-integration:
`typescript
import {
createModuleFederationConfig,
DATA_PLATFORM_SHARED_DEPS,
} from "@grasp-labs/ds-web-microfrontends-common-lib";
import { federation } from "@module-federation/vite";
export default defineConfig({
plugins: [
react(),
federation({
...createModuleFederationConfig("your-microfrontend-name", {
shared: DATA_PLATFORM_SHARED_DEPS,
}),
}),
],
});
`
#### dsFederation(name, overrides?)
Creates a configured Vite Module Federation plugin.
Parameters:
- name (string): The name of the microfrontend (typically from package.json)overrides
- (Partial
Returns: Configured Vite plugin
Example:
`typescript`
dsFederation("my-app", {
exposes: {
".": "./src/App",
"./utils": "./src/utils",
},
});
#### createModuleFederationConfig(name, overrides?)
Generates the Module Federation configuration object without wrapping it in a Vite plugin.
Parameters:
- name (string): The name of the microfrontendoverrides
- (Partial
Returns: ModuleFederationOptions object
Example:
`typescript`
const config = createModuleFederationConfig("my-app");
#### createMicrofrontendsBase(name)
Generates the standardized public path for a microfrontend.
Parameters:
- name (string): The name of the microfrontend
Returns: string - Path in format microfrontends/${name}/
Example:
`typescript`
createMicrofrontendsBase("data-sources"); // "microfrontends/data-sources/"
#### COMMON_SHARED_DEPS
Standard shared dependencies for Module Federation. Versions are sourced from this package's peerDependencies.
`typescript`
{
react: { singleton: true, requiredVersion: "
"react-dom": { singleton: true, requiredVersion: "
"react-router": { singleton: true, requiredVersion: "
}
#### DATA_PLATFORM_SHARED_DEPS
Extended shared dependencies including Data Platform integration library.
`typescript`
{
...COMMON_SHARED_DEPS,
"@grasp-labs/ds-microfrontends-integration": {
singleton: true,
requiredVersion: "
},
}
#### RouteConfig
Defines a single route in the navigation system.
`typescript`
type RouteConfig = {
label: string; // Display name
path: string; // Route path
icon?: IconName; // Optional icon from @grasp-labs/ds-react-components
type?: "hidden" | "visible"; // Visibility in navigation
};
#### CategoryConfig
Defines a navigation category with nested routes.
`typescript`
type CategoryConfig = {
label: string;
icon?: IconName;
type: "category";
children: Record
};
#### NavigationItem
Union type for navigation items.
`typescript`
type NavigationItem = RouteConfig | CategoryConfig;
#### NavigationConfig
Type-safe navigation configuration. Requires an INDEX route.
`typescript`
type NavigationConfig
INDEX: RouteConfig;
} & Record
Example:
`typescript`
const navigationConfig = {
INDEX: {
label: "Data Sources",
path: "/",
icon: "database",
type: "visible",
},
CATALOG: {
label: "Catalog",
icon: "folder",
type: "category",
children: {
LIST: {
label: "All Sources",
path: "/catalog",
icon: "list",
},
CREATE: {
label: "Create",
path: "/catalog/create",
icon: "plus",
},
},
},
} satisfies NavigationConfig;
#### MicrofrontendExposes
Type for Module Federation exposes configuration.
`typescript`
type MicrofrontendExposes = {
".": string;
"./navigationConfig": string;
} & Record
These dependencies are configured as Module Federation singletons, ensuring one instance across all microfrontends:
| Dependency | Purpose |
| ------------------------------------------- | ----------------------------------------------- |
| react | UI library (singleton) |react-dom
| | React DOM renderer (singleton) |react-router
| | Routing library (singleton) |@grasp-labs/ds-microfrontends-integration
| | Data Platform integration (singleton, optional) |
Singleton configuration prevents version conflicts across microfrontends. Version requirements are defined in this package's peerDependencies - check package.json for current requirements.
`bashInstall dependencies
npm install
Project Structure
`
src/
└── index.ts # Module Federation configuration and type definitions
`Publishing
This package is published to npm as
@grasp-labs/ds-web-microfrontends-common-lib.Publishing is done via GitHub Actions workflow (
publish.yml):1. Go to Actions → "Version and Publish Package"
2. Click "Run workflow"
3. Select version type:
-
patch - Bug fixes (0.1.0 → 0.1.1)
- minor - New features (0.1.0 → 0.2.0)
- major - Breaking changes (0.1.0 → 1.0.0)
- beta - Beta release with timestampThe workflow automatically:
- Builds the package
- Bumps version and creates git tag (for release versions)
- Publishes to npm registry
Contributing
1. Create a feature branch
2. Ensure
npm run check passes (format, lint, typecheck)
3. Build successfully with npm run build
4. Create a pull request with semantic title (e.g., feat:, fix:, chore:`)Apache-2.0