Astro sites deploy to Netlify by leveraging Netlify’s build system and hosting capabilities, but the real magic is how Astro’s islands architecture minimizes client-side JavaScript, making those Netlify deployments incredibly fast.

Let’s see Astro in action. Imagine a simple blog post component in Astro.

---
const { title, date } = Astro.props;
const formattedDate = new Date(date).toLocaleDateString('en-US', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
});
---

<article>
  <h1>{title}</h1>
  <p>Published on: {formattedDate}</p>
  <slot />
</article>

When this Astro site is deployed to Netlify, Netlify’s build process kicks off. Netlify fetches your Astro code, installs dependencies (like npm install), and then runs the Astro build command, usually npm run build. Astro then takes this component, renders it into static HTML on the server, and crucially, doesn’t ship the JavaScript for this component to the browser by default. Only if you explicitly add client-side interactivity (e.g., using client:load, client:idle, client:visible) will Astro generate the necessary JavaScript just for that component. Netlify then takes these static HTML files and deploys them to its global CDN.

The core problem Astro solves is the "JavaScript bloat" common in modern web frameworks. Traditional frameworks often send a large chunk of JavaScript to the browser that hydrates the entire page, even parts that don’t change. Astro’s "islands" architecture breaks the UI into smaller, independent components. Each island can be rendered to HTML on the server, and only the specific islands that need client-side JavaScript will have it sent. This means your Netlify deployment is serving mostly static HTML, which is blazingly fast to download and render.

Here’s how you configure a Netlify deployment for Astro. You’ll typically have a netlify.toml file in your project root:

[build]
  command = "npm run build"
  publish = "dist"

[functions]
  node_bundler = "esbuild"
  • command = "npm run build": This tells Netlify to run your Astro build process. Astro’s build script in package.json is configured to generate static HTML, CSS, and any necessary JavaScript.
  • publish = "dist": This specifies that the output of the build command (the static assets) will be found in the dist directory. Netlify will serve files from this directory.
  • [functions]: If your Astro site includes serverless functions (e.g., for form submissions or API endpoints), this section configures how Netlify bundles them. esbuild is a fast and efficient bundler for Node.js.

Beyond the static HTML generation, Astro allows for "partial hydration." This is where you can opt-in specific components to run JavaScript in the browser. For example, if you had a client-side counter component:

---
import { useState } from 'preact/hooks';

let count = 0;
---
<button onClick={() => count++}>
  Count: {count}
</button>

To make this interactive, you’d add a directive:

---
import { useState } from 'preact/hooks';

let count = 0;
---
<button onClick={() => count++} client:load>
  Count: {count}
</button>

The client:load directive tells Astro to include the necessary JavaScript for this useState hook and the onClick handler in the final build. This JavaScript will be fetched and executed as soon as the page loads. Other directives like client:idle (runs when the browser is idle) or client:visible (runs when the component scrolls into view) offer fine-grained control over when JavaScript is delivered and executed, further optimizing performance on Netlify.

The beauty of Astro’s island architecture is that it allows you to use your preferred UI frameworks (React, Vue, Svelte, Preact, etc.) within the same Astro project, and each framework component is treated as a potential island. Astro will render it to HTML server-side and only hydrate it if explicitly instructed. This means you can build complex, interactive applications while still benefiting from the static-first performance characteristics that Netlify excels at serving.

What many developers don’t realize is that Astro’s default behavior is to send zero JavaScript to the client for components that don’t have explicit client-side directives. This isn’t just about less JavaScript; it’s about selective JavaScript. Astro’s compiler analyzes your components and determines which ones require client-side execution based on directives like client:load, client:idle, client:visible, client:media, or client:only. For components that are purely static (like our blog post example), no JavaScript is bundled or sent to the browser at all, leading to significantly smaller initial page loads and faster Time To Interactive (TTI) metrics on Netlify.

The next step after deploying is optimizing your Astro site’s build output for even faster Netlify deployments.

Want structured learning?

Take the full Netlify course →