> ## 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.

# Extend Bazel with AXL, the Aspect Extension Language

> Write Bazel tasks in AXL, a Starlark dialect, and run them identically on laptops and CI. Free with the Aspect CLI, with built-in format, lint, and delivery tasks.

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 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 Extension Language" subtitle="AXL is how you make Bazel do what your team needs. Write tasks in Starlark, the language you already know from BUILD files, and run them identically everywhere with the free Aspect CLI: laptops, GitHub Actions, CircleCI, GitLab, and Buildkite." primaryCta="Get Started Free" primaryHref="/docs/cli/install" secondaryCta="Read the Docs" secondaryHref="/docs/cli/guides/basic" centered={false}>
  <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/product/axl-img.avif?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=1ba18616087f5f7414073fc3bbc50ceb" alt="Aspect Extension Language" width="1292" height="720" data-path="images/marketing/product/axl-img.avif" />
</Hero>

<Section>
  <SectionHeader title="Why AXL" />

  <div className="max-w-2xl mx-auto text-center space-y-4 mb-12">
    <p className="text-lg font-semibold text-zinc-700 dark:text-zinc-300">
      Bazel is fast, scalable, and battle-tested in the enterprise.
    </p>

    <p className="text-lg text-zinc-600 dark:text-zinc-300">
      But anyone who's used it knows: some important workflows are missing, awkward, or just not adapted to your organization. So teams bury them in shell scripts and Makefiles that drift, break, and behave differently on every machine.
    </p>

    <p className="text-lg font-semibold text-zinc-700 dark:text-zinc-300">
      The usual suspects:
    </p>
  </div>

  <FeatureGrid3>
    <FeatureCard title="Formatting" description="One command that formats every language in the repo, the same way on every machine." href="/docs/cli/tasks/format">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Formatting.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=e5951ee7e92fe23b8eb79b0d2c96af93" alt="" width="48" height="48" data-path="images/marketing/icons/Formatting.svg" />
    </FeatureCard>

    <FeatureCard title="Linting" description="Run every configured linter across the build graph, with machine-applicable fixes." href="/docs/cli/tasks/lint">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Linting.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=3bfc20666b4b77e26bb1027a52d6075c" alt="" width="48" height="48" data-path="images/marketing/icons/Linting.svg" />
    </FeatureCard>

    <FeatureCard title="Release automation" description="Stamp artifacts, detect what changed, and push only that. Scripted release trains become one task." href="/docs/cli/tasks/delivery">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Release-automation.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=fe6347df8f3a3ea7edf4ddff8d6716fc" alt="" width="48" height="48" data-path="images/marketing/icons/Release-automation.svg" />
    </FeatureCard>

    <FeatureCard title="Test reporting" description="Status checks and annotations on your CI provider instead of scrolling raw logs." href="/docs/cli/tasks-ci">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Test-reporting.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=645b8801b1504d458c831a6ec036ec59" alt="" width="48" height="48" data-path="images/marketing/icons/Test-reporting.svg" />
    </FeatureCard>

    <FeatureCard title="Coverage" description="Collect coverage across languages and publish it where your team actually looks.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Coverage.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=306ae317088aaa2ae5630a60ec44bdba" alt="" width="48" height="48" data-path="images/marketing/icons/Coverage.svg" />
    </FeatureCard>

    <FeatureCard title="Documentation" description="Generate and publish docs from the build graph as part of the same workflow.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Documentation.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=06dde831b9dc258ec192c68dee586094" alt="" width="48" height="48" data-path="images/marketing/icons/Documentation.svg" />
    </FeatureCard>
  </FeatureGrid3>

  <div className="max-w-2xl mx-auto text-center space-y-4 mt-12">
    <p className="text-lg text-zinc-600 dark:text-zinc-300">
      AXL replaces that scripting layer with tasks: first-class, programmable commands that ship with the <a href="/platform/cli" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">Aspect CLI</a> or are written by your team, in one language, with Bazel's APIs at hand.
    </p>
  </div>
</Section>

<Section gray>
  <SectionHeader title="A dialect of Starlark" subtitle="AXL is the same language Bazel itself is configured in. That means extensions are:" />

  <FeatureGrid3>
    <FeatureCard title="Familiar" description="If you've ever read a BUILD file or a Bazel rule, AXL is readable on day one. No new language to learn, no plugin SDK to master.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/puzzle.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=d7988f951af9de3713bb62f795bc3da2" alt="" width="40" height="40" data-path="images/marketing/icons/puzzle.svg" />
    </FeatureCard>

    <FeatureCard title="Safe and deterministic" description="No hidden side effects, no unbounded execution. Tasks behave the same on a laptop as they do in CI.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/protect.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=af5818d5725923799e54382c188d5256" alt="" width="40" height="40" data-path="images/marketing/icons/protect.svg" />
    </FeatureCard>

    <FeatureCard title="Composable" description="Tasks drive Bazel's build, test, and query APIs directly, and share code across repositories as versioned AXL modules.">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/chain.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=eb48ca77026766b251216ae33176625f" alt="" width="40" height="40" data-path="images/marketing/icons/chain.svg" />
    </FeatureCard>
  </FeatureGrid3>
</Section>

<Section>
  <SectionHeader title="Batteries included" subtitle="The Aspect CLI ships with built-in tasks, themselves written against the same AXL machinery. Customize any of them in .aspect/config.axl, or use them as-is." />

  <FeatureGrid3>
    <FeatureCard title="aspect build & test" description="Bazel build and test with CI status checks, artifact upload, and build event streaming wired in." href="/docs/cli/tasks/build_test">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Build_1.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=21cbc19b2d6e86104cc5db65b8f643df" alt="" width="32" height="32" data-path="images/marketing/icons/Build_1.svg" />
    </FeatureCard>

    <FeatureCard title="aspect format" description="Format every language from one command. Opt into aspect buildifier for Starlark with a one-line alias." href="/docs/cli/tasks/format">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Formatting.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=e5951ee7e92fe23b8eb79b0d2c96af93" alt="" width="48" height="48" data-path="images/marketing/icons/Formatting.svg" />
    </FeatureCard>

    <FeatureCard title="aspect lint" description="Run all configured linters, with suggested fixes that surface on pull requests and merge requests." href="/docs/cli/tasks/lint">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Linting.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=3bfc20666b4b77e26bb1027a52d6075c" alt="" width="48" height="48" data-path="images/marketing/icons/Linting.svg" />
    </FeatureCard>

    <FeatureCard title="aspect gazelle" description="Generate and sync BUILD files from your source code." href="/docs/cli/tasks/gazelle">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Build_1.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=21cbc19b2d6e86104cc5db65b8f643df" alt="" width="32" height="32" data-path="images/marketing/icons/Build_1.svg" />
    </FeatureCard>

    <FeatureCard title="aspect delivery" description="Selective Delivery: stamp artifacts and push only the targets whose outputs actually changed." href="/docs/cli/tasks/delivery">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Release-automation.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=fe6347df8f3a3ea7edf4ddff8d6716fc" alt="" width="48" height="48" data-path="images/marketing/icons/Release-automation.svg" />
    </FeatureCard>

    <FeatureCard title="aspect run" description="Build a target and run the resulting binary, with the same task ergonomics as everything else." href="/docs/cli/tasks/run">
      <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>
  </FeatureGrid3>

  <div className="max-w-2xl mx-auto text-center mt-10">
    <a href="/docs/cli/tasks" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">
      Browse the full task reference →
    </a>
  </div>
</Section>

<Section gray>
  <div className="flex flex-col md:flex-row items-start gap-12">
    <div className="flex-1">
      <h2 className="text-3xl md:text-4xl font-semibold text-zinc-900 dark:text-white">Write your own in minutes</h2>

      <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-300">
        A custom task is a Starlark function. Drop an <code>.axl</code> file into your repo's <code>.aspect/</code> directory and it auto-registers as a real CLI command, listed in <code>aspect help</code> next to the built-ins.
      </p>

      <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-300">
        Tasks get typed arguments, Bazel's build and query engines, build event streams, and a standard library. No wrapper scripts, no YAML contortions.
      </p>

      <div className="mt-8 flex flex-col gap-3">
        <a href="/docs/cli/guides/basic" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">Write your first task →</a>
        <a href="/docs/cli/guides/module" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">Share tasks across repos with MODULE.aspect →</a>
        <a href="/docs/cli/guides/build-events" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">React to build events →</a>
        <a href="/docs/cli/guides/delivery-manifest" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">Hook the delivery manifest →</a>
      </div>
    </div>

    <div className="flex-1 w-full min-w-0">
      ```python title=".aspect/mycmd.axl" theme={null}
      def impl(ctx: TaskContext) -> int:
          events = bazel.build_events.iterator()
          build = ctx.bazel.build(
              build_events = [events],
              *ctx.args.target_pattern,
          )

          for event in events:
              if event.kind == "named_set_of_files":
                  for f in event.payload.files:
                      ctx.std.io.stdout.write("Built {}\n".format(f.name))

          return build.wait().code

      mycmd = task(
          implementation = impl,
          args = {
              "target_pattern": args.positional(default = ["..."]),
          },
      )
      ```

      <p className="mt-3 text-sm text-zinc-500 dark:text-zinc-400 text-center font-mono">\$ aspect mycmd //services/...</p>
    </div>
  </div>
</Section>

<Section>
  <SectionHeader title="The same task, everywhere" subtitle="aspect <task> behaves identically on a developer laptop and in your CI pipeline. No CI-specific wrappers to maintain." />

  <FeatureGrid3>
    <FeatureCard title="Any CI system" description="Invoke tasks from plain CI YAML on GitHub Actions, CircleCI, GitLab, or Buildkite. The CLI detects the CI environment and adapts." href="/docs/cli/tasks-ci">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/integrations.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=773ccf480cdd92e597ae8aeb794d7a8d" alt="" width="32" height="32" data-path="images/marketing/icons/integrations.svg" />
    </FeatureCard>

    <FeatureCard title="CI-aware by default" description="Set one API token to unlock GitHub status checks, Buildkite annotations, and GitLab job annotations. Without it, tasks still run normally." href="/docs/cli/tasks-ci">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/Test-reporting.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=645b8801b1504d458c831a6ec036ec59" alt="" width="48" height="48" data-path="images/marketing/icons/Test-reporting.svg" />
    </FeatureCard>

    <FeatureCard title="Supercharged on Workflows" description="On Aspect Workflows runners, tasks auto-detect the environment and configure remote caching, remote execution, and pre-warmed NVMe output bases." href="/platform/ci-runners">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/fast.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=a631c8f2127105e4112db8e0a4ccc641" alt="" width="48" height="49" data-path="images/marketing/icons/fast.svg" />
    </FeatureCard>
  </FeatureGrid3>
</Section>

<Section gray>
  <div className="flex flex-col md:flex-row items-center gap-12">
    <div className="flex-1">
      <h2 className="text-3xl md:text-4xl font-semibold text-zinc-900 dark:text-white">Marvin Saves the BUILD</h2>

      <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-300">
        In Marvin Saves the BUILD, read how Nina, Perry, and Ivan replace a sprawl of local dev and CI scripts with AXL to manage tasks in a programmable, maintainable command-line interface (Aspect CLI).
      </p>

      <div className="mt-8">
        <a href="https://cdn.aspect.build/documents/Marvin-Saves-the-BUILD.pdf" target="_blank" rel="noopener noreferrer" 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">
          Download the PDF →
        </a>
      </div>
    </div>

    <div className="flex-1">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/product/book-cover.avif?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=15b276b9f12ddbdeb5fb2db038315d9c" alt="Marvin Saves the BUILD book cover" className="w-full rounded-xl shadow-lg border border-zinc-200 dark:border-zinc-700" width="1655" height="1083" data-path="images/marketing/product/book-cover.avif" />
    </div>
  </div>
</Section>

<CTA title="Extend Bazel with AXL" subtitle="AXL ships with the Aspect CLI, free for every developer." primaryCta="Install the Free CLI" primaryHref="/docs/cli/install" secondaryCta="Talk with Us" secondaryHref="/contact" />
