Back to Blog
Code editor with JavaScript code on dark background

Building Modern Web Apps with Astro and Vue

Discover why Astro has become my go-to framework for building fast, content-driven websites. Plus, see how to integrate Vue for interactive islands.

Devin Brand 3 min read

After years of building websites with various frameworks, I’ve found my sweet spot: Astro for the content layer and Vue for interactive components. Here’s why this combination is so powerful.

The Problem with Traditional SPAs

Single Page Applications (SPAs) revolutionized web development, but they came with costs:

  • JavaScript bloat - Sending entire frameworks to the browser
  • Poor initial load times - Users wait for JS to parse and execute
  • SEO challenges - Search engines struggle with client-rendered content
  • Complexity - State management, routing, and hydration issues

Enter Astro

Astro takes a different approach: ship zero JavaScript by default. Your pages are rendered to static HTML, and you only add JavaScript where you need interactivity.

---
// This runs at build time (or on the server)
import Layout from '../layouts/Layout.astro';
import BlogCard from '../components/BlogCard.astro';
import { getCollection } from 'astro:content';

const posts = await getCollection('blog');
---

<Layout>
  <h1>Latest Posts</h1>
  {posts.map(post => (
    <BlogCard post={post} />
  ))}
</Layout>

The Island Architecture

Astro’s killer feature is islands architecture. You can add interactive Vue (or React, Svelte, etc.) components that hydrate independently:

---
import InteractiveChart from '../components/Chart.vue';
---

<!-- This loads and hydrates only when visible -->
<InteractiveChart client:visible data={chartData} />

My Favorite Astro Features

1. Content Collections

Type-safe content management with Zod schemas:

// src/content/config.ts
import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    pubDate: z.coerce.date(),
    tags: z.array(z.string()),
  }),
});

export const collections = { blog };

2. Built-in Image Optimization

---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.png';
---

<Image src={heroImage} alt="Hero" width={800} quality={80} />

3. View Transitions

Smooth page transitions without the SPA complexity:

---
import { ViewTransitions } from 'astro:transitions';
---

<head>
  <ViewTransitions />
</head>

Performance Wins

Here’s what I’ve seen on real projects:

MetricBefore (SPA)After (Astro)
First Contentful Paint2.4s0.8s
Time to Interactive4.1s1.2s
JavaScript Bundle450KB45KB
Lighthouse Score7298

When to Use What

Use Astro when:

  • Content is the focus (blogs, docs, marketing sites)
  • SEO matters
  • Performance is critical
  • You want to mix frameworks

Stick with SPAs when:

  • Building highly interactive apps (dashboards, editors)
  • Real-time collaboration features
  • Complex state management across the entire app

Getting Started

Ready to try Astro? Here’s how to get started:

# Create a new project
npm create astro@latest

# Add Vue integration
npx astro add vue

# Start developing
npm run dev

Building something with Astro? I’d love to see it! Share your projects in the feedback form.

Share this post

Devin Brand

Devin Brand

Data explorer, web builder, and eternally curious human. Always asking "why?" and digging for answers.

Related Posts