angular/angular-cli · warning

The "@angular-devkit/build-angular:app-shell" builder is dep

Error message

The "@angular-devkit/build-angular:app-shell" builder is deprecated as part of Angular's Webpack support deprecation. Use "@angular/build:application" instead. For more information, see https://angular.dev/tools/cli/build-system-migration.

What it means

The `@angular-devkit/build-angular:app-shell` builder is part of the legacy Webpack toolchain, which Angular is deprecating. Running it emits a deprecation warning directing users to the esbuild-based `@angular/build:application` builder and the build-system migration guide.

Source

Thrown at packages/angular_devkit/build_angular/src/builders/app-shell/index.ts:165

  if (!fs.existsSync(outputPath)) {
    throw new Error(`Could not find server output directory: ${outputPath}.`);
  }

  const re = /^main\.(?:[a-zA-Z0-9]{16}\.)?js$/;
  const maybeMain = fs.readdirSync(outputPath).find((x) => re.test(x));

  if (!maybeMain) {
    throw new Error('Could not find the main bundle.');
  }

  return path.join(outputPath, maybeMain);
}

async function _appShellBuilder(
  options: BuildWebpackAppShellSchema,
  context: BuilderContext,
): Promise<BuilderOutput> {
  context.logger.warn(
    'The "@angular-devkit/build-angular:app-shell" builder is deprecated as part of Angular\'s Webpack support deprecation. ' +
      'Use "@angular/build:application" instead. For more information, see https://angular.dev/tools/cli/build-system-migration.',
  );

  const browserTarget = targetFromTargetString(options.browserTarget);
  const serverTarget = targetFromTargetString(options.serverTarget);

  // Never run the browser target in watch mode.
  // If service worker is needed, it will be added in _renderUniversal();
  const browserOptions = (await context.getTargetOptions(browserTarget)) as JsonObject &
    BrowserBuilderSchema;

  const optimization = normalizeOptimization(browserOptions.optimization);
  optimization.styles.inlineCritical = false;

  const browserTargetRun = await context.scheduleTarget(browserTarget, {
    watch: false,
    serviceWorker: false,

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Migrate to the new build system: `ng generate @angular/build:apply-build-system-migration` (or follow https://angular.dev/tools/cli/build-system-migration).
  2. Switch `angular.json` targets from `@angular-devkit/build-angular:*` to `@angular/build:application` and use `@angular/build` prerendering/SSG for app-shell needs.
  3. Update options to the new schema (e.g. `browser`/`server` entry points under the application builder) and re-run the build.

Example fix

// before (angular.json)
"builder": "@angular-devkit/build-angular:app-shell"
// after
"builder": "@angular/build:application"
// with SSG/prerender configured via @angular/build
Defensive patterns

Strategy: validation

Validate before calling

// fail CI if deprecated builders are configured
const arch = require('./angular.json');
for (const [name, t] of Object.entries(arch.projects).flatMap(([p, pr]) => Object.entries(pr.architect ?? {}).map(([t2, v]) => [`${p}:${t2}`, v]))) {
  if (String(t.builder).startsWith('@angular-devkit/build-angular:')) throw new Error(`Migrate ${name} (${t.builder}) to @angular/build`);
}

Prevention

When it happens

Trigger: Executing a build/serve target whose builder is `@angular-devkit/build-angular:app-shell` in `angular.json` (or invoking that builder programmatically via `_appShellBuilder`).

Common situations: Projects created before the esbuild migration that still use app-shell prerendering with the Webpack builder; apps not yet migrated during Angular version upgrades.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/f76d1413b7177c07. Report an issue: GitHub.