@bleedingdev/modern-js-main-doc 3.4.0-ultramodern.9 → 3.5.0-ultramodern.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/docs/en/community/blog/v3-release-note.mdx +1 -1
  2. package/docs/en/configure/app/bff/effect.mdx +15 -3
  3. package/docs/en/configure/app/bff/runtime-framework.mdx +4 -2
  4. package/docs/en/configure/app/experiments/source-build.mdx +1 -1
  5. package/docs/en/configure/app/html/template-parameters.mdx +1 -1
  6. package/docs/en/configure/app/output/convert-to-rem.mdx +1 -1
  7. package/docs/en/configure/app/security/check-syntax.mdx +1 -1
  8. package/docs/en/configure/app/tools/html-plugin.mdx +1 -1
  9. package/docs/en/configure/app/tools/ts-checker.mdx +20 -1
  10. package/docs/en/guides/advanced-features/bff/data-platform.mdx +4 -4
  11. package/docs/en/guides/advanced-features/bff/frameworks.mdx +25 -14
  12. package/docs/en/guides/advanced-features/bff/function.mdx +4 -0
  13. package/docs/en/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
  14. package/docs/en/guides/basic-features/debug/using-storybook.mdx +1 -1
  15. package/docs/en/guides/basic-features/static-assets/json-files.mdx +2 -2
  16. package/docs/en/guides/get-started/_meta.json +2 -1
  17. package/docs/en/guides/get-started/ai-coding-agents.mdx +48 -0
  18. package/docs/en/guides/get-started/ultramodern.mdx +74 -23
  19. package/docs/en/guides/upgrade/config.mdx +1 -1
  20. package/docs/en/plugin/introduction.mdx +9 -9
  21. package/docs/zh/community/blog/v3-release-note.mdx +1 -1
  22. package/docs/zh/configure/app/bff/effect.mdx +14 -3
  23. package/docs/zh/configure/app/bff/runtime-framework.mdx +4 -2
  24. package/docs/zh/configure/app/experiments/source-build.mdx +1 -1
  25. package/docs/zh/configure/app/html/template-parameters.mdx +1 -1
  26. package/docs/zh/configure/app/output/convert-to-rem.mdx +1 -1
  27. package/docs/zh/configure/app/security/check-syntax.mdx +1 -1
  28. package/docs/zh/configure/app/tools/html-plugin.mdx +1 -1
  29. package/docs/zh/configure/app/tools/ts-checker.mdx +19 -0
  30. package/docs/zh/guides/advanced-features/bff/data-platform.mdx +2 -2
  31. package/docs/zh/guides/advanced-features/bff/frameworks.mdx +24 -14
  32. package/docs/zh/guides/advanced-features/page-performance/optimize-bundle.mdx +1 -1
  33. package/docs/zh/guides/basic-features/debug/using-storybook.mdx +1 -1
  34. package/docs/zh/guides/basic-features/static-assets/json-files.mdx +2 -2
  35. package/docs/zh/guides/get-started/_meta.json +2 -1
  36. package/docs/zh/guides/get-started/ai-coding-agents.mdx +48 -0
  37. package/docs/zh/guides/get-started/ultramodern.mdx +59 -19
  38. package/docs/zh/guides/upgrade/config.mdx +1 -1
  39. package/docs/zh/plugin/introduction.mdx +9 -9
  40. package/package.json +2 -2
@@ -591,7 +591,7 @@ As Node.js continues to evolve, Node.js 18 has reached EOL. In Modern.js 3.0, we
591
591
 
592
592
  #### Storybook Rsbuild
593
593
 
594
- In Modern.js 3.0, we implemented Storybook for Modern.js applications based on [Storybook Rsbuild](https://github.com/rspack-contrib/storybook-rsbuild).
594
+ In Modern.js 3.0, we implemented Storybook for Modern.js applications based on [Storybook Rsbuild](https://github.com/rstackjs/storybook-rsbuild).
595
595
 
596
596
  Through a Storybook Addon, we convert and merge Modern.js configuration into Rsbuild configuration, and use Storybook Rsbuild to drive the build, keeping Storybook debugging aligned with development command configurations.
597
597
 
@@ -9,6 +9,7 @@ title: effect
9
9
  ```ts
10
10
  type BffEffectUserConfig = {
11
11
  entry?: string;
12
+ strictEffectApproach?: true;
12
13
  openapi?: boolean | { path?: string };
13
14
  dataPlatform?: {
14
15
  enabled?: boolean;
@@ -58,7 +59,7 @@ For Effect v4, TypeScript should use export-map aware module resolution.
58
59
  ## bff.effect.entry
59
60
 
60
61
  - **Type:** `string`
61
- - **Default:** `<apiDirectory>/effect/index`
62
+ - **Default:** `<apiDirectory>/index`
62
63
 
63
64
  Specifies the entry module for Effect HttpApi runtime.
64
65
 
@@ -67,12 +68,23 @@ export default defineConfig({
67
68
  bff: {
68
69
  runtimeFramework: 'effect',
69
70
  effect: {
70
- entry: './api/effect/index',
71
+ entry: './api/index',
71
72
  },
72
73
  },
73
74
  });
74
75
  ```
75
76
 
77
+ ## bff.effect.strictEffectApproach
78
+
79
+ - **Type:** `true`
80
+ - **Default:** `true`
81
+
82
+ Effect BFF modules must expose the strict Effect API surface
83
+ (`defineEffectBff(...)` or `{ api, layer }`) and raw request handlers are
84
+ rejected. Generated UltraModern apps write this marker explicitly and pair it
85
+ with source checks that reject Hono server imports, manual request parsing, and
86
+ manual `Response` construction in generated API modules.
87
+
76
88
  ## bff.effect.openapi
77
89
 
78
90
  - **Type:** `boolean | { path?: string }`
@@ -173,4 +185,4 @@ export default defineConfig({
173
185
 
174
186
  `batch.flushIntervalMs` controls the client-side micro-batch window in the generated Effect client. `maxConcurrency` and `requestTimeoutMs` are applied by the server batch gateway when dispatching items.
175
187
 
176
- The generated `effectBff.client.*` API only exists for loader-materialized `@api/effect/*` imports. Directly importing the server entry (`api/effect/index`) exposes the Effect BFF definition; its `client` property is a placeholder that fails on operation access.
188
+ The generated `api.client.*` API only exists for loader-materialized `@api/index` imports. Directly importing the server entry (`api/index`) exposes the Effect BFF definition; its `client` property is a placeholder that fails on operation access.
@@ -21,8 +21,10 @@ export default defineConfig({
21
21
  });
22
22
  ```
23
23
 
24
- - Set to `'effect'` to run BFF only from `api/effect/index` (Effect HttpApi runtime).
24
+ - Set to `'effect'` to run BFF only from `api/index` (Effect HttpApi runtime).
25
25
  - Set to `'hono'` to run BFF only from file-convention handlers under `api/lambda/**`.
26
26
 
27
27
  There is no implicit fallback between runtimes. Choose one runtime mode per app.
28
- Generated UltraModern apps use the Effect lane by default; set `runtimeFramework: 'hono'` only for the compatibility runtime.
28
+ Generated UltraModern apps use strict Effect APIs by default and set
29
+ `bff.effect.strictEffectApproach: true`; `hono` and `api/lambda/**` are not
30
+ valid generated UltraModern HTTP API paths.
@@ -19,7 +19,7 @@ More detail can see ["Source Code Build Mode"](https://modernjs.dev/en/guides/ad
19
19
 
20
20
  ### Options
21
21
 
22
- `experiments.sourceBuild` is implemented based on [@rsbuild/plugin-source-build](https://github.com/rspack-contrib/rsbuild-plugin-source-build?tab=readme-ov-file#options). You can pass plugin options like this:
22
+ `experiments.sourceBuild` is implemented based on [@rsbuild/plugin-source-build](https://github.com/rstackjs/rsbuild-plugin-source-build?tab=readme-ov-file#options). You can pass plugin options like this:
23
23
 
24
24
  ```ts
25
25
  export default {
@@ -30,7 +30,7 @@ type DefaultParameters = {
30
30
  };
31
31
  ```
32
32
 
33
- Define the parameters in the HTML template, corresponding to the `templateParameters` config of [html-rspack-plugin](https://github.com/rspack-contrib/html-rspack-plugin). You can use the config as an object or a function.
33
+ Define the parameters in the HTML template, corresponding to the `templateParameters` config of [html-rspack-plugin](https://github.com/rstackjs/html-rspack-plugin). You can use the config as an object or a function.
34
34
 
35
35
  import RsbuildConfig from '@site-docs-en/components/rsbuild-config-tooltip';
36
36
 
@@ -80,4 +80,4 @@ export default {
80
80
  };
81
81
  ```
82
82
 
83
- For detailed usage, please refer to [rsbuild-plugin-rem](https://github.com/rspack-contrib/rsbuild-plugin-rem).
83
+ For detailed usage, please refer to [rsbuild-plugin-rem](https://github.com/rstackjs/rsbuild-plugin-rem).
@@ -70,4 +70,4 @@ If a syntax error is detected, you can handle it in the following ways:
70
70
 
71
71
  ### Options
72
72
 
73
- `security.checkSyntax` is implemented based on `@rsbuild/plugin-check-syntax`. For specific options, please refer to [@rsbuild/plugin-check-syntax](https://github.com/rspack-contrib/rsbuild-plugin-check-syntax).
73
+ `security.checkSyntax` is implemented based on `@rsbuild/plugin-check-syntax`. For specific options, please refer to [@rsbuild/plugin-check-syntax](https://github.com/rstackjs/rsbuild-plugin-check-syntax).
@@ -38,7 +38,7 @@ const defaultOptions = {
38
38
  SSR Application does not enable the `minify.removeComments` configuration, otherwise the SSR rendering will fail.
39
39
  :::
40
40
 
41
- The configs of [html-rspack-plugin](https://github.com/rspack-contrib/html-rspack-plugin) can be modified through `tools.htmlPlugin`.
41
+ The configs of [html-rspack-plugin](https://github.com/rstackjs/html-rspack-plugin) can be modified through `tools.htmlPlugin`.
42
42
 
43
43
  import RsbuildConfig from '@site-docs-en/components/rsbuild-config-tooltip';
44
44
 
@@ -43,7 +43,9 @@ By default, the [@rsbuild/plugin-type-check](https://github.com/rstackjs/rsbuild
43
43
 
44
44
  ## Example
45
45
 
46
- When the value of `tsChecker` is of type Object, it will be deeply merged with the default configuration.
46
+ ### Object Type
47
+
48
+ When the value of `tsChecker` is an object, it will be deeply merged with the default configuration.
47
49
 
48
50
  ```ts
49
51
  export default {
@@ -57,6 +59,23 @@ export default {
57
59
  };
58
60
  ```
59
61
 
62
+ ### Function Type
63
+
64
+ When the value of `tsChecker` is a function, the default configuration will be passed as the first argument. You can directly modify the configuration object or return an object as the final configuration.
65
+
66
+ ```ts
67
+ export default {
68
+ tools: {
69
+ tsChecker(options) {
70
+ options.async = false;
71
+ return options;
72
+ },
73
+ },
74
+ };
75
+ ```
76
+
77
+ > Please refer to [@rsbuild/plugin-type-check](https://github.com/rstackjs/rsbuild-plugin-type-check) for more details.
78
+
60
79
  ## TypeScript Go by Default
61
80
 
62
81
  Type checking runs on [TypeScript Go](https://github.com/microsoft/typescript-go) (`tsgo`) by default in this fork. The capability is provided by [`ts-checker-rspack-plugin`](https://github.com/rstackjs/ts-checker-rspack-plugin), which is integrated by [`@rsbuild/plugin-type-check`](https://github.com/rstackjs/rsbuild-plugin-type-check), and reduces type-checking time by about 5-10x.
@@ -4,7 +4,7 @@ title: Data Platform
4
4
 
5
5
  # Data Platform
6
6
 
7
- Modern.js Effect BFF now supports a request-envelope based data platform contract for safer and more predictable data orchestration in complex applications such as Module Federation and micro frontends.
7
+ Modern.js Effect API runtime now supports a request-envelope based data platform contract for safer and more predictable data orchestration in complex applications such as Module Federation and micro frontends.
8
8
 
9
9
  ## What it solves
10
10
 
@@ -57,11 +57,11 @@ export default defineConfig({
57
57
 
58
58
  Envelope validation is enabled by default but does not require an envelope unless `requireEnvelope` is set. Origin validation is enabled by default; set `validateOrigin: false` to skip comparing the envelope origin against the incoming `Origin` header, or the request URL origin when the header is absent.
59
59
 
60
- ## Generated Effect client behavior
60
+ ## Generated API client behavior
61
61
 
62
- When using the generated Effect client (`@api/effect/index`), Modern.js automatically attaches a serialized data envelope header (`x-modernjs-data-envelope`) for same-origin requests.
62
+ When using the generated API client (`@api/index`), Modern.js automatically attaches a serialized data envelope header (`x-modernjs-data-envelope`) for same-origin requests.
63
63
 
64
- The generated client is loader-materialized. Import it from `@api/effect/*` in browser or client-bundled code; direct imports of the server entry (`api/effect/index`) expose the Effect BFF definition and only provide a placeholder `client`.
64
+ The generated client is loader-materialized. Import it from `@api/index` in browser or client-bundled code; direct imports of the server entry (`api/index`) expose the Effect API definition and only provide a placeholder `client`.
65
65
 
66
66
  The envelope includes:
67
67
 
@@ -7,11 +7,20 @@ title: Runtime Framework
7
7
 
8
8
  Modern.js supports two BFF runtime frameworks:
9
9
 
10
- - `effect` (default): use [Effect HttpApi](https://effect.website/) runtime from `api/effect/index`.
10
+ - `effect` (default): use [Effect HttpApi](https://effect.website/) runtime from `api/index`.
11
11
  - `hono`: use file-convention BFF handlers from `api/lambda/**`.
12
12
 
13
13
  `effect` and `hono` are strict runtime modes. There is no automatic fallback between them.
14
14
 
15
+ ::::info
16
+ This page documents generic Modern.js runtime support. Generated UltraModern
17
+ workspaces always use the `effect` runtime with
18
+ `bff.effect.strictEffectApproach: true`. Add or change generated UltraModern
19
+ HTTP API work through `shared/api.ts` and `api/index.ts`; do not add
20
+ Hono/file-convention handlers, raw request parsing, or manual `Response`
21
+ construction inside those workspaces.
22
+ ::::
23
+
15
24
  ## Switch to Effect runtime
16
25
 
17
26
  ```ts title="modern.config.ts"
@@ -23,6 +32,8 @@ export default defineConfig({
23
32
  bff: {
24
33
  runtimeFramework: 'effect',
25
34
  effect: {
35
+ entry: './api/index',
36
+ strictEffectApproach: true,
26
37
  openapi: {
27
38
  path: '/openapi.json',
28
39
  },
@@ -33,7 +44,7 @@ export default defineConfig({
33
44
 
34
45
  Define a shared Effect HttpApi contract (for type-safe client + server):
35
46
 
36
- ```ts title="shared/effect/api.ts"
47
+ ```ts title="shared/api.ts"
37
48
  import {
38
49
  HttpApi,
39
50
  HttpApiEndpoint,
@@ -41,18 +52,18 @@ import {
41
52
  Schema,
42
53
  } from '@modern-js/plugin-bff/effect-client';
43
54
 
44
- export const bffEffectApi = HttpApi.make('MyApi').add(
55
+ export const bffApi = HttpApi.make('MyApi').add(
45
56
  HttpApiGroup.make('hello').add(
46
- HttpApiEndpoint.get('ping', '/effect/ping', {
57
+ HttpApiEndpoint.get('ping', '/ping', {
47
58
  success: Schema.String,
48
59
  }),
49
60
  ),
50
61
  );
51
62
  ```
52
63
 
53
- Implement your Effect BFF entry at `api/effect/index.ts`:
64
+ Implement your Effect API entry at `api/index.ts`:
54
65
 
55
- ```ts title="api/effect/index.ts"
66
+ ```ts title="api/index.ts"
56
67
  import {
57
68
  Schema,
58
69
  Effect,
@@ -61,7 +72,7 @@ import {
61
72
  Layer,
62
73
  ServiceMap,
63
74
  } from '@modern-js/plugin-bff/effect-server';
64
- import { bffEffectApi } from '../../shared/effect/api';
75
+ import { bffApi } from '../shared/api';
65
76
 
66
77
  class GreetingUnavailableError extends Schema.TaggedError<GreetingUnavailableError>()(
67
78
  'GreetingUnavailableError',
@@ -87,7 +98,7 @@ class GreetingService extends ServiceMap.Service<GreetingService>()('GreetingSer
87
98
  static readonly layer = Layer.effect(this, this.make);
88
99
  }
89
100
 
90
- const group = HttpApiBuilder.group(bffEffectApi, 'hello', handlers =>
101
+ const group = HttpApiBuilder.group(bffApi, 'hello', handlers =>
91
102
  handlers.handle('ping', () =>
92
103
  GreetingService.use(service => service.hello()).pipe(
93
104
  Effect.catchTag('GreetingUnavailableError', error =>
@@ -97,23 +108,23 @@ const group = HttpApiBuilder.group(bffEffectApi, 'hello', handlers =>
97
108
  ),
98
109
  );
99
110
 
100
- const layer = HttpApiBuilder.layer(bffEffectApi).pipe(
111
+ const layer = HttpApiBuilder.layer(bffApi).pipe(
101
112
  Layer.provide(group),
102
113
  Layer.provide(GreetingService.layer),
103
114
  );
104
115
 
105
- export default defineEffectBff({ api: bffEffectApi, layer });
116
+ export default defineEffectBff({ api: bffApi, layer });
106
117
  ```
107
118
 
108
- Call Effect endpoints from browser code via `@api/effect/index`:
119
+ Call Effect endpoints from browser code via `@api/index`:
109
120
 
110
121
  ```ts title="src/routes/page.tsx"
111
- import effectBff from '@api/effect/index';
122
+ import api from '@api/index';
112
123
 
113
- const response = await effectBff.client.hello.ping({});
124
+ const response = await api.client.hello.ping({});
114
125
  ```
115
126
 
116
- The `effectBff.client.*` surface is materialized by the BFF loader for `@api/effect/*` imports. Do not import `api/effect/index` directly and expect `client` to run in server code, scripts, or tests; direct entry imports expose the server runtime definition, and `client` is only a typed placeholder there.
127
+ The `api.client.*` surface is materialized by the BFF loader for `@api/index` imports. Do not import `api/index` directly and expect `client` to run in server code, scripts, or tests; direct entry imports expose the server runtime definition, and `client` is only a typed placeholder there.
117
128
 
118
129
  import Hono from '@site-docs-en/components/hono';
119
130
 
@@ -2,6 +2,10 @@
2
2
 
3
3
  In a Modern.js application, developers can define API files under the `api/lambda` directory and export API functions from these files. In the frontend code, these API functions can be directly invoked by importing the file, which initiates the API requests.
4
4
 
5
+ :::warning
6
+ `api/lambda/**` is the Hono/file-function compatibility runtime. New UltraModern generated API work should use the strict Effect runtime with `api/index.ts`, `shared/api.ts`, `defineEffectBff(...)`, and Effect `HttpApi` schemas instead.
7
+ :::
8
+
5
9
  This invocation method is called **unified invocation**, where developers do not need to write glue code for the frontend and backend separately, thereby ensuring type safety across both.
6
10
 
7
11
  ## Enable BFF
@@ -92,7 +92,7 @@ export default {
92
92
  };
93
93
  ```
94
94
 
95
- See details in [plugin-image-compress](https://github.com/rspack-contrib/rsbuild-plugin-image-compress).
95
+ See details in [plugin-image-compress](https://github.com/rstackjs/rsbuild-plugin-image-compress).
96
96
 
97
97
  ## Split Chunk
98
98
 
@@ -97,4 +97,4 @@ Now you can request the path configured in `bff.prefix`; if not configured, use
97
97
 
98
98
  ## Example
99
99
 
100
- You can check out the [example](https://github.com/rspack-contrib/storybook-rsbuild/tree/main/sandboxes/modernjs-react) to learn how to use Storybook in Modern.js.
100
+ You can check out the [example](https://github.com/rstackjs/storybook-rsbuild/tree/main/sandboxes/modernjs-react) to learn how to use Storybook in Modern.js.
@@ -38,7 +38,7 @@ import { name } from './example.json';
38
38
 
39
39
  YAML is a data serialization language commonly used for writing configuration files.
40
40
 
41
- You can configure the [YAML plugin](https://github.com/rspack-contrib/rsbuild-plugin-yaml) in `modern.config.ts` to support importing `.yaml` or `.yml` files, they will be automatically converted to JSON format.
41
+ You can configure the [YAML plugin](https://github.com/rstackjs/rsbuild-plugin-yaml) in `modern.config.ts` to support importing `.yaml` or `.yml` files, they will be automatically converted to JSON format.
42
42
 
43
43
  ```ts
44
44
  import { defineConfig } from '@modern-js/app-tools';
@@ -85,7 +85,7 @@ declare module '*.yml' {
85
85
 
86
86
  Toml is a semantically explicit, easy-to-read configuration file format.
87
87
 
88
- You can configure the [TOML plugin](https://github.com/rspack-contrib/rsbuild-plugin-toml) in `modern.config.ts` to support importing `.toml` files, it will be automatically converted to JSON format.
88
+ You can configure the [TOML plugin](https://github.com/rstackjs/rsbuild-plugin-toml) in `modern.config.ts` to support importing `.toml` files, it will be automatically converted to JSON format.
89
89
 
90
90
  ```ts
91
91
  import { defineConfig } from '@modern-js/app-tools';
@@ -4,5 +4,6 @@
4
4
  "quick-start",
5
5
  "upgrade",
6
6
  "glossary",
7
- "tech-stack"
7
+ "tech-stack",
8
+ "ai-coding-agents"
8
9
  ]
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: AI Tools
3
+ sidebar_position: 6
4
+ ---
5
+
6
+ # Modern.js For AI
7
+
8
+ Modern.js provides a toolkit for AI agents that helps developers use AI to efficiently complete feature development, dependency upgrades, and version migration for Modern.js applications.
9
+
10
+ ## llms.txt
11
+
12
+ Modern.js docs follow the [llms.txt specification](https://llmstxt.org/), auto-generated by [`@rspress/plugin-llms`](https://rspress.rs/plugin/official-plugins/llms), accessible via `/llms.txt` or `/llms-full.txt`:
13
+
14
+ - Index: [`https://modernjs.dev/llms.txt`](https://modernjs.dev/llms.txt)
15
+ - Full text: `https://modernjs.dev/llms-full.txt` (large — fetch on demand)
16
+
17
+ Most "what is this API / config" questions can be answered from llms.txt. Just let your agent retrieve it on demand; no need to copy docs into your project.
18
+
19
+ ## Skills
20
+
21
+ Skills are on-demand AI capabilities following the [Agent Skills open standard](https://github.com/vercel-labs/skills). User-facing Skills:
22
+
23
+ | Skill | Identifier | Description |
24
+ |---|---|---|
25
+ | Upgrade to v3 | `modernjs-migrate-to-v3` | Migrate a v2 app to v3: safe rewrites + manual checklist + migration report |
26
+ | Enable features | `modernjs-feature-enable` | Enable BFF / SSG / styled-components for v3 apps, and scaffold Tailwind CSS / custom Web Server |
27
+
28
+ > Skills are not force-installed or implicitly installed — you install them explicitly. RSC and micro-frontend setups are configuration or architecture decisions, not one-click `modernjs-feature-enable` actions.
29
+
30
+ ## Installing Skills
31
+
32
+ Modern.js user-facing Skills live in the repo's root `skills/` directory and follow the [Agent Skills open standard](https://github.com/vercel-labs/skills). The recommended way is the standard `skills` CLI, installing straight from GitHub:
33
+
34
+ ```bash
35
+ # List installable Skills
36
+ npx skills add web-infra-dev/modern.js --list
37
+
38
+ # Install a single Skill into your agent directory (--agent: claude-code / codex / cursor / ...)
39
+ npx skills add web-infra-dev/modern.js --skill modernjs-migrate-to-v3 --agent codex -y
40
+ ```
41
+
42
+ It installs the entire Skill directory (`SKILL.md` + `scripts/` + `references/`) into the corresponding agent directory, ready to trigger there.
43
+
44
+ > To pin a specific version, append `#<ref>` (a tag, branch, or commit) to the repo — it installs the Skill as of that ref (replace `<tag>` with a release tag that contains this Skill):
45
+ >
46
+ > ```bash
47
+ > npx skills add web-infra-dev/modern.js#<tag> --skill modernjs-migrate-to-v3 --agent codex -y
48
+ > ```
@@ -7,14 +7,16 @@ sidebar_position: 2
7
7
 
8
8
  This page compares **UltraModern.js 3.0** with the Modern.js 3.x line this fork tracks. The baseline is the current merged Modern.js `release-v3.x` baseline, not a frozen patch-version snapshot.
9
9
 
10
- UltraModern.js 3.0 is our SuperApp framework forked from Modern.js. It keeps compatibility with the Modern.js plugin/runtime mental model where that helps adoption, but it is positioned as a separate framework for Effect-first BFFs, TanStack Router, SSR, Module Federation, and independently deployable Micro Verticals.
10
+ UltraModern.js 3.0 is our SuperApp framework forked from Modern.js. It keeps the Modern.js plugin/runtime mental model where that helps adoption, but it is positioned as a separate framework for Effect HttpApi-first HTTP APIs, TanStack Router, SSR, Module Federation, and independently deployable Micro Verticals.
11
11
 
12
12
  ## Design Principles
13
13
 
14
14
  - Keep deltas explicit and auditable.
15
- - Preserve compatibility with useful Modern.js concepts without presenting UltraModern.js as a preset-only variant.
15
+ - Keep upstream Modern.js merge compatibility explicit: generic Modern.js runtime
16
+ code can remain where it belongs, while UltraModern-generated surfaces stay
17
+ strict.
16
18
  - Add platform-level contracts only where they improve cross-team reliability.
17
- - Keep opt-out switches and explicit compatibility lanes available.
19
+ - Keep escape hatches explicit and outside the generated HTTP API path.
18
20
 
19
21
  ## Compatibility Contract
20
22
 
@@ -24,7 +26,9 @@ UltraModern.js 3.0 keeps:
24
26
  - Existing project structure and command flow.
25
27
  - Progressive adoption path (apps can stay mostly unchanged).
26
28
 
27
- UltraModern.js additions are designed as the default product surface for new SuperApps. Compatibility lanes remain available when they reduce migration risk, but the framework direction is Effect + TanStack + SSR + Micro Verticals.
29
+ UltraModern.js additions are designed as the default product surface for new SuperApps. The framework direction is Effect + TanStack + SSR + Micro Verticals, and generated HTTP API work uses that direction by default instead of preserving parallel raw-handler layouts.
30
+ Existing Modern.js apps can migrate gradually; once an API surface is generated
31
+ or migrated as UltraModern HTTP API, it must use the strict Effect HttpApi path.
28
32
 
29
33
  ## Intentional Differences (v3 line)
30
34
 
@@ -33,7 +37,7 @@ UltraModern.js additions are designed as the default product surface for new Sup
33
37
  | Build diagnostics | RsDoctor is generally opt-in | Adds a first-class `performance.rsdoctor` config surface (opt-in; the earlier default-on behavior and diagnostics contract artifact were reverted) |
34
38
  | Output and static serving | Precompression behavior is app-defined | Enables `output.precompress` by default and serves `.br` / `.gz` variants via `Accept-Encoding` negotiation |
35
39
  | BFF runtime and contracts | Standard BFF runtime/client generation | Adds `requestId`-aware producer isolation, fail-fast initialization checks, and operation/trace correlation headers |
36
- | BFF runtime choices | Hono runtime path only in Modern.js 3.0 baseline (no built-in Effect runtime path) | Sets Effect as default runtime, enforces strict runtime split (`effect` -> `api/effect`, `hono` -> `api/lambda`), and adds Effect-Schema-first contracts plus MF failure-injection reliability coverage |
40
+ | BFF runtime choices | Standard request-handler oriented BFF paths | Uses Effect `HttpApi` as the only generated HTTP API path (`api/index.ts`, `shared/api.ts`, `src/api/*`) and rejects raw handlers, manual parsing, manual `Response` construction, and Hono server imports in generated workspaces |
37
41
  | Telemetry standardization | Observability wiring is often app-specific | Adds framework-level telemetry pipeline with OTLP/VictoriaMetrics exporters, redaction, batching, and backpressure controls |
38
42
  | App-level MF SSR handshake | No dedicated super-app app-level stability contract focus | Adds `server.ssr.moduleFederationAppSSR` plus integration-tested env/config handshake |
39
43
  | MF vertical loading reliability | Retry/fallback patterns are often implemented per app | Adds deterministic timeout/network/contract-error reliability matrix and distributed OTEL continuity tests |
@@ -46,16 +50,19 @@ UltraModern.js additions are designed as the default product surface for new Sup
46
50
 
47
51
  - We do not hide the fork behind legacy Modern.js branding.
48
52
  - We do not optimize for generic Modern.js defaults when they conflict with SuperApp reliability.
49
- - We keep both runtime modes (`effect`, `hono`) as explicit choices and avoid implicit fallback between them.
50
- - We avoid incompatible API changes unless there is a hard reliability requirement.
53
+ - We do not delete generic Modern.js Hono/file-convention runtime support just
54
+ to enforce UltraModern policy; the enforcement lives in UltraModern
55
+ generator, config, checks, and generated workspaces.
56
+ - Generated UltraModern API work uses the Effect runtime only; raw Hono/function handlers are not part of the generated API architecture.
57
+ - We make incompatible scaffold changes when they remove architecture drift.
51
58
 
52
59
  ## Migration Guide
53
60
 
54
- For teams already on Modern.js 3.0 or an older BleedingDev UltraModern scaffold, the adoption path remains compatibility-aware: keep the pieces that reduce risk, move toward MV-first / TanStack-first / Effect-first defaults, and keep fallback lanes explicit while you adopt UltraModern.js 3.0 as a separate framework.
61
+ For teams already on Modern.js 3.0 or an older BleedingDev UltraModern scaffold, the adoption path is to move API work onto the strict Effect HttpApi surface instead of preserving older raw handler layouts.
55
62
 
56
- 1. Keep existing React Router apps running as-is. TanStack Router is the preferred path for new scaffolds and incremental route adoption, but the React Router lane remains supported while teams move on their own schedule.
57
- 2. Prefer `bff.runtimeFramework: 'effect'` for new BFF work, with the entry implemented at `api/effect/index.ts`. If your app already uses Hono handlers under `api/lambda/**`, keep `bff.runtimeFramework: 'hono'` until you are ready to move them; Hono remains a supported compatibility lane.
58
- 3. Treat the baseline contracts as progressive defaults, not a forced cutover. `MODERN_BASELINE_ENABLE_MF_SSR`, `MODERN_BASELINE_ENABLE_BFF_REQUEST_ID`, and `MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS` already let each app opt out while it converges on the preferred stack.
63
+ 1. Keep existing Modern.js apps running as-is while they are outside the generated UltraModern surface. TanStack Router is the preferred path for new scaffolds and incremental route adoption, but route migration can happen on the team's schedule.
64
+ 2. Use `bff.runtimeFramework: 'effect'` with `bff.effect.strictEffectApproach: true` for API work. Entries live at `api/index.ts`, contracts live at `shared/api.ts`, clients live under `src/api/*`, and request/response/error shapes come from Effect `Schema` plus `HttpApi`.
65
+ 3. Treat raw handlers, `api/lambda/**`, manual `Response` construction, and manual request parsing as migration defects in generated or migrated UltraModern workspaces.
59
66
  4. The public preset now ships with explicit release and certification gates. Generated workspaces include `.github/workflows/ultramodern-workspace-gates.yml`, so `pnpm check` and `pnpm build` stay part of the local adoption contract from day one while CI runs the primitive gates as parallel matrix jobs.
60
67
 
61
68
  For an older generated workspace, migrate by treating the published cohort as
@@ -71,14 +78,58 @@ mise exec -- pnpm check
71
78
  mise exec -- pnpm build
72
79
  ```
73
80
 
81
+ Strict generated API migration requires `3.5.0-ultramodern.0` or newer.
82
+ `3.4.0-ultramodern.20` and earlier cohorts do not include this full direct
83
+ `api/index.ts` generator, generated `.mts` checks, and strict Oxlint boundary
84
+ rule set. Agents that cannot install that BleedingDev cohort yet should use the
85
+ local Modern.js workspace for migration validation; otherwise pin
86
+ `3.5.0-ultramodern.0` or newer with `--ultramodern-package-version`.
87
+
88
+ Gradual migration means old, unmigrated Modern.js apps can keep their existing
89
+ runtime until they are converted. Once a surface is generated or migrated as
90
+ UltraModern HTTP API, it uses Effect HttpApi only; do not keep Hono, lambda
91
+ handlers, or raw request handlers inside that UltraModern API surface.
92
+
93
+ When migrating a generated workspace that already has nested Effect API files, make the
94
+ move explicit and do not keep compatibility aliases:
95
+
96
+ 1. Move each vertical server entry from `verticals/<id>/api/effect/index.ts` to
97
+ `verticals/<id>/api/index.ts`.
98
+ 2. Move each shared API contract from `verticals/<id>/shared/effect/api.ts` to
99
+ `verticals/<id>/shared/api.ts`.
100
+ 3. Move generated clients from `verticals/<id>/src/effect/*-client.ts` to
101
+ `verticals/<id>/src/api/*-client.ts`.
102
+ 4. Move shell API aggregates from `apps/shell-super-app/src/effect/*` to
103
+ `apps/shell-super-app/src/api/*`.
104
+ 5. Update imports and package exports to use `./api`, `./api/client`, and
105
+ `@<workspace>/<vertical>/api/client`; remove `./effect/client`,
106
+ `./shared/effect/api`, and shared Effect API packages.
107
+ 6. Update every vertical `modern.config.ts` to use
108
+ `bff.effect.entry: './api/index'` and
109
+ `bff.effect.strictEffectApproach: true`.
110
+ 7. Update topology so API metadata lives directly under `api` with
111
+ `api.bff.strictEffectApproach: true`; do not keep `api.effect`.
112
+ 8. Run `pnpm api:check`,
113
+ `scripts/validate-ultramodern-workspace.mts`, `pnpm check`, and
114
+ `pnpm build`.
115
+
116
+ If a migration fails, fix the owning generated contract, topology, package
117
+ exports, or API module. Do not add app-level aliases, raw request handlers,
118
+ manual `Response` construction, local type casts, or package shims to make the
119
+ old layout pass.
120
+
121
+ Effect RPC, WebSockets, and other transports should be added as explicit
122
+ transport surfaces when needed. They do not make raw request handlers valid
123
+ inside generated HTTP API modules.
124
+
74
125
  Use one package-source strategy per repo. The published BleedingDev create
75
126
  package defaults to `--ultramodern-package-source=install` and records the
76
- exact cohort in `.modernjs/ultramodern-package-source.json`. Keep `--workspace`
77
- only for local monorepo testing against unreleased packages. Release proof and
78
- CI should pin the exact cohort with `--ultramodern-package-version` when a
79
- repo must prove a specific published framework version.
127
+ exact cohort in `.modernjs/ultramodern.json`. Keep `--workspace` only for local
128
+ monorepo testing against unreleased packages. Release proof and CI should pin
129
+ the exact cohort with `--ultramodern-package-version` when a repo must prove a
130
+ specific published framework version.
80
131
 
81
- Older repos with Effect BFF entries and `verbatimModuleSyntax` should update to
132
+ Older repos with nested Effect entries and `verbatimModuleSyntax` should update to
82
133
  the latest BleedingDev cohort instead of adding app-level `"type": "module"`
83
134
  metadata, Module Federation shims, or custom server wrappers. The framework BFF
84
135
  compiler normalizes CommonJS server output while generated app packages keep
@@ -92,7 +143,7 @@ repos by hand-editing generated worker output; upgrade the framework cohort and
92
143
  rerun the generated validation instead.
93
144
 
94
145
  After installing the new cohort, run the generated
95
- `scripts/validate-ultramodern-workspace.mjs` contract check before accepting
146
+ `scripts/validate-ultramodern-workspace.mts` contract check before accepting
96
147
  manual edits. Fix topology, ownership, package-source, local overlay, generated
97
148
  contract, Tailwind prefix, or Module Federation conflicts in the owning files
98
149
  instead of patching generated output by hand.
@@ -182,10 +233,10 @@ addUltramodernVertical({
182
233
  ```
183
234
 
184
235
  The public result includes the workspace root, package source, created apps,
185
- created paths, rewritten paths, assigned ports, Module Federation names, Effect
186
- API prefixes, generated contract path, and warnings. MicroVertical dry-run
236
+ created paths, rewritten paths, assigned ports, Module Federation names, API
237
+ prefixes, generated contract path, and warnings. MicroVertical dry-run
187
238
  returns the same shape plus `dryRun`, `selectedPort`, `moduleFederationRemote`,
188
- `effectApiPrefix`, `jsonMutations`, `shellDependencyChanges`, and
239
+ `apiPrefix`, `jsonMutations`, `shellDependencyChanges`, and
189
240
  `generatedContractChanges`; it prints JSON from the CLI and writes no files.
190
241
 
191
242
  CodeSmith consumers can use the adapter subpath:
@@ -239,8 +290,8 @@ non-indexable routes emit no JSON-LD by default. Public route owners can add
239
290
  `jsonLd` beside localized paths and use the generated
240
291
  `src/routes/ultramodern-jsonld.ts` helpers for common schema.org shapes.
241
292
 
242
- The generated contract writes `.modernjs/ultramodern-generated-contract.json`
243
- with a `cssFederation` section:
293
+ The generated contract writes `.modernjs/ultramodern.json` with a
294
+ `cssFederation` section:
244
295
 
245
296
  - `packages/shared-design-tokens` owns the shared token layer and exports `./tokens.css`.
246
297
  - Shell CSS owns only shell base and overlay layers under `[data-app-id="shell-super-app"]`.
@@ -248,7 +299,7 @@ with a `cssFederation` section:
248
299
  - Tailwind CSS v4 is local to each generated app through `@tailwindcss/postcss`; shared base styles must not be duplicated by verticals.
249
300
  - SSR first paint requires shared token CSS and app-owned CSS to be emitted by Modern/Rspack assets. Vertical CSS is loaded through manifest ownership, not copied into shell source.
250
301
 
251
- Version switching must select UI, Effect API, CSS, i18n JSON, and MF manifest evidence from the same vertical build marker. A shell render that only changes the UI marker is not enough.
302
+ Version switching must select UI, API, CSS, i18n JSON, and MF manifest evidence from the same vertical build marker. A shell render that only changes the UI marker is not enough.
252
303
 
253
304
  ### Validation And Deploy
254
305
 
@@ -314,7 +314,7 @@ export default {
314
314
 
315
315
  ### tools.pug
316
316
 
317
- **Change**: This configuration has been deprecated, use Rsbuild's [Pug plugin](https://github.com/rspack-contrib/rsbuild-plugin-pug) to enable support.
317
+ **Change**: This configuration has been deprecated, use Rsbuild's [Pug plugin](https://github.com/rstackjs/rsbuild-plugin-pug) to enable support.
318
318
 
319
319
  **Migration Example**:
320
320
 
@@ -131,21 +131,21 @@ The following are official Rsbuild plugins that are already built into Modern.js
131
131
  | [React Plugin](https://v2.rsbuild.rs/plugins/list/plugin-react) | Provides support for React | - |
132
132
  | [SVGR Plugin](https://v2.rsbuild.rs/plugins/list/plugin-svgr) | Supports converting SVG images into React components | [output.disableSvgr](/configure/app/output/disable-svgr)<br />[output.svgDefaultExport](/configure/app/output/svg-default-export) |
133
133
  | [Assets Retry Plugin](https://github.com/rstackjs/rsbuild-plugin-assets-retry) | Automatically retries requests when static asset loading fails | [output.assetsRetry](/configure/app/output/assets-retry.html) |
134
- | [Type Check Plugin](https://github.com/rspack-contrib/rsbuild-plugin-type-check) | Runs TypeScript type checking in a separate process | [output.disableTsChecker](/configure/app/output/disable-ts-checker.html)<br />[tools.tsChecker](/configure/app/tools/ts-checker.html) |
135
- | [Source Build Plugin](https://github.com/rspack-contrib/rsbuild-plugin-source-build) | For monorepo scenarios, supports referencing source code from other subdirectories and completing builds and hot updates | [experiments.sourceBuild](/configure/app/experiments/source-build.html) |
136
- | [Check Syntax Plugin](https://github.com/rspack-contrib/rsbuild-plugin-check-syntax) | Analyzes the syntax compatibility of the build artifacts to determine if there are any advanced syntax features that cause compatibility issues | [security.checkSyntax](/configure/app/security/check-syntax.html) |
137
- | [CSS Minimizer Plugin](https://github.com/rspack-contrib/rsbuild-plugin-css-minimizer) | Used to customize the CSS compression tool, switch to [cssnano](https://cssnano.co/) or other tools for CSS compression | [tools.minifyCss](/configure/app/tools/minify-css.html) |
138
- | [Rem Plugin](https://github.com/rspack-contrib/rsbuild-plugin-rem) | Implements rem adaptive layout for mobile pages | [output.convertToRem](/configure/app/output/convert-to-rem.html) |
134
+ | [Type Check Plugin](https://github.com/rstackjs/rsbuild-plugin-type-check) | Runs TypeScript type checking in a separate process | [output.disableTsChecker](/configure/app/output/disable-ts-checker.html)<br />[tools.tsChecker](/configure/app/tools/ts-checker.html) |
135
+ | [Source Build Plugin](https://github.com/rstackjs/rsbuild-plugin-source-build) | For monorepo scenarios, supports referencing source code from other subdirectories and completing builds and hot updates | [experiments.sourceBuild](/configure/app/experiments/source-build.html) |
136
+ | [Check Syntax Plugin](https://github.com/rstackjs/rsbuild-plugin-check-syntax) | Analyzes the syntax compatibility of the build artifacts to determine if there are any advanced syntax features that cause compatibility issues | [security.checkSyntax](/configure/app/security/check-syntax.html) |
137
+ | [CSS Minimizer Plugin](https://github.com/rstackjs/rsbuild-plugin-css-minimizer) | Used to customize the CSS compression tool, switch to [cssnano](https://cssnano.co/) or other tools for CSS compression | [tools.minifyCss](/configure/app/tools/minify-css.html) |
138
+ | [Rem Plugin](https://github.com/rstackjs/rsbuild-plugin-rem) | Implements rem adaptive layout for mobile pages | [output.convertToRem](/configure/app/output/convert-to-rem.html) |
139
139
 
140
140
  #### Plugins Not Built-in
141
141
 
142
142
  The following are official Rsbuild plugins that are not built into Modern.js:
143
143
 
144
- - [Image Compress Plugin](https://github.com/rspack-contrib/rsbuild-plugin-image-compress): Compresses image resources used in the project.
144
+ - [Image Compress Plugin](https://github.com/rstackjs/rsbuild-plugin-image-compress): Compresses image resources used in the project.
145
145
  - [Stylus Plugin](https://v2.rsbuild.rs/plugins/list/plugin-stylus): Uses Stylus as the CSS preprocessor.
146
- - [UMD Plugin](https://github.com/rspack-contrib/rsbuild-plugin-umd): Used to build UMD format artifacts.
147
- - [YAML Plugin](https://github.com/rspack-contrib/rsbuild-plugin-yaml): Used to reference YAML files and convert them to JavaScript objects.
148
- - [TOML Plugin](https://github.com/rspack-contrib/rsbuild-plugin-toml): Used to reference TOML files and convert them to JavaScript objects.
146
+ - [UMD Plugin](https://github.com/rstackjs/rsbuild-plugin-umd): Used to build UMD format artifacts.
147
+ - [YAML Plugin](https://github.com/rstackjs/rsbuild-plugin-yaml): Used to reference YAML files and convert them to JavaScript objects.
148
+ - [TOML Plugin](https://github.com/rstackjs/rsbuild-plugin-toml): Used to reference TOML files and convert them to JavaScript objects.
149
149
 
150
150
  import OtherPlugins from '@site-docs-en/components/other-plugins.mdx';
151
151