diff --git a/docs/guide/api-environment.md b/docs/guide/api-environment.md
index 19efb8a8d0a0ca..02bfccfb126969 100644
--- a/docs/guide/api-environment.md
+++ b/docs/guide/api-environment.md
@@ -956,7 +956,7 @@ The callback is queued and it will wait for the current update to be resolved be
 
 In the CLI, calling `vite build` and `vite build --ssr` will still build the client only and ssr only environments for backward compatibility.
 
-When `builder.entireApp` is `true` (or when calling `vite build --app`), `vite build` will opt-in into building the entire app instead. This would later on become the default in a future major. A `ViteBuilder` instance will be created (build-time equivalent to a `ViteDevServer`) to build all configured environments for production. By default the build of environments is run in series respecting the order of the `environments` record. A framework or user can further configure how the environments are built using:
+When calling `vite build --app` or the `createBuilder()` API, Vite will opt into building the entire app instead. This would later on become the default in a future major. A `ViteBuilder` instance will be created (build-time equivalent to a `ViteDevServer`) to build all configured environments for production. By default the build of environments is run in series respecting the order of the `environments` record. A framework or user can further configure how the environments are built using:
 
 ```js
 export default {
diff --git a/docs/guide/cli.md b/docs/guide/cli.md
index 2860367e816c5b..d4aeab988d3d9e 100644
--- a/docs/guide/cli.md
+++ b/docs/guide/cli.md
@@ -69,7 +69,7 @@ vite build [root]
 | `-f, --filter <filter>`        | Filter debug logs (`string`)                                                                                        |
 | `-m, --mode <mode>`            | Set env mode (`string`)                                                                                             |
 | `-h, --help`                   | Display available CLI options                                                                                       |
-| `--app`                        | Build all environments, same as `builder.entireApp` (`boolean`, experimental)                                       |
+| `--app`                        | Build all environments, same as `(await createBuilder()).buildApp()` (`boolean`, experimental)                      |
 
 ## Others
 
diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts
index 7f1813ec4113d6..50c9da5ad519b3 100644
--- a/packages/vite/src/node/build.ts
+++ b/packages/vite/src/node/build.ts
@@ -521,15 +521,6 @@ export async function build(
     }
   }
   const config = await resolveConfigToBuild(inlineConfig, patchConfig)
-  return buildWithResolvedConfig(config)
-}
-
-/**
- * @internal used to implement `vite build` for backward compatibility
- */
-export async function buildWithResolvedConfig(
-  config: ResolvedConfig,
-): Promise<RollupOutput | RollupOutput[] | RollupWatcher> {
   const environmentName = config.build.ssr ? 'ssr' : 'client'
   const environment = await config.environments[
     environmentName
@@ -538,7 +529,7 @@ export async function buildWithResolvedConfig(
   return buildEnvironment(environment)
 }
 
-export function resolveConfigToBuild(
+function resolveConfigToBuild(
   inlineConfig: InlineConfig = {},
   patchConfig?: (config: ResolvedConfig) => void,
   patchPlugins?: (resolvedPlugins: Plugin[]) => void,
@@ -1503,7 +1494,6 @@ export interface ViteBuilder {
 export interface BuilderOptions {
   sharedConfigBuild?: boolean
   sharedPlugins?: boolean
-  entireApp?: boolean
   buildApp?: (builder: ViteBuilder) => Promise<void>
 }
 
@@ -1519,7 +1509,6 @@ export function resolveBuilderOptions(
   return {
     sharedConfigBuild: options.sharedConfigBuild ?? false,
     sharedPlugins: options.sharedPlugins ?? false,
-    entireApp: options.entireApp ?? false,
     buildApp: options.buildApp ?? defaultBuildApp,
   }
 }
@@ -1533,17 +1522,6 @@ export async function createBuilder(
   inlineConfig: InlineConfig = {},
 ): Promise<ViteBuilder> {
   const config = await resolveConfigToBuild(inlineConfig)
-  return createBuilderWithResolvedConfig(inlineConfig, config)
-}
-
-/**
- * Used to implement the `vite build` command without resolving the config twice
- * @internal
- */
-export async function createBuilderWithResolvedConfig(
-  inlineConfig: InlineConfig,
-  config: ResolvedConfig,
-): Promise<ViteBuilder> {
   const environments: Record<string, BuildEnvironment> = {}
 
   const builder: ViteBuilder = {
diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts
index f829e18e9ba387..fb42fd76acbe04 100644
--- a/packages/vite/src/node/cli.ts
+++ b/packages/vite/src/node/cli.ts
@@ -4,13 +4,13 @@ import { performance } from 'node:perf_hooks'
 import { cac } from 'cac'
 import colors from 'picocolors'
 import { VERSION } from './constants'
-import type { BuildEnvironmentOptions, ResolvedBuildOptions } from './build'
+import type { BuildEnvironmentOptions } from './build'
 import type { ServerOptions } from './server'
 import type { CLIShortcut } from './shortcuts'
 import type { LogLevel } from './logger'
 import { createLogger } from './logger'
 import { resolveConfig } from './config'
-import type { InlineConfig, ResolvedConfig } from './config'
+import type { InlineConfig } from './config'
 
 const cli = cac('vite')
 
@@ -279,14 +279,14 @@ cli
     `[boolean] force empty outDir when it's outside of root`,
   )
   .option('-w, --watch', `[boolean] rebuilds when modules have changed on disk`)
-  .option('--app', `[boolean] same as builder.entireApp`)
+  .option('--app', `[boolean] same as \`(await createBuilder()).buildApp()\``)
   .action(
     async (
       root: string,
       options: BuildEnvironmentOptions & BuilderCLIOptions & GlobalCLIOptions,
     ) => {
       filterDuplicateOptions(options)
-      const build = await import('./build')
+      const { build, createBuilder } = await import('./build')
 
       const buildOptions: BuildEnvironmentOptions = cleanGlobalCLIOptions(
         cleanBuilderCLIOptions(options),
@@ -301,35 +301,13 @@ cli
           logLevel: options.logLevel,
           clearScreen: options.clearScreen,
           build: buildOptions,
-          ...(options.app ? { builder: { entireApp: true } } : {}),
         }
-        const patchConfig = (resolved: ResolvedConfig) => {
-          if (resolved.builder.entireApp) {
-            return
-          }
-          // Until the ecosystem updates to use `environment.config.build` instead of `config.build`,
-          // we need to make override `config.build` for the current environment.
-          // We can deprecate `config.build` in ResolvedConfig and push everyone to upgrade, and later
-          // remove the default values that shouldn't be used at all once the config is resolved
-          const environmentName = resolved.build.ssr ? 'ssr' : 'client'
-          ;(resolved.build as ResolvedBuildOptions) = {
-            ...resolved.environments[environmentName].build,
-          }
-        }
-        const config = await build.resolveConfigToBuild(
-          inlineConfig,
-          patchConfig,
-        )
-
-        if (config.builder.entireApp) {
-          const builder = await build.createBuilderWithResolvedConfig(
-            inlineConfig,
-            config,
-          )
+        if (options.app) {
+          const builder = await createBuilder(inlineConfig)
           await builder.buildApp()
         } else {
           // Single environment (client or ssr) build or library mode build
-          await build.buildWithResolvedConfig(config)
+          await build(inlineConfig)
         }
       } catch (e) {
         createLogger(options.logLevel).error(