{"id":24755174,"url":"https://github.com/gravity-ui/app-builder","last_synced_at":"2026-04-06T17:03:13.785Z","repository":{"id":166976947,"uuid":"534535579","full_name":"gravity-ui/app-builder","owner":"gravity-ui","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-03T09:45:22.000Z","size":2968,"stargazers_count":29,"open_issues_count":13,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-04-03T15:23:32.892Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gravity-ui.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-09-09T07:03:04.000Z","updated_at":"2026-04-03T09:43:33.000Z","dependencies_parsed_at":"2023-09-23T07:49:51.913Z","dependency_job_id":"3bca6331-d97b-4325-8a4d-ffb5ea2060d9","html_url":"https://github.com/gravity-ui/app-builder","commit_stats":null,"previous_names":["gravity-ui/app-builder"],"tags_count":110,"template":false,"template_full_name":"gravity-ui/package-example","purl":"pkg:github/gravity-ui/app-builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity-ui%2Fapp-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity-ui%2Fapp-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity-ui%2Fapp-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity-ui%2Fapp-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gravity-ui","download_url":"https://codeload.github.com/gravity-ui/app-builder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gravity-ui%2Fapp-builder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31481238,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T14:34:32.243Z","status":"ssl_error","status_checked_at":"2026-04-06T14:34:31.723Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-28T12:36:49.220Z","updated_at":"2026-04-06T17:03:13.778Z","avatar_url":"https://github.com/gravity-ui.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @gravity-ui/app-builder \u0026middot; [![npm package](https://img.shields.io/npm/v/@gravity-ui/app-builder)](https://www.npmjs.com/package/@gravity-ui/app-builder) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/app-builder/.github/workflows/ci.yml?branch=main)](https://github.com/gravity-ui/app-builder/actions/workflows/ci.yml?query=branch:main)\n\nDevelop and build your client-server projects, powered by typescript and webpack.\n\n## Install\n\n```shell\nnpm install --save-dev @gravity-ui/app-builder\n```\n\n## Usage\n\n`@gravity-ui/app-builder` provides CLI (`npx app-builder`). You can view available commands with the `--help` flag.\n\n### Develop your project\n\n```sh\nnpx app-builder dev # to view supported options add the --help flag.\n```\n\n### Build your project\n\n```sh\nnpx app-builder build # to view supported options add the --help flag.\n```\n\n### Configuration\n\nYou can use any of these files:\n\n- app-builder.config.ts\n- app-builder.config.js\n- app-builder.config.json\n- app-builder property in your package.json\n\nYou can also specify a custom filename using the `--config` flag\n\n#### TypeScript/JavaScript\n\n```ts\nimport {defineConfig} from '@gravity-ui/app-builder';\n\nexport default defineConfig({\n  client: {\n    // client settings\n  },\n  server: {\n    // server settings\n  },\n});\n```\n\n#### Conditional config\n\nIf the config needs to be conditionally determined, it can export a function instead:\n\n```ts\nimport {defineConfig} from '@gravity-ui/app-builder';\n\nexport default defineConfig(\n  async function (\n    /** @type dev | build */\n    command,\n    /**\n     * values specified with --env flag\n     *\n     * @type {[k in string]: string}\n     *\n     * @example\n     *   With follow command:\n     *       app-build dev --env=path.to.member1=value1 --env=path.to.member2=value2\n     *   you get:\n     *       env = {path: {to: {member1: 'value1', member2: 'value2'}}}\n     */\n    env,\n  ) {\n    return {\n      verbose: command === 'dev',\n      client: {\n        // client settings\n      },\n      server: {\n        // server settings\n      },\n    };\n  },\n);\n\nexport default config;\n```\n\n#### package.json\n\n```json\n{\n  \"app-builder\": {\n    \"client\": {\n      // client settings\n    },\n    \"server\": {\n      // server settings\n    }\n  },\n  \"scripts\": {\n    \"dev\": \"app-builder dev\",\n    \"build\": \"app-builder build\"\n  }\n}\n```\n\n### Common\n\n- `target` (`client | server`) — select compilation unit.\n- `verbose` (`boolean`) - turn on verbose output.\n\n#### Environment Variables\n\n`app-builder` automatically injects environment variables during the build process that are available in your application code:\n\n- `process.env.PUBLIC_PATH` — automatically set to the resolved public path value (including CDN URLs if configured). This allows your application code to dynamically access the correct resource URLs at runtime.\n\n  ```ts\n  // In your application code, you can access:\n  const publicPath = process.env.PUBLIC_PATH; // e.g., \"https://cdn.example.com/build/\" or \"/build/\"\n\n  // Useful for dynamically loading assets or configuring Module Federation\n  const assetUrl = `${process.env.PUBLIC_PATH}images/logo.png`;\n  ```\n\n  **Note**: On the server side, `process.env.PUBLIC_PATH` is only available when using SWC compiler (`compiler: 'swc'`). With TypeScript compiler, this variable is not injected.\n\n- `process.env.NODE_ENV` — current environment (`'development'` | `'production'`)\n- `process.env.IS_SSR` — boolean flag indicating if code is running in SSR context\n\n### Server\n\n`app-builder` compiles server with typescript.\nDefault folder for server code is `src/server`. There is must be file `tsconfig.json`\n\n```json\n{\n  \"compilerOptions\": {\n    \"outDir\": \"../../dist/server\"\n  }\n}\n```\n\nand `index.ts` - server entrypoint.\n\n`outDir` - must be configured to place compiled files to `{rootDir}/dist/server`.\nThe server is started with the command `node {rootDir}/dist/server/index.js`.\n\n#### Options\n\nAll server settings are used only in dev mode:\n\n- `port` (`number | true`) — specify port that server listens. The port will be used to\n  pass through requests from the client to the server. If set to `true`, the port will be selected automatically.\n  The server is started with the command `APP_PORT=${port} node dist/${outputPath}/index.js --port ${port}`.\n- `watch` (`string[]`) — by default `app-builder` monitors only `src/server` directory.\n  If you need to watch other directories, specify them here.\n- `watchThrottle` (`number`) — use to add an extra throttle, or delay restarting.\n- `inspect/inspectBrk` (`number | true`) — listen for a debugging client on specified port.\n  If specified `true`, try to listen on `9229`.\n- `compiler` (`'typescript' | 'swc'`) — choose TypeScript compiler for server code compilation.\n  Default is `'typescript'`. Set to `'swc'` for faster compilation with SWC.\n- `outputPath` (`string`) — custom output path for compiled server code relative to `dist` directory.\n  Default: `server`. Use this when your `server` entrypoint changed from `dist/server` to a different location (e.g., `package/src/server` for path `dist/package/src/server` in monorepo setups).\n\n### Client\n\n`app-builder` bundles client with [webpack](https://webpack.js.org). Client code must be in `src/ui` folder.\n`src/ui/entries` - each file in this folder is used as entrypoint. `dist/public/build` is output directory for bundles.\n\n#### Options\n\nAll paths must be specified relative `rootDir` of the project.\n\n- `modules` (`string[]`) — Tell webpack what directories should be searched when resolving modules. `modules` automatically\n  populates with `baseUrl` from `src/ui/tsconfig.json`.\n- `alias` (`Record\u003cstring, string\u003e`) — Create aliases to import or require certain modules more easily, [more](https://webpack.js.org/configuration/resolve/#resolvealias)\n\nWith this `{rootDir}/src/ui/tsconfig.json`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"baseDir\": \".\",\n    \"paths\": {\n      \"~units\": [\"units/*\"]\n    }\n  }\n}\n```\n\n`modules` will contain `[\"{rootDir}/src\"]` and aliases - `{\"~units\": [\"{rootDir}/src/units\"]}`;\n\n- `includes` (`string[]`) — additional compilation paths. Example: `includes: ['node_modules/my-lib', 'src/shared']`\n- `images` (`string[]`) — Additional paths for images. Example: `images: ['node_modules/my-lib/img']`\n- `icons` (`string[]`) — Additional paths for svg icons. By default, all svgs with paths including `icons/` will be processed.\n  Example: `icons: [node_modules/@fortawesome/fontawesome-pro/svgs]`\n- `publicPathPrefix` (`string`) — publicPath prefix, will be added to `/build/`\n- `publicPath` (`string`) — publicPath for bundler, this option has higher priority than publicPathPrefix\n- `outputPath` (`string`) — Build directory for output, default: `dist/public/build` and `dist/ssr` - for SSR\n- `assetsManifestFile` (`string`) — File name for assets manifest, default: `assets-manifest.json`\n- `symlinks` (`boolean`) — Follow symbolic links while looking for a file. [more](https://webpack.js.org/configuration/resolve/#resolvesymlinks)\n- `externals` — specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. [more](https://webpack.js.org/configuration/externals/)\n- `node` — include polyfills or mocks for various node stuff. [more](https://webpack.js.org/configuration/node/)\n- `fallback` — Redirect module requests when normal resolving fails. [more](https://webpack.js.org/configuration/resolve/#resolvefallback)\n- `polyfill` — allow enable Node.js `process` object polyfill.\n- `hiddenSourceMap` (`boolean=true`) - if `false` - source maps will be generated for prod builds\n- `disableSourceMapGeneration` (`boolean`) — disable sourcemap generation;\n- `definitions` — add additional options to DefinePlugin. [more](https://webpack.js.org/plugins/define-plugin/#usage)\n- `newJsxTransform` (`boolean=true`) — use new JSX Transform.\n- `svgr` (`SvgrConfig`) — svgr plugin options. [more](https://react-svgr.com/docs/options/)\n- `entry` (`string | string[] | Record\u003cstring, string | string[]\u003e`) — entry for bundler, overrides entry which is generated from entries directory\n- `entryFilter` (`string[]`) — filter used entrypoints.\n- `excludeFromClean` (`string[]`) — do not clean provided paths before build.\n- `forkTsCheker` (`false | ForkTsCheckerWebpackPluginOptions`) - config for ForkTsCheckerWebpackPlugin [more](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#options). If `false`, ForkTsCheckerWebpackPlugin will be disabled.\n- `cache` (`boolean | FileCacheOptions | MemoryCacheOptions`) — Cache the generated webpack modules and chunks to improve build speed. [more](https://webpack.js.org/configuration/cache/)\n- `bundler` (`'webpack' | 'rspack'`) - Option to choose a bundler.\n- `javaScriptLoader` (`'babel' | 'swc'`) - Option to choose a JavaScript loader.\n- `babel` (`(config: babel.TransformOptions, options: {configType: 'development' | 'production'; isSsr: boolean}) =\u003e babel.TransformOptions | Promise\u003cbabel.TransformOptions\u003e`) - Allow override the default babel transform options.\n- `babelCacheDirectory` (`boolean | string`) — Set directory for babel-loader cache (`default: node_modules/.cache/babel-loader``)\n- `swc` (`(config: SwcConfig, options: {configType: 'development' | 'production'; isSsr: boolean}) =\u003e SwcConfig | Promise\u003cSwcConfig\u003e`) - Allow override the default swc configuration.\n- `webpack` (`(config: webpack.Configuration, options: {configType: 'development' | 'production'; isSsr: boolean}) =\u003e webpack.Configuration | Promise\u003cwebpack.Configuration\u003e`) - Allow override the default webpack configuration.\n- `rspack` (`(config: rspack.Configuration, options: {configType: 'development' | 'production'; isSsr: boolean}) =\u003e rspack.Configuration | Promise\u003crspack.Configuration\u003e`) - Allow override the default rspack configuration.\n- `ssr` - build SSR bundle. The SSR entries should be inside `src/ui/ssr` directory and match the client entries.\n  - `noExternal` (`string | RegExp | (string | RegExp)[] | true`) - prevent listed dependencies from being externalized for SSR. By default, all dependencies are externalized.\n  - `moduleType`: (`'commonjs' | 'esm'`) - library type for the SSR bundle, by default `commonjs`.\n\n##### Dev build\n\n- `devServer` (`Object`) — webpack dev server options.\n  - `ipc` (`string`) — the Unix socket to listen to. If `ipc` and `port` are not defined, then the socket `{rootDir}/dist/run/client.sock` is used.\n  - `port` (`number | true`) — specify a port number to listen for requests on. If `true`, the free port will be selected automatically.\n  - `webSocketPath` (`string`) — tells clients connected to devServer to use the provided path to connect. Default is `${publicPathPrefix}/build/sockjs-node`.\n  - `webSocketClientPort` (`number`) - tells clients to connect to devServer using this port from a browser. Default is `${devServer.port}`\n  - `type` (`'https'`) — allow to serve over HTTPS.\n  - `options` (`import('https').ServerOptions`) — allow to provide your own certificate.\n- `watchOptions` — a set of options used to customize watch mode, [more](https://webpack.js.org/configuration/watch/#watchoptions)\n  - `watchPackages` (`boolean`) - watch all changes in `node_modules`.\n- `reactRefresh` (`false | (options: ReactRefreshPluginOptions) =\u003e ReactRefreshPluginOptions`) — disable or configure `react-refresh` in dev mode, [more](https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/API.md#options)\n- `detectCircularDependencies` (`true | CircularDependenciesOptions`) - detect modules with circular dependencies, [more](https://github.com/aackerman/circular-dependency-plugin)\n- `lazyCompilation` (`true | LazyCompilationConfig`) — enable experimental [lazy compilation](https://webpack.js.org/configuration/experiments/#experimentslazycompilation) feature\n  - `true` — enable feature\n  - `LazyCompilationConfig`\n    - `port` (`number`) — port where to listen to from the server\n    - `entries` (`boolean=true`) — if `false` - disables lazy compilation for `src/ui/entries` folder content\n\n##### Production build\n\n- `analyzeBundle` (`true | statoscope`) — tools to analyze bundle.\n  - `true` — enable [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer) plugin. Report generated to `dist/public/build/stats.html`\n  - `statoscope` — enable [statoscope](https://github.com/statoscope/statoscope) plugin. Reports generated to `dist/public/build/stats.json` and `dist/public/build/report.json`\n- `reactProfiling` (`boolean`) — use react profiler API in production, this option also disable minimization. The API is required by React developers tools for profile.\n- `statoscopeConfig` (`Options`) — `@statoscope/webpack-plugin` [configuration options](https://github.com/statoscope/statoscope/tree/master/packages/webpack-plugin#usage). Might be used to override the defaults. Requires `analyzeBundle: statoscope`.\n- `cdn` (`CdnUploadConfig | CdnUploadConfig[]`) - upload bundled client files to CDN.\n  - `bucket` (`string`) — bucket name\n  - `prefix` (`string`) — path to files inside the bucket\n  - `region` (`string`) — AWS region or any string\n  - `endpoint` (`string`) - cdn host to upload files\n  - `publicPath` (`string`) - public path to access files from the browser\n  - `compress` (`boolean`) - upload also gzip and brotli compressed versions of files\n  - `additionalPattern` (`string[]`) — patterns for uploading additional files. By default, only files generated by webpack are loaded.\n- `sentryConfig` (`Options`) — `@sentry/webpack-plugin` [configuration options](https://www.npmjs.com/package/@sentry/webpack-plugin/v/2.7.1).\n\n##### Optimization\n\n- `vendors` (`string[] | (defaultVendors: string[]) =\u003e string[]`) — additional libraries or a function returning libraries for a vendor chunk;\n- `momentTz` — [settings](https://www.npmjs.com/package/moment-timezone-data-webpack-plugin) for moment-timezone (by default data is truncated);\n- `contextReplacement` (`object`)\n  - `highlight.js` (`string[]`) — list of language names to include, e.g. `['javascript', 'python', 'bash']`;\n  - `locale`: (`string[]=['ru']`) — list of `moment.js` or `day.js` locales to include, e.g. `['de', 'es']`. Locale `En` is always present.\n- `safari10` (`boolean`) — Enables `safari10` terser's option. [Terser options](https://github.com/terser/terser#minify-options)\n- `transformCssWithLightningCss` (`boolean`) — use [Lighting CSS](https://lightningcss.dev) to transform and minimize css instead of PostCSS and cssnano\n- `lightningCssMinimizerOptions` (`(options: LightningCssMinimizerRspackPluginOptions) =\u003e LightningCssMinimizerRspackPluginOptions`) - modify or return a custom [LightningCssMinimizerRspackPlugin](https://rspack.dev/plugins/rspack/lightning-css-minimizer-rspack-plugin)\n- `terser` (`(options: TerserOptions) =\u003e TerserOptions`) - modify or return a custom [Terser options](https://github.com/terser/terser#minify-options).\n\n##### Monaco editor support\n\n- `monaco` (`object`) — use [monaco-editor-webpack-plugin](https://github.com/microsoft/monaco-editor/tree/main/webpack-plugin#monaco-editor-webpack-loader-plugin)\n\n  - `fileName` (`string`) — custom filename template for worker scripts.\n  - `languages` (`string[]`) - include only a subset of the languages supported. If you don't need support for all languages, set needed languages explicitly, since it may significantly affect build time.\n  - `features` (`string[]`) - include only a subset of the editor features.\n  - `customLanguages` (`IFeatureDefinition[]`) - include custom languages (outside of the ones shipped with the `monaco-editor`).\n\n##### WebWorker support\n\nWeb workers allow you to run JavaScript code in a separate thread from the main UI thread.\nThis can improve the performance and responsiveness of your web application by offloading\nintensive tasks to the background.\n\nTo create a web worker, you need to write a script file that defines the logic of the worker. For example,\nthis file (my.worker.ts) implements a simple function that adds two numbers and sends the result back to the main thread:\n\n```ts\n// my.worker.ts\nself.onmessage = async (ev) =\u003e {\n  const {a = 0, b = 0} = ev.data || {};\n  const result = a + b;\n  self.postMessage({\n    result,\n  });\n};\n```\n\n`app-builder` provides built-in support for web workers for files with the `.worker.[jt]s` suffix. You can choose\nbetween two variants of getting web workers by setting the `webWorkerHandle` option:\n\n- `loader` (default) - use the `worker-loader` to import web workers.\n  Content of worker file will be included in main bundle as blob. This variant does not\n  support dynamic imports inside worker. For example:\n\n```ts\n// main.ts\nimport MyWorker from './my.worker.ts';\n\nconst worker = new MyWorker();\n```\n\nIn this variant, you need to add some type declarations for the worker files::\n\n```ts\n// worker.d.ts\ndeclare module '*.worker.ts' {\n  class WebpackWorker extends Worker {}\n\n  export default WebpackWorker;\n}\n```\n\n- `cdn-compat` - use the webpack 5 web workers [syntax](https://webpack.js.org/guides/web-workers/#syntax)\n  to import web workers. This variant allows to use dynamic imports inside worker and load worker bundle from CDN. For example:\n\n```ts\nimport {Worker} from '@gravity-ui/app-builder/worker';\n\nconst MyWorker = new Worker(new URL('./my.worker', import.meta.url));\n```\n\n- `none` - disable worker-specific handling.\n\nTo use the web worker in your main script, you need to communicate with it using the postMessage and onmessage methods. For example:\n\n```ts\n// main.ts\n\nconst worker = '...'; // Worker creation, first or second variant\n\nworker.onmessage = ({data: {result}}) =\u003e {\n  console.log(result);\n};\n\nworker.postMessage({a: 1, b: 2});\n```\n\n##### Module Federation\n\nModule Federation is a Webpack 5 feature that enables micro-frontend architecture, where JavaScript applications can dynamically load code from each other at runtime.\n\n`app-builder` uses `@module-federation/enhanced` for advanced Module Federation support.\n\n- `moduleFederation` (`object`) — Module Federation configuration\n\n  - `name` (`string`) — unique name of the application in the Module Federation ecosystem. Required parameter.\n  - `version` (`string`) — application version. When specified, the entry file will be named `entry-{version}.js` instead of `entry.js`.\n  - `disableManifest` (`boolean`) — disable manifest file generation. When `true`, uses regular `.js` files for remote entry instead of manifest files. Default is `false`.\n  - `remotes` (`string[]`) — list of remote application names that this application can load. This is a simplified alternative to `originalRemotes` that automatically generates remote URLs based on your public path configuration.\n\n    **How it works:**\n\n    - In **development mode**: Remote URLs are automatically generated using the pattern `{commonPublicPath}{remoteName}/entry.js` (or manifest files if enabled)\n    - In **production mode**: You need to ensure remote applications are deployed and accessible at the expected URLs\n    - Remote entry files are loaded at runtime to provide federated modules from other micro-frontends\n\n    **File naming patterns** (depends on configuration):\n\n    - With `disableManifest: false` (default): `mf-manifest.json` or `mf-manifest-[version].json` (with versioning)\n    - With `disableManifest: true`: `entry.js` or `entry-[version].js` (with versioning)\n\n    **Example:**\n\n    ```ts\n    // Simple configuration - URLs auto-generated in development\n    remotes: ['header', 'navigation', 'footer'];\n\n    // Results in loading from (in development):\n    // - https://localhost:3000/header/mf-manifest.json\n    // - https://localhost:3000/navigation/mf-manifest.json\n    // - https://localhost:3000/footer/mf-manifest.json\n    ```\n\n    **Development vs Production:**\n\n    - **Development**: App-builder automatically starts all remote applications and generates their URLs\n    - **Production**: Remote applications must be independently deployed and accessible at the generated URLs\n\n    **Integration with other options:**\n\n    - Works with `enabledRemotes` to selectively enable remotes in development\n    - Affected by `remotesRuntimeVersioning` for versioned file names\n    - File format controlled by `disableManifest` option\n\n    For more complex scenarios requiring custom URLs or cross-environment configurations, use `originalRemotes` instead.\n\n  - `enabledRemotes` (`string[]`) — list of enabled remotes for module federation. **Development mode only**. If not specified, all remotes from the `remotes` array will be enabled by default.\n\n    **Purpose:**\n\n    - Allows selective enabling/disabling of specific remotes during development\n    - Useful for debugging, testing individual micro-frontends, or working with partial system setups\n    - Helps reduce development startup time by loading only needed remotes\n    - Can be overridden via CLI flag: `--mf-remotes header footer`\n\n    **Loading behavior:**\n\n    **When CDN is disabled:**\n\n    - **Enabled remotes**: Loaded from local development server with version-specific paths\n    - **Disabled remotes**: Loaded from `cdnPublicPath` (if configured), otherwise fallback to local paths\n\n    **When CDN is enabled:**\n\n    - **All remotes**: Use common public path, `enabledRemotes` selection has no effect on URLs\n\n    **In production builds:**\n\n    - This option is completely ignored, all configured remotes are included in the bundle\n\n    **Example:**\n\n    ```ts\n    // Load all available remotes (header, navigation, footer)\n    remotes: ['header', 'navigation', 'footer'];\n\n    // Enable only specific remotes in development\n    enabledRemotes: ['header', 'footer']; // navigation will be skipped\n    ```\n\n    **CLI Override:**\n\n    ```bash\n    # Override enabledRemotes from command line\n    npx app-builder dev --mf-remotes header navigation\n    ```\n\n    **Note:** This option has no effect in production builds - all configured remotes will be included in the production bundle configuration.\n\n  - `originalRemotes` (`RemotesObject`) — full configuration of remote applications in Module Federation Plugin format. Use this when you need explicit control over remote URLs or for cross-environment deployments.\n\n    **When to use:**\n\n    - Custom remote URLs (different domains, ports, paths)\n    - Cross-environment loading (staging, production CDN URLs)\n    - Complex deployment scenarios\n    - When `remotes` auto-generation doesn't meet your needs\n\n    **Format:**\n\n    ```ts\n    originalRemotes: {\n      remoteName: 'remoteName@remoteUrl',\n    }\n    ```\n\n    **Examples:**\n\n    ```ts\n    originalRemotes: {\n      header: 'header@https://cdn.example.com/header/entry.js',\n      footer: 'footer@https://cdn.example.com/footer/entry.js',\n    }\n    ```\n\n    **Note:** When `originalRemotes` is specified, the `remotes` option is ignored. Use either `remotes` OR `originalRemotes`, not both.\n\n  - `remotesRuntimeVersioning` (`boolean`) — enables runtime versioning for remote applications. When enabled, remote entry files include version information in their filenames, allowing for cache busting and version-specific loading.\n\n    **How it affects file names:**\n\n    - With `disableManifest: false`: `mf-manifest-[version].json` instead of `mf-manifest.json`\n    - With `disableManifest: true`: `entry-[version].js` instead of `entry.js`\n    - Version is taken from the remote application's `version` configuration\n\n    **Benefits:**\n\n    - **Cache busting**: Different versions get different URLs, preventing browser caching issues\n    - **Rollback capability**: Can load specific versions of remotes\n    - **Deployment safety**: Gradual rollouts with version-specific remote loading\n\n    **Important considerations:**\n\n    - **Without CDN**: Version is inlined immediately during build time, as single build cannot contain multiple application versions\n    - **With CDN**: True runtime versioning is possible, versions are resolved dynamically at runtime\n    - **Recommendation**: Use `remotesRuntimeVersioning` together with CDN configuration for full dynamic versioning capabilities\n\n    **Example with versioning enabled:**\n\n    ```ts\n    // Host application\n    {\n      moduleFederation: {\n        name: 'shell',\n        remotes: ['header', 'navigation'],\n        remotesRuntimeVersioning: true, // Enable versioning\n      }\n    }\n\n    // Remote application (header)\n    {\n      moduleFederation: {\n        name: 'header',\n        version: '2.1.0', // This version appears in filename\n        exposes: { './Header': './src/Header' }\n      }\n    }\n\n    // Results in loading: header/mf-manifest-2.1.0.json\n    ```\n\n    **Runtime behavior:**\n\n    - The version is resolved at runtime from the remote's manifest or entry file\n    - Enables loading different versions of the same remote in different environments\n    - Works with both `remotes` and `originalRemotes` configurations\n\n  - `isolateAssets` (`boolean`) - put all assets to a folder with the name of Module Federation app name\n  - `isolateStyles` (`object`) — CSS style isolation settings to prevent conflicts between micro-frontends.\n    - `getPrefix` (`(entryName: string) =\u003e string`) — function to generate CSS class prefix.\n    - `prefixSelector` (`(prefix: string, selector: string, prefixedSelector: string, filePath: string) =\u003e string`) — function to add prefix to CSS selectors.\n  - Also supports all standard options from [@module-federation/enhanced](https://module-federation.io/), except `name` and `remotes`, such as:\n    - `filename` — entry file name (default `entry.js`)\n    - `exposes` — modules that this application exports\n    - `shared` — shared dependencies between applications\n    - `runtimePlugins` — plugins for Module Federation runtime\n\n**Host Application Configuration Example:**\n\nHost applications consume remote modules from other micro-frontends:\n\n```ts\nexport default defineConfig({\n  client: {\n    moduleFederation: {\n      name: 'shell',\n      // Simple remotes configuration\n      remotes: ['header', 'footer', 'sidebar'],\n      shared: {\n        react: {singleton: true, requiredVersion: '^18.0.0'},\n        'react-dom': {singleton: true, requiredVersion: '^18.0.0'},\n        lodash: {singleton: true},\n      },\n    },\n  },\n});\n```\n\n**Advanced Host Configuration:**\n\n```ts\nexport default defineConfig({\n  client: {\n    moduleFederation: {\n      name: 'main-shell',\n      version: '2.1.0',\n      // Detailed remotes configuration\n      originalRemotes: {\n        header: 'header@https://cdn.example.com/header/entry.js',\n        footer: 'footer@https://cdn.example.com/footer/entry.js',\n        userProfile: 'userProfile@https://cdn.example.com/user-profile/entry.js',\n      },\n      remotesRuntimeVersioning: true,\n      isolateStyles: {\n        getPrefix: (entryName) =\u003e `.app-${entryName}`,\n        prefixSelector: (prefix, selector, prefixedSelector, filePath) =\u003e {\n          if (\n            [prefix, ':root', 'html', 'body', '.g-root', '.remote-app'].some((item) =\u003e\n              selector.startsWith(item),\n            ) ||\n            filePath.includes('@gravity-ui/chartkit')\n          ) {\n            return selector;\n          }\n          return prefixedSelector;\n        },\n      },\n      shared: {\n        react: {singleton: true, requiredVersion: '^18.0.0'},\n        'react-dom': {singleton: true, requiredVersion: '^18.0.0'},\n        lodash: {singleton: true},\n      },\n    },\n  },\n});\n```\n\n**Remote Application Configuration Example:**\n\nRemote applications expose their modules for consumption by host applications:\n\n```ts\nexport default defineConfig({\n  client: {\n    moduleFederation: {\n      name: 'header',\n      // Expose modules for other applications\n      exposes: {\n        './Header': './src/components/Header',\n        './Navigation': './src/components/Navigation',\n        './UserMenu': './src/components/UserMenu',\n      },\n      shared: {\n        react: {singleton: true, requiredVersion: '^18.0.0'},\n        'react-dom': {singleton: true, requiredVersion: '^18.0.0'},\n        lodash: {singleton: true},\n      },\n    },\n  },\n});\n```\n\n**Bidirectional Configuration Example:**\n\nApplications can be both host and remote simultaneously:\n\n```ts\nexport default defineConfig({\n  client: {\n    moduleFederation: {\n      name: 'dashboard',\n      version: '1.5.0',\n      // Consume remote modules\n      remotes: ['charts', 'notifications'],\n      // Expose own modules\n      exposes: {\n        './DashboardLayout': './src/layouts/DashboardLayout',\n        './DataTable': './src/components/DataTable',\n      },\n      shared: {\n        react: {singleton: true, requiredVersion: '^18.0.0'},\n        'react-dom': {singleton: true, requiredVersion: '^18.0.0'},\n        lodash: {singleton: true},\n      },\n    },\n  },\n});\n```\n\n**Advanced Remotes Configuration Examples:**\n\n```ts\nexport default defineConfig({\n  client: {\n    moduleFederation: {\n      name: 'advanced-shell',\n      version: '3.0.0',\n\n      // Example 1: Simple remotes for development\n      remotes: ['header', 'sidebar', 'footer', 'analytics'],\n\n      // Example 2: Enable only specific remotes in development\n      enabledRemotes: ['header', 'sidebar'], // Only these will load in dev mode\n\n      // Example 3: Runtime versioning with manifests (production-ready)\n      remotesRuntimeVersioning: true, // Enables version-specific loading\n      disableManifest: false, // Use mf-manifest-[version].json files\n\n      shared: {\n        react: {singleton: true, requiredVersion: '^18.0.0'},\n        'react-dom': {singleton: true, requiredVersion: '^18.0.0'},\n      },\n    },\n  },\n});\n\n// Alternative: Explicit URLs for production\nexport default defineConfig({\n  client: {\n    moduleFederation: {\n      name: 'production-shell',\n\n      // Use originalRemotes for explicit control\n      originalRemotes: {\n        // Static CDN URLs\n        header: 'header@https://cdn.company.com/header/mf-manifest-2.1.0.json',\n        sidebar: 'sidebar@https://cdn.company.com/sidebar/entry-1.5.0.js',\n\n        // Dynamic remote loading\n        analytics: `promise new Promise((resolve) =\u003e {\n          const remoteUrl = process.env.NODE_ENV === 'production' \n            ? 'https://analytics.cdn.com/entry.js'\n            : 'http://localhost:3003/entry.js';\n          resolve(\\`analytics@\\${remoteUrl}\\`);\n        })`,\n      },\n\n      shared: {\n        react: {singleton: true, requiredVersion: '^18.0.0'},\n        'react-dom': {singleton: true, requiredVersion: '^18.0.0'},\n      },\n    },\n  },\n});\n```\n\n**Development Workflow with Remotes:**\n\n```bash\n# Start host application with all remotes\nnpx app-builder dev\n\n# Start host with only specific remotes (faster development)\nnpx app-builder dev --mf-remotes header sidebar\n\n# The above is equivalent to setting enabledRemotes in config:\n# enabledRemotes: ['header', 'sidebar']\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgravity-ui%2Fapp-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgravity-ui%2Fapp-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgravity-ui%2Fapp-builder/lists"}