> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Aspect CLI: The Task Runner for Bazel

> The Aspect CLI is a free, open-source task runner that extends Bazel with first-class developer workflows: format, lint, BUILD generation, and delivery, programmable in Starlark.

export const MarketingPage = () => <div className="marketing-page-marker" style={{
  display: "none"
}} />;

export const CTA = ({title, subtitle, primaryCta, primaryHref = "#", secondaryCta, secondaryHref = "#"}) => <section className="w-full flex justify-center px-4 py-16 md:py-20">
    <div className="w-full rounded-2xl text-white flex flex-col md:flex-row items-center justify-center gap-10 md:gap-16 p-8 md:p-12 text-center md:text-left" style={{
  maxWidth: "1140px",
  background: "linear-gradient(135deg, #1a3a5c 0%, #176ACC 100%)"
}}>
      <div>
        <h2 className="text-2xl md:text-3xl font-semibold tracking-tight">{title}</h2>
        {subtitle && <div className="mt-3 text-blue-100 text-base">{subtitle}</div>}
      </div>
      <div className="flex flex-wrap gap-3 shrink-0 justify-center">
        {primaryCta && <a href={primaryHref} className="inline-flex items-center px-6 py-3 rounded-lg bg-white text-blue-700 font-semibold hover:bg-blue-50 transition whitespace-nowrap shadow-sm">
            {primaryCta}
          </a>}
        {secondaryCta && <a href={secondaryHref} className={`inline-flex items-center px-6 py-3 rounded-lg border border-blue-300/50 text-white font-semibold hover:bg-blue-700/30 transition whitespace-nowrap ${secondaryHref === "/request-demo" ? "demo-gradient-btn" : ""}`}>
            {secondaryCta}
          </a>}
      </div>
    </div>
  </section>;

export const FeatureCard = ({title, description, href, children}) => {
  const Tag = href ? "a" : "div";
  const tagProps = href ? {
    href
  } : {};
  return <Tag {...tagProps} className={`group flex flex-col p-6 rounded-xl border border-zinc-200 dark:border-zinc-700/60 bg-white dark:bg-zinc-800/50 ${href ? "hover:shadow-md hover:border-blue-200 dark:hover:border-blue-700 transition-all duration-200" : ""}`}>
      {children && <div className="feature-card-icon mb-5 flex items-center justify-center rounded-xl bg-blue-50 dark:bg-blue-900/20 border border-blue-100 dark:border-blue-800/30" style={{
    width: "4rem",
    height: "4rem"
  }}>
          {children}
        </div>}
      <h3 className={`text-lg font-semibold text-zinc-900 dark:text-white ${href ? "group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors" : ""}`}>
        {title}
      </h3>
      {description && <p className="feature-card-desc text-sm text-zinc-500 dark:text-zinc-400 leading-relaxed">{description}</p>}
    </Tag>;
};

export const FeatureGrid3 = ({children}) => <div className="marketing-grid-3">{children}</div>;

export const FeatureGrid2 = ({children}) => <div className="marketing-grid-2">{children}</div>;

export const SectionHeader = ({title, subtitle, centered = true, label}) => <div className={`mb-12 ${centered ? "text-center" : ""}`}>
    {label && <p className="text-xs font-semibold tracking-widest text-blue-600 dark:text-blue-400 uppercase mb-3">
        {label}
      </p>}
    <h2 className="text-4xl md:text-5xl font-semibold text-zinc-900 dark:text-white tracking-tight">{title}</h2>
    {subtitle && <div className={`subtitle-gap text-lg md:text-xl text-zinc-500 dark:text-zinc-300 leading-relaxed ${centered ? "mx-auto" : ""}`} style={{
  marginTop: "1rem",
  maxWidth: centered ? "700px" : "none"
}}>
        {subtitle}
      </div>}
  </div>;

export const Section = ({children, className = "", gray = false, dark = false, id}) => <section id={id} className={`w-full flex justify-center px-4 py-16 md:py-24 ${gray ? "bg-gray-50 dark:bg-zinc-900" : dark ? "bg-zinc-900 dark:bg-zinc-950" : ""} ${className}`}>
    <div className="w-full" style={{
  maxWidth: "1140px"
}}>
      {children}
    </div>
  </section>;

export const Hero = ({title, subtitle, badge, primaryCta, primaryHref = "#", secondaryCta, secondaryHref = "#", centered = true, children}) => <section className="w-full flex justify-center px-4 pt-16 pb-16 md:pt-24 md:pb-24" style={{
  background: "linear-gradient(180deg, var(--hero-gradient-start, #f8fafc) 0%, var(--hero-gradient-end, #ffffff) 100%)"
}}>
    <div className="w-full" style={{
  maxWidth: "1140px"
}}>
      {centered && !children ? <div className="flex flex-col items-center text-center">
          {badge && <div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 text-blue-700 dark:text-blue-300 text-sm font-medium mb-6">
              {badge}
            </div>}
          <h1 className="text-4xl md:text-5xl font-semibold text-zinc-900 dark:text-white leading-tight tracking-tight" style={{
  maxWidth: "820px"
}}>
            {String(title).split(/\\n|\n/).map((line, i) => i ? [<br key={i} />, line] : line)}
          </h1>
          {subtitle && <div className="subtitle-gap text-lg md:text-xl text-zinc-500 dark:text-zinc-300 leading-relaxed" style={{
  marginTop: "1rem",
  maxWidth: "600px"
}}>
              {subtitle}
            </div>}
          <div className="flex flex-wrap gap-3 mt-10 justify-center">
            {primaryCta && <a href={primaryHref} className="inline-flex items-center px-6 py-3 rounded-lg bg-blue-600 text-white font-semibold hover:bg-blue-700 transition shadow-sm">
                {primaryCta}
              </a>}
            {secondaryCta && <a href={secondaryHref} className={`inline-flex items-center px-6 py-3 rounded-lg border border-zinc-300 dark:border-zinc-600 text-zinc-700 dark:text-zinc-200 font-semibold hover:bg-zinc-50 dark:hover:bg-zinc-800 transition ${secondaryHref === "/request-demo" ? "demo-gradient-btn" : ""}`}>
                {secondaryCta}
              </a>}
          </div>
        </div> : <div className="flex flex-col md:flex-row items-center gap-10 md:gap-16">
          <div className="flex-1 min-w-0">
            {badge && <div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 text-blue-700 dark:text-blue-300 text-sm font-medium mb-6">
                {badge}
              </div>}
            <h1 className="text-4xl md:text-5xl font-semibold text-zinc-900 dark:text-white leading-tight tracking-tight">
            {String(title).split(/\\n|\n/).map((line, i) => i ? [<br key={i} />, line] : line)}
          </h1>
            {subtitle && <div className="subtitle-gap text-lg md:text-xl text-zinc-500 dark:text-zinc-300 leading-relaxed" style={{
  marginTop: "1rem"
}}>
                {subtitle}
              </div>}
            <div className="flex flex-wrap gap-3 mt-8">
              {primaryCta && <a href={primaryHref} className="inline-flex items-center px-6 py-3 rounded-lg bg-blue-600 text-white font-semibold hover:bg-blue-700 transition shadow-sm">
                  {primaryCta}
                </a>}
              {secondaryCta && <a href={secondaryHref} className={`inline-flex items-center px-6 py-3 rounded-lg border border-zinc-300 dark:border-zinc-600 text-zinc-700 dark:text-zinc-200 font-semibold hover:bg-zinc-50 dark:hover:bg-zinc-800 transition ${secondaryHref === "/request-demo" ? "demo-gradient-btn" : ""}`}>
                  {secondaryCta}
                </a>}
            </div>
          </div>
          {children && <div className="flex-1 min-w-0 hero-image">
              {children}
            </div>}
        </div>}
    </div>
  </section>;

<MarketingPage />

<Hero title="Aspect CLI: the task runner for Bazel" subtitle="A free, open-source task runner that extends Bazel with first-class developer workflows. Replace the pile of shell scripts and CI YAML with tasks that run identically on every laptop and every CI provider. Apache 2.0, no account required." primaryCta="Install in minutes" primaryHref="/quickstart" secondaryCta="Read the docs" secondaryHref="/docs/cli/overview" centered={false} />

<Section gray>
  <div className="max-w-3xl mx-auto text-center space-y-6">
    <div className="h-px bg-zinc-300 dark:bg-zinc-600 w-full" />

    <p className="text-lg text-zinc-700 dark:text-zinc-300 italic leading-relaxed">
      Bazel is a build system, not a developer-workflow tool. Every Bazel monorepo eventually grows the same pile of bespoke shell scripts and CI YAML: format pre-submits, lint enforcement, BUILD-file generation, release delivery. Each is written in a different language, breaks differently, and behaves differently in CI versus on a laptop.
    </p>

    <p className="text-lg text-zinc-700 dark:text-zinc-300 italic leading-relaxed">
      The Aspect CLI replaces that pile with a single task runner you program in Starlark, the same language you already use for your BUILD files.
    </p>

    <div className="h-px bg-zinc-300 dark:bg-zinc-600 w-full" />
  </div>
</Section>

<Section>
  <SectionHeader title="Why developers adopt it" />

  <FeatureGrid2>
    <FeatureCard title="Zero adoption cost" description="aspect build, test, and run work in any Bazel workspace with no config. Your existing bazel workflow keeps working alongside.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/rocket.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=aad2842e33767a3adfda39f90f336298" alt="" width="48" height="49" data-path="images/marketing/icons/rocket.svg" />
    </FeatureCard>

    <FeatureCard title="One language for everything" description="Configure the CLI and write custom tasks in Starlark via AXL. No new YAML schema, no new template language.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Extension.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=3239bb28f38ff4a7e9d06bace830bac7" alt="" width="32" height="32" data-path="images/marketing/icons/Extension.svg" />
    </FeatureCard>

    <FeatureCard title="Same command in every environment" description="aspect lint does the same thing on a laptop as in CI. Eliminates an entire class of works-on-my-machine bugs.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/customizable.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=1aa79204a9a6914dce58770845dd5de7" alt="" width="48" height="48" data-path="images/marketing/icons/customizable.svg" />
    </FeatureCard>

    <FeatureCard title="Open source, no lock-in" description="Apache 2.0 licensed. Your Bazel build never depends on it to keep working.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/open-source.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=8be03fe9577fdc3ec8ddb2838834dd99" alt="" width="48" height="48" data-path="images/marketing/icons/open-source.svg" />
    </FeatureCard>
  </FeatureGrid2>
</Section>

<Section gray>
  <SectionHeader title="Built-in tasks" subtitle="The patterns every Bazel monorepo eventually re-invents, shipped out of the box and working on any CI provider." />

  <FeatureGrid3>
    <FeatureCard title="aspect format" description="Format only the files changed in the PR." href="/docs/cli/tasks/format" />

    <FeatureCard title="aspect lint" description="Hold-the-line linting that only fails on violations you introduced." href="/docs/cli/tasks/lint" />

    <FeatureCard title="aspect gazelle" description="Generate and sync BUILD files automatically." href="/docs/cli/tasks/gazelle" />

    <FeatureCard title="aspect delivery" description="Deliver only targets whose outputs actually changed." href="/docs/cli/tasks/delivery" />

    <FeatureCard title="aspect build & test" description="Build and test with retry on transient errors, BES streaming, coverage, and test-log upload." href="/docs/cli/tasks/build_test" />

    <FeatureCard title="Custom tasks" description="Write your own tasks in Starlark. They run identically on every laptop and CI provider." href="/docs/cli/tasks" />
  </FeatureGrid3>

  <p className="mt-8 text-center text-sm text-zinc-500 dark:text-zinc-400">
    Native integration with GitHub Status Checks and PR comments, GitLab job annotations and MR comments, Buildkite Annotations, and the equivalent on CircleCI.
  </p>
</Section>

<Section dark id="installation">
  <div className="text-center">
    <h2 className="text-3xl md:text-4xl font-semibold text-white">Install in one command</h2>
    <p className="mt-4 text-zinc-300">Works on macOS and Linux. Your existing bazel workflow keeps working alongside.</p>

    <div className="mt-6 max-w-xl mx-auto text-left">
      ```shell theme={null}
      curl -fsSL https://install.aspect.build | bash
      ```
    </div>

    <div className="mt-6">
      <a href="/quickstart" className="text-blue-400 font-semibold hover:underline">
        Follow the 10-minute quickstart →
      </a>
    </div>
  </div>
</Section>

<Section>
  <SectionHeader title="Fit Bazel to your organization" subtitle="Every organization has a different engineering culture and developer stack. Custom tasks let you encode your team's workflows: stamp out new projects following local conventions, add commands for deploying or rebasing, and point error messages at your internal documentation." />

  <div className="flex justify-center">
    <a href="/docs/cli/guides/basic" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">
      Writing custom tasks →
    </a>
  </div>
</Section>

<CTA title="Try the Aspect CLI today" subtitle="Free, open source, and installed in minutes. When you want fast CI to match, Aspect Workflows is ready." primaryCta="Install the CLI" primaryHref="/quickstart" secondaryCta="Explore Aspect Workflows" secondaryHref="/platform" />
