Cover for article Astro: The blazing fast web framework

Astro: The blazing fast web framework

This brand-new web framework caught my attention, and I plan to use it for my future static website.

Last modified: 2025/03/01 03:00 PM

Created at: 2025/03/01

astro
website
framework
frontend

It all happened on the day I started wondering how I could build my personal website.

Pulling one template from GitHub surely does the job, but it will look identical to others’ websites. Using only HTML surely works, but its downside is you will need to improve your website’s performance by yourself. Making the whole development way too focused on performance improvement. The webpage can also be tough to maintenance as your website grows.

Framework?

So surely I need a web framework to do these works for me. I pulled up my rusty frontend development knowledge, thinking what framework I should use.

Next.js

The first framework is Next.js, which is ideal for building a full-stack website.

With React’s huge ecosystem, Next.js got a nearly perfect score in my mind. That’s why I considered Next.js first when I was trying to start my website at that time.

A good thing always comes with a downside. For example, without SSR (server-side rendering), the website does not work with JavaScript disabled; the bundled runtime Next.js and React ship to the user is relatively large compared to pure HTML.

Vue.js

The Second is Vue.js, as the name described, also requires JavaScript to do client-side rendering. And Vue’s syntax is not appealing to me. <script setup> ? kinda weird, ain’t it?

Angular… does anyone actually use it?

Well well well Angular, long time no see, isn’t it? Angular seems got a good reputation in front-end development before, not sure how it’s doing recently.

I decided to check it out by looking into Angular’s official website. But this example code lets me think for a while before I start digging into it…

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <label for="name">Name:</label>
    <input type="text" id="name" [(ngModel)]="name" placeholder="Enter a name here" />
    <hr />
    <h1>Hello {{ name }}!</h1>
  `,
  imports: [FormsModule],
})
export class DemoComponent {
  name = '';
}

bootstrapApplication(DemoComponent);

Not sure how you think about this snippet, I think it’s even worse than Vue does.

Astro

And I ran into Astro. Some cool bleeding-edge Reddit users said, “Hell yeah, Astro, it’s blazing fast. You gotta try it out.” Again, I opened Astro’s official website and took a look. Here’s a small code snippet about the index page of a starter template.

---
import '../styles/global.css';
// Component Imports
import Button from '../components/Button.astro';

// Full Astro Component Syntax:
// https://docs.astro.build/basics/astro-components/
---

<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="generator" content={Astro.generator} />
		<title>Astro + TailwindCSS</title>
	</head>

	<body>
		<div class="grid place-items-center h-screen content-center">
			<Button>Tailwind Button in Astro!</Button>
			<a href="/markdown-page" class="p-4 underline">Markdown is also supported...</a>
		</div>
	</body>
</html>

Hold up, I’m looking at HTML or a fully fledged web framework’s syntax? This simple syntax immediately got me, making me want to try it out.

Brief stop at here, why I think users without JavaScript is so important?

First, most websites relying on JavaScript tend to use more computer resources. Second, a browser that enforces a higher level of security (e.g., Tor browser) will block JavaScript most of the time.

I want to make my website accessible to everyone, including the people who don’t have a good connection speed, who have a slower smartphone.

There is also a plan to make my website sounds better for blind people, I’m still working on that.

Digging into Astro

After deciding to be an astronaut, I initialized a website repository using Astro with the following command:

pnpm create astro@latest

Then add TailwindCSS into my project:

pnpm astro add tailwind

Note that TailwindCSS v4 changed how styles work on the webpage. Please check out Astro & TailwindCSS’s documentation for more information.

And I just started writing my website. Astro’s intuitive syntax is really easy to understand if you previously have written a HTML website before. The framework island is also a great feature if you have existing code that uses React.

Astronaut’s problem

The JavaScript

Since Astro does not ship JavaScript to user by default, writing an interactive webpage using Astro is not ideal. For example, there is no state management like React does. Take my navigation bar as an example:

Here’s what the code will look like when using React:

const [scroll, setScroll] = useState(false);

window.addEventListener("scroll", (event) => {
  // some condition at here
  setScroll(true);
});

return (
  <nav class={twMerge("some-default-style", scroll && "some-special-style")}>
    {/* ...Something else... */}
  </nav>
);

But if I use Astro, which ships with vanilla JavaScript with almost no modification from the framework.

<nav class="some-default-style" id="nav">
  {/* ..Something else... */}
</nav>

<script>
  window.addEventListener("scroll", (event) => {
    // some condition at here
    document.getElementById("nav").classList.add("special-style");
    // else
    document.getElementById("nav").classList.remove("special-style");
  }
</script>

At first, it may seem useful because it doesn’t apply extra rules from the framework but is relatively inconvenient when writing lots of animations that require pulling and putting classes. This made Astro inconvenient when writing interactive website. You have been warned.

Image optimization

Astro’s built in astro:assets modules does provide some image optimization, like compressing images when building static output, adding extra properties to img tag to improve accessibility.

But Astro doesn’t provide a necessary (at least for me) feature: providing multiple srcset depending on different screen size. I have to write a custom OptimizePicture component that generates multiple widths property, a property that Image components from astro:assets supports: reference in Astro documentation

Here’s a code snippet from that component:

---
import { Picture, inferRemoteSize } from "astro:assets";

const props = Astro.props;

let width;
if (typeof props.src === "object") {
  width = parseInt(props.src.width);
} else if (typeof props.src === "string") {
  const size = await inferRemoteSize(props.src);
  width = size.width;
}

const widths = [];
const ratioMultiplier = props.maxWidth / props.maxViewport;
let currentViewport = props.maxViewport;

while (currentViewport >= 240) {
  widths.push({
    viewport: currentViewport,
    width: Math.round(currentViewport * ratioMultiplier),
  });
  currentViewport -= 320;
}
---

<Picture
  formats={["avif"]}
  widths={widths.map(({ width }) => width)}
  sizes={widths
    .reverse()
    .map(
      ({ viewport, width }) =>
        `(max-width: ${viewport}px) ${width}px`,
    )
    .concat(`${width}px`)
    .join(", ")
    .trim()}
  quality={100}
  {...props}
>
  <slot />
</Picture>

At the time of writing this custom image component, it doesn’t look like Astro got a standard way to import images. In props.src, some of them are string, some of them are object. The component only works when the src is object, which will happen when using images in Markdown files.

Hey, did you get a better solution for this? Please write me an email to let me know!

Conclusion

After reading this article, you might think do you need to use Astro in your website?

If you plan to build a static site, personal blog that doesn’t have excessive works on JavaScript, yes, Astro is definitely for you. Who can’t resist good score from PageSpeed Insights?

Mobile score from PageSpeed Insights

Mobile score from PageSpeed Insights

Desktop score from PageSpeed Insights

Desktop score from PageSpeed Insights

But if you plan to build a website, that’s probably an: online office suite, interactive form or webpage to show off a very cool JavaScript animation technique. Considering using other web frameworks.

Wants to chat with me?

Fire an email to [email protected]!