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

# BUILD File Generation with aspect gazelle

> Generate and sync Bazel BUILD files automatically with aspect gazelle: incremental runs for monorepo scale, drift detection in CI, and custom Gazelle extensions 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 FeatureGrid2 = ({children}) => <div className="marketing-grid-2">{children}</div>;

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="BUILD File Generation" subtitle="Generate and sync Bazel BUILD files automatically with the aspect gazelle task, built into the free Aspect CLI. Drift fails CI before it accumulates, fixes apply themselves locally, and you extend it for your own conventions in Starlark." primaryCta="Install the Free CLI" primaryHref="/docs/cli/install" secondaryCta="Read the Docs" secondaryHref="/docs/cli/tasks/gazelle" 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">
      Writing BUILD files by hand requires every engineer to learn Bazel's configuration language, and hand-written files drift out of sync the moment someone adds an import and forgets the dep.
    </p>

    <p className="text-lg text-zinc-700 dark:text-zinc-300 italic leading-relaxed">
      Your source code already declares its dependencies. BUILD files should be generated from it, checked in CI, and fixed with one command.
    </p>

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

<Section>
  <div className="flex flex-col md:flex-row items-start gap-12">
    <div className="flex-1">
      <p className="text-xs font-semibold tracking-widest text-blue-600 dark:text-blue-400 uppercase mb-3">The aspect gazelle task</p>
      <h2 className="text-3xl md:text-4xl font-semibold text-zinc-900 dark:text-white">Drift fails CI. Fixes apply themselves.</h2>

      <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-300">
        The <code>aspect gazelle</code> task runs Gazelle over your repository and adapts to where it runs. In CI it detects whether BUILD files are out of sync with source code and fails the step if so, preventing drift before it accumulates into a bigger cleanup. On a developer machine, the same command applies the fixes in place.
      </p>

      <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-300">
        One Gazelle invocation produces both the verdict and the patch, so even the CI check stays fast on a large monorepo.
      </p>

      <div className="mt-6">
        <a href="/docs/cli/tasks/gazelle" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">
          The aspect gazelle task →
        </a>
      </div>
    </div>

    <div className="flex-1 w-full min-w-0">
      ```shell theme={null}
      # On a laptop: writes the fixes in place
      aspect gazelle

      # In CI: fails the job if BUILD files are out of sync
      aspect gazelle --check-only
      ```
    </div>
  </div>
</Section>

<Section gray>
  <SectionHeader title="Built for monorepo scale" subtitle="Running BUILD generation over millions of lines on every PR is the naive way. The aspect gazelle task, built into the free Aspect CLI, is smarter." />

  <FeatureGrid3>
    <FeatureCard title="Incremental by scope" description="Restrict generation to directories containing changed files with --scope=changed, instead of re-walking the whole tree on every pull request." href="/docs/cli/tasks/gazelle">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/filters.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=291b4db68d69e6a8e7cd83b45b61837f" alt="" width="48" height="49" data-path="images/marketing/icons/filters.svg" />
    </FeatureCard>

    <FeatureCard title="Smart escalation" description="Changes that can affect resolution repo-wide, like MODULE.bazel or go.sum, automatically escalate to a full run. You configure which patterns trigger it." href="/docs/cli/tasks/gazelle">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/marketing/icons/alert.svg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=b94eb68321eeb5fc8c9b592045a2858a" alt="" width="24" height="24" data-path="images/marketing/icons/alert.svg" />
    </FeatureCard>

    <FeatureCard title="Single-run drift detection" description="Gazelle runs once in diff mode, and the task gets both the answer and the patch from that one run. No double execution to check and then fix." href="/docs/cli/tasks/gazelle">
      <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>
  <div className="flex flex-col md:flex-row items-center gap-12">
    <div className="flex-1">
      <p className="text-xs font-semibold tracking-widest text-blue-600 dark:text-blue-400 uppercase mb-3">The aspect-gazelle open source project</p>
      <h2 className="text-3xl md:text-4xl font-semibold text-zinc-900 dark:text-white">Extensions in Starlark, not Go</h2>

      <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-300">
        Gazelle is the standard tool for generating BUILD files, but extending it means learning its Go API and adding a compile-time dependency for your developers. With the Aspect Extension Language (AXL), you write Gazelle extensions in Starlark instead: declare the rule kinds you generate, tell Gazelle what to look for in source files, and write the logic that produces targets.
      </p>

      <p className="mt-4 text-lg text-zinc-600 dark:text-zinc-300">
        Extensions are short, live in your repo next to the code they generate for, and need no compilation. They run on <a href="https://github.com/aspect-build/aspect-gazelle" target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">aspect-gazelle</a>, our open source Gazelle distribution: prebuilt binaries bundling the language plugins and the Starlark extension host, plus quality-of-life upgrades stock Gazelle lacks, like gitignore support, file-based caching, and a watch mode powered by Watchman. The aspect gazelle task runs it for you; you can also run it standalone.
      </p>

      <div className="mt-6">
        <a href="/docs/cli/guides/gazelle" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">
          How to extend Gazelle in Starlark →
        </a>
      </div>
    </div>

    <div className="flex-1 w-full min-w-0">
      ```python title="oci_image.axl" theme={null}
      def declare_targets(ctx):
          for file in ctx.sources:
              if len(file.query_results["has_main"]) > 0:
                  ctx.targets.add(
                      name = "image",
                      kind = "go_image",
                      attrs = {
                          "binary": path.base(ctx.rel),
                      },
                  )
      ```
    </div>
  </div>
</Section>

<Section gray>
  <SectionHeader title="Batteries included" subtitle="The aspect-gazelle prebuilt binaries ship BUILD generation for these ecosystems out of the box. Custom Starlark generators cover everything else, including your internal macros and conventions." />

  <div className="flex flex-wrap justify-center gap-3 max-w-2xl mx-auto">
    <span className="px-5 py-2.5 rounded-full bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-200 font-semibold">Python</span>
    <span className="px-5 py-2.5 rounded-full bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-200 font-semibold">JavaScript & TypeScript</span>
    <span className="px-5 py-2.5 rounded-full bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-200 font-semibold">Go</span>
    <span className="px-5 py-2.5 rounded-full bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-200 font-semibold">Protobuf</span>
    <span className="px-5 py-2.5 rounded-full bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-200 font-semibold">C & C++</span>
    <span className="px-5 py-2.5 rounded-full bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-200 font-semibold">Starlark</span>
  </div>
</Section>

<CTA title="Generate your BUILD files today" subtitle="aspect gazelle is part of the free, open source Aspect CLI." primaryCta="Install the Free CLI" primaryHref="/docs/cli/install" secondaryCta="Talk with Us" secondaryHref="/contact" />
