withastro/astro
CLI
The astro CLI is the front door for everything in the framework. It lives at packages/astro/bin/astro.mjs (a tiny import('../dist/cli/index.js') shim) and is implemented in packages/astro/src/cli/.
Purpose
Parse command-line arguments, route to the right command implementation, render help, surface errors, and run telemetry notifications. All commands ultimately delegate to either:
- Direct CLI-only commands (
help,version,info,create-key,docs,telemetry,sync,preferences). - Astro framework commands (
add,db/login/logout/link/init,dev,build,preview,check).
Source: packages/astro/src/cli/index.ts.
Commands
| Command | Implementation | Notes |
|---|---|---|
astro dev |
src/cli/dev/ → src/core/dev/dev.ts |
Long-running dev server. |
astro build |
src/cli/build/ → src/core/build/index.ts |
Static + SSR builder. |
astro preview |
src/cli/preview/ → src/core/preview/ |
Adapter-aware preview server. |
astro check |
src/cli/check/ |
Delegates to @astrojs/check. |
astro sync |
src/cli/sync/ → src/core/sync/ |
Generates .astro/types.d.ts, content types, env types. |
astro add <pkg> |
src/cli/add/ |
Installs and registers an integration. |
astro docs |
src/cli/docs/ |
Opens docs.astro.build in the right browser/IDE. |
astro info |
src/cli/info/ |
Prints debug info; can copy to clipboard. |
astro create-key |
src/cli/create-key/ |
Generates a base64 AES key for astro:env/sessions/CSP. |
astro telemetry |
src/cli/telemetry/ |
Enable/disable/reset telemetry. |
astro preferences |
src/cli/preferences/ |
Get/set user-level preferences. |
astro db <subcommand> |
src/cli/db/ → @astrojs/db |
Studio + migration commands. |
astro help, --version |
src/cli/help/, src/cli/utils/format-version.ts |
Help/version output. |
Argument parsing
The CLI uses yargs-parser (lightweight, no schema):
const flags = yargs(argv, { boolean: ['global'], alias: { g: 'global' } });The first positional after astro is the command (flags._[2]). Subcommands like astro db push use further positionals (flags._[3]).
Dispatch flow
graph TD
A[bin/astro.mjs] --> B[cli function]
B --> C[resolveCommand]
C --> D{Direct command?}
D -- help/version/info<br/>create-key/docs/<br/>telemetry/sync/preferences --> E[Run inline, no notify, no config]
D -- add/db/dev/build/<br/>preview/check --> F[notify telemetry]
F --> G[Lazy import command module]
G --> H[Execute]
E --> I[Exit]
H --> IThe lazy imports inside runCommand() keep startup fast: only the modules needed for the current command are loaded. This is why astro --version is essentially free even though the framework itself is several megabytes of TypeScript output.
Dependency injection
The newer commands follow the pattern documented under "Making code testable" in CONTRIBUTING.md:
- Domain types live in
src/cli/<command>/core/(pure functions and classes that consume interfaces). - Concrete implementations live in
src/cli/<command>/infra/. - Shared interfaces are in
src/cli/definitions.ts.
Example: astro info constructs a CliDebugInfoProvider, a StyledDebugInfoFormatter, a ClackPrompt, a TinyclipClipboard, and passes them to infoCommand({ logger, debugInfoProvider, getDebugInfoFormatter, clipboard }). Tests pass SpyLogger, fake formatters, and an in-memory clipboard.
astro create-key is the canonical example used in the contributing guide.
Older commands (build, dev, preview) have not been migrated; they import their core/ modules directly and pass through flags.
Help and version
packages/astro/src/cli/help/index.ts defines DEFAULT_HELP_PAYLOAD, which is rendered by LoggerHelpDisplay. A TextStyler interface (with implementations for piccolore and a passthrough no-color version) keeps the formatting testable.
formatVersion() in src/cli/utils/format-version.ts reads the version from BuildTimeAstroVersionProvider (which is generated at build time so the bundled CLI doesn't need to read package.json at runtime).
Recent changes
feat(cli): use tinyclip for astro info(commit7ac43c7) — replaced the previous clipboard library withtinyclipto drop a native dependency.- The
info,docs,create-key, andtelemetrycommands all received the dependency-injection refactor in 2025.
Entry points for modification
- Adding a new command: register it in
resolveCommand(), add acaseinrunCommand(), and create a module undersrc/cli/<command>/. - Changing a help string: edit
src/cli/help/index.ts'sDEFAULT_HELP_PAYLOAD. - Adding a flag: thread it from
runCommand()into the command module; add a Zod schema if it's persisted.
Related pages
- packages / astro
- features / actions —
astro create-keyunderpins encrypted action payloads. - how-to-contribute / patterns and conventions — DI pattern in detail.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.