DEV Community

Cover image for Astro? Let's try it
Mirko
Mirko

Posted on • Edited on

Astro? Let's try it

DEMO: https://astro-rickandmorty.netlify.app/
CODE: https://github.com/mirkosaugo/Astro-RAM

Why this project

As a developer I think it's important to jump in new challenges sometimes, not only because I have fun to try new technologies, but also because is a great opportunity to update my skills and have a full panoramic on what's going on out there.
Today I want to share with you my feedback about a new framework called Astro.
I'm not a good writer and the goal of this article is not to generate content, so I'll be very brief focusing on some framework principles, explaining my demo and at the end outline pros and cons.

What is Astro?

As the payoff in homepage says Astro is a "web framework for building fast, content-focused websites".
It's pretty new in this market, but I saw a lot of enthusiasm around it.
Astro is a new kind of static site builder that renders your entire page to static HTML, removing all JavaScript from your final build by default. You can compose your website using differents UI components from your favorite JavaScript framework (React, Svelte, Vue, etc) extending your vite configuration with these plugins.

Main Concept: Islands

"Astro Islands represent a leading paradigm shift for frontend web architecture."
This principles allows Astro to deliver less javascript in the page, because it loads a small piece of code of a specific component only when become interactive (for example when react components enter in the viewport). So, there isn't a huge bundle size of unused javascript.

Islands Architecture

And, as the figure shows sometimes a lot of components in a website are pure static content, and in that case you don't want to ship unused javascript to the user right? (think about a blog post page, maybe the user click on google link and he/she visit only that page. So, why load all the entire JS bundle?).
Read more about Astro Islands.


The project

Okay, now let's jump in a real case.
I developed this project using the RickAndMortyAPI (I'm a big fan of it), typescript and tailwind.
You can find the code in my Github repo and the demo at this link.

In Astro components you can write js code in 2 different ways. On top of the page that is compiled at build time (server side) or inside a normal script tag for client actions:

---
// Server Side (compiled on build process)
import Contact from '../components/Contact.jsx';
import Location from '../components/Location.astro';

const response = await fetch('https://randomuser.me/api/');
const data = await response.json();
const randomUser = data.results[0];
---
<!-- Markup -->
<h2>{randomUser.name.first} {randomUser.name.last}</h2>
<button id="interactivity">Click Me</button>

<!-- JS Client Side -->
<script>
  const button = document.getElementById('interactivity');
  button.addEventListener('click', () => {
    alert('Hello World!');
  });
</script>
Enter fullscreen mode Exit fullscreen mode

In the first case, that part is used to fetch and display content when the page is rendered and/or to read props passed from another component.
These components are oriented to be static, so you don't have access to states in page (like detect outside the component when a menu is open or closed) or custom events handling like onClick in react, but you can use the classic querySelector to trigger events and knows the status of the DOM.

Examples

Astro components and Framework components (in my case, react)

Astro components are very easy to use, BUT you can't use it inside a framework components (like react).
In my case I ran into this when i created a static component <CharacterCard /> where i could use also a useful astro plugin to generate blurred images on lazy images in the character card.
I used those cards in HomePage where the data comes from a fetch at build time and the content is static.
But, let's say that i want to create a search component in react (you can see it in HomePage) and loop all the items after the response. Well, in this case I can't reuse the same component to render the list because you can't use astro static components inside framework components. Or better, you can use the <slot /> property to render html inside of it, but you can't pass props to another astro component or loop it, so it's pretty useless in my opinion.
Read more about Astro and UI Frameworks.

Do you ship less for real?

The performance are unbeatable if compared with NextJS for example, but actually Astro always import js code in the document, when is written in the script tag inside an Astro component, even if the component is not in the viewport or called (like for framework components).
So it isn't like Qwik where js is loaded only when a specific element in the dom becomes interactive and is awake by the user.


Conclusion

PROS

  • Easy to understand and use
  • Better performance compared for example with NextJS
  • You can use your favorite framework (react, vue, svelte, etc) with Astro
  • Good community: There are a lot of useful plugins to use in Astro (like the plugin to generate blurred images for lazy images)

 CONS

  • You cant combine SSR pages and SSG pages in Astro (for example if you want to read params from a search form you need to transform your entire project in SSR: this causes a big issue for SEO because you lose the power of the static content)
  • Framework components (like react) cant use Astro (static) components
  • Astro components aren't reactive, so you cannot manage states when they change
  • if Framework components are in client:idle or client:load mode, they import the entire code when the page is loaded (I would like to have the client:load mode in the build process and then serve it as client:visible mode)

Image description

At the end, in my opinion and in poor words, Astro is good for small blogs and static/creative websites, but not for web applications where, for example, interactivity is the main focus (like: searching, filtering, ordering, shared states ecc...) because in that case you lost the real power of Astro.

Top comments (0)