Learning Astro - Extensibility & Custom Integrations
Episode 18 of 24

Learning Astro - Extensibility & Custom Integrations

This episode covers Astro extensibility: writing custom integrations and plugins, using third-party libraries and frameworks, extending the build pipeline with custom scripts, and interoperability across the frontend ecosystem.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Every framework has limits, and what distinguishes a great framework is how easy it is to extend those limits. Episode 18 covers Astro extensibility: writing custom integrations, using third-party libraries, extending the build pipeline, and connecting different frontend ecosystems.

You will learn that Astro integrations are not magic — they are plain JavaScript objects with hooks that run at specific moments in the build lifecycle. Understanding this opens the door to automating much of what you previously did by hand.

By the end of the episode, you can write your own integrations and hook any tool into an Astro project.

Custom Astro Integrations and Plugins

The Anatomy of an Integration

An Astro integration is an object with hooks functions called at specific times: astro:config:setup, astro:config:done, and astro:build:done. Example of a simple integration that injects a script into every page:

JSIntegrasi kustom sederhana
import type { AstroIntegration } from "astro";
 
export function sapaPengunjung(): AstroIntegration {
  return {
    name: "sapa-pengunjung",
    hooks: {
      "astro:config:done": ({ injectScript }) => {
        injectScript(
          "page",
          `console.log("Selamat datang di situs ini!");`,
        );
      },
    },
  };
}

The injectScript("page", ...) function injects code into the page. This integration just needs to be added to the integrations array in astro.config.mjs to become active.

When to Write Your Own Integration

Write a custom integration when the need is recurring and reusable across many projects: adding automatic meta tags, transforming build output, or integrating an analytics service. For one-off needs, a plain script is enough.

Using Third-Party Frameworks and Libraries

Using npm Packages Directly

Plain JavaScript libraries can be used directly in frontmatter or in src/lib. Because Astro uses Vite, almost any browser-compatible npm package works without configuration:

Memasang library Date
npm install date-fns

Then use it in a page:

JSMemakai library di frontmatter
---
import { format } from "date-fns";
import { id } from "date-fns/locale";
 
const tanggal = format(new Date(), "d MMMM yyyy", { locale: id });
---
 
<p>Hari ini: {tanggal}</p>

format(new Date(), "d MMMM yyyy", { locale: id }) uses date-fns to format the date in Indonesian — everything runs at build time.

Components from Other Frameworks

The React, Vue, Svelte, and Solid integrations (episode 7) are the prime examples of interoperability. You can also load UI components from any design system as long as they are converted or wrapped into a supported form.

Extending the Build Pipeline with Custom Scripts

Scripts in package.json

Custom scripts are added to package.json and can be chained with the build command:

Script kustom di package.json
{
  "scripts": {
    "build": "astro build && node scripts/gen-sitemap-ekstra.mjs",
    "prerender": "node scripts/prerender.mjs"
  }
}

The command astro build && node scripts/gen-sitemap-ekstra.mjs runs the build then produces an extra file. This approach is flexible for needs that integrations do not handle.

The astro:build:done Hook

For full access to the build result, use the astro:build:done hook inside an integration. This hook receives the list of generated pages — perfect for reports, validation, or output transformation:

JSHook astro:build:done
"astro:build:done": ({ pages }) => {
  console.log(`Total halaman yang dibangun: ${pages.length}`);
}

pages contains all generated routes. You can write a build summary to a file or validate that important pages actually exist.

Interoperability Across Frontend Ecosystems

One Project, Many Technologies

A frequently underestimated Astro strength: different frontend teams can live in one project. Team A uses React for the dashboard, team B uses Svelte for widgets — both are rendered by Astro with separate hydration.

Patterns for Healthy Integrations

So integrations do not turn into spaghetti:

  • Create one clear directory per framework, for example src/components/react and src/components/svelte.
  • Limit cross-framework communication through simple props and events.
  • Document where each framework is used and why.

Interoperability is a strength, but clear boundaries keep it maintainable.

Tip

Before writing your own integration, check npm first — @astrojs/* and community packages may already provide what you need. Write custom code only for needs with no existing solution.

Conclusion

Episode 18 opens up Astro extensibility: writing custom integrations with hooks like injectScript and astro:build:done, using npm libraries directly, extending the build pipeline with custom scripts, and maintaining cross-framework interoperability.

The key takeaways:

  • An Astro integration is an object with hooks at specific build moments.
  • injectScript injects code into pages from an integration.
  • npm libraries work directly because Astro uses Vite.
  • Custom scripts can be chained with && in package.json.
  • astro:build:done gives access to the build result.
  • Limit cross-framework communication to keep things maintainable.

In the next episode 19, we will cover modern tooling and build automation: the Astro CLI and Vite, TypeScript integration with strict typing, CI/CD pipelines for Astro projects, and linting, formatting, and pre-commit hooks. Your quality will be maintained automatically.

Learning Astro - Extensibility & Custom Integrations | Learning Astro