pnpm exec aero <command>. Use the --root flag if your app lives in a subdirectory:
Commands
aero check
aero check validates your project without starting a dev server or running a full build. It checks your Aero config, content collections, and compiles every .html template to catch parse and codegen errors.
--types to also run TypeScript checking against your build scripts and { } expression sites:
--types, the CLI writes .aero/cache/types/components.d.ts so cross-file component references resolve correctly during the check. Resolution uses your workspace tsconfig.json, including path aliases and strict mode.
Exit codes
| Code | Meaning |
|---|---|
0 | No error-level diagnostics |
10 | Config error |
12 | Compile, resolve, or build-script error |
13 | Content schema error |
14 | Route error |
aero doctor
aero doctor prints a short environment checklist for your project:
- Node.js version (exits
1if below the minimum, currently Node 18) vitepresence inpackage.json@aero-js/coreor@aero-js/vitepresence inpackage.json@aero-js/cliversion- A reminder about the Aero VS Code extension
[ok], [warn], [info], or [fail]. Warnings still exit 0.
aero build
aero build runs vite build using your project’s Aero Vite config. Use --incremental to enable incremental builds for that run:
CI usage
Useaero check in CI to catch template and content errors before deploying. Add --types to also fail the pipeline on TypeScript errors.
--root when your CI job’s working directory is not the app root:
aero check validates config, content, and template compilation. It does not execute SSR, Nitro,
or a full Vite build, so it runs faster than vite build in CI.Why the CLI is a separate package
@aero-js/config already depends on @aero-js/core for alias resolution. Putting the CLI inside core and importing config loading would risk a circular dependency. The CLI lives in packages/cli, depends on @aero-js/core, @aero-js/config, and @aero-js/content, and publishes the aero binary.
How aero check works (summary)
- Config —
loadAeroConfig(root)from@aero-js/configloadsaero.config.ts,.js, or.mjswith the same behavior as Vite. If the config is missing or fails to load in some edge cases, behavior may fall back to defaultdirs; usevite buildorDEBUG=aeroif templates under a custom client directory seem skipped. - Content — When
aero.contentis enabled or acontent.config.tsexists, collections are loaded and validated. See Content. - Templates — Every
.htmlunderclient/pages,client/components, andclient/layouts(perdirs) is passed throughcompileTemplatefor parse and codegen checks, without a full Vite build.
vite.config.ts should import createViteConfig from @aero-js/config/vite so aero.config.ts can load without pulling Vite into the config entrypoint.
Programmatic APIs for tooling
Programmatic APIs for tooling
@aero-js/cli — The aero binary is the supported entry. runAeroCheck and runAeroDoctor
implement aero check and aero doctor; they are not necessarily exported as stable
programmatic APIs for apps — prefer invoking the CLI in CI.@aero-js/config — loadAeroConfig(root) loads project config. Effect-based loaders exist for
stricter failure handling where you need them.@aero-js/content — loadContentConfigFileSync, loadAllCollections, and
contentSchemaIssuesToAeroDiagnostics support the same content pipeline as the CLI.@aero-js/core/compile-check — compileTemplate for Node-only tooling that needs compile
checks without browser-oriented entrypoints.@aero-js/core/diagnostics — formatDiagnosticsTerminal, unknownToAeroDiagnostics,
AeroDiagnostic, and related helpers; aero check uses the same diagnostics contract as other
tooling surfaces.