Open-Source Wikis

/

Astro

/

Systems

/

CLI

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 --> I

The 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 (commit 7ac43c7) — replaced the previous clipboard library with tinyclip to drop a native dependency.
  • The info, docs, create-key, and telemetry commands all received the dependency-injection refactor in 2025.

Entry points for modification

  • Adding a new command: register it in resolveCommand(), add a case in runCommand(), and create a module under src/cli/<command>/.
  • Changing a help string: edit src/cli/help/index.ts's DEFAULT_HELP_PAYLOAD.
  • Adding a flag: thread it from runCommand() into the command module; add a Zod schema if it's persisted.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

CLI – Astro wiki | Factory