Dunia pengembangan web modern terus berkembang dengan cepat, dan dua framework yang belakangan ini sering menjadi perbincangan hangat di kalangan developer adalah Next.js dan Astro. Keduanya menawarkan pendekatan yang berbeda untuk membangun website yang cepat dan modern, namun dengan filosofi arsitektur yang sangat berbeda satu sama lain. Memahami perbedaan mendasar antara keduanya bukan sekadar urusan preferensi teknis, melainkan keputusan strategis yang bisa berdampak pada performa, skalabilitas, hingga biaya infrastruktur dalam jangka panjang.


Gambaran Umum

Next.js adalah framework full-stack yang dibangun di atas React, dikembangkan dan dipelihara oleh Vercel. Sejak pertama kali dirilis pada tahun 2016, Next.js telah menjadi pilihan utama bagi developer yang ingin membangun aplikasi web kompleks dengan kemampuan server-side rendering (SSR), static site generation (SSG), dan incremental static regeneration (ISR). Next.js pada dasarnya membungkus React dengan serangkaian konvensi dan fitur tambahan seperti routing berbasis file system, API routes, serta optimasi gambar dan font bawaan. Dengan popularitas React yang masif, Next.js mewarisi ekosistem yang sangat kaya akan library, komponen, dan komunitas pendukung.

Astro, di sisi lain, adalah framework web generasi baru yang pertama kali dirilis pada tahun 2021 dengan filosofi yang sangat berbeda: "ship zero JavaScript by default." Astro dirancang dari awal untuk membangun website berbasis konten — seperti blog, dokumentasi, landing page, dan portfolio — dengan mengutamakan kecepatan melalui arsitektur yang mereka sebut Islands Architecture. Yang membuat Astro unik adalah kemampuannya untuk menggunakan komponen dari berbagai framework UI sekaligus dalam satu proyek yang sama — React, Vue, Svelte, bahkan komponen Astro sendiri — tanpa harus terikat pada satu ekosistem tertentu.

Kenapa perbandingan ini penting? Karena dalam beberapa tahun terakhir, industri web mengalami pergeseran paradigma yang signifikan. Di satu sisi, ada gerakan "back to basics" yang mendorong pengembangan website dengan JavaScript sesedikit mungkin untuk mengoptimalkan performa dan pengalaman pengguna. Di sisi lain, kompleksitas aplikasi web terus meningkat dan menuntut interaktivitas yang kaya. Pilihan antara Next.js dan Astro bukan hanya soal framework mana yang "lebih baik," melainkan framework mana yang lebih cocok untuk jenis proyek tertentu.

Jika kita membandingkan secara head-to-head berdasarkan fitur, Next.js unggul dalam hal interaktivitas dan kompleksitas aplikasi. Dengan App Router yang diperkenalkan di versi 13, Next.js mendukung React Server Components, streaming SSR, parallel data fetching, dan middleware yang powerful. Namun, semua kemampuan ini datang dengan biaya: bundle JavaScript yang lebih besar dan waktu hidrasi yang lebih lambat di sisi klien. Astro, sebaliknya, secara default menghasilkan halaman HTML murni tanpa JavaScript klien. Ketika interaktivitas diperlukan, Astro menggunakan directive client:* untuk menghidrasi hanya komponen yang membutuhkan, sehingga menghasilkan payload yang jauh lebih ringan.

Dari segi harga dan hosting, kedua framework bisa di-deploy di berbagai platform. Next.js memiliki integrasi paling mulus dengan Vercel, yang menawarkan tier gratis generous namun biaya bisa meningkat signifikan untuk aplikasi dengan traffic tinggi karena model pricing berdasarkan function execution dan bandwidth. Astro, karena secara default menghasilkan static site, bisa di-host secara gratis di platform seperti Netlify, Cloudflare Pages, atau GitHub Pages tanpa biaya compute. Bahkan ketika menggunakan Astro dalam mode hybrid atau server, opsi deployment ke Node.js adapter atau Deno memberikan fleksibilitas yang serupa dengan Next.js, namun dengan footprint resource yang umumnya lebih kecil.


Cara Kerjanya di Balik Layar

Konsep inti Next.js berputar pada paradigma React-centric dengan server-first approach. Dalam App Router (direktori app/), setiap folder merepresentasikan route, dan file-file khusus seperti page.tsx, layout.tsx, loading.tsx, dan error.tsx mendefinisikan berbagai aspek dari route tersebut. Next.js membedakan secara eksplisit antara Server Components (default) dan Client Components (ditandai dengan directive "use client"). Server Components merender di server dan tidak mengirim JavaScript ke klien, sementara Client Components menghidrasi di browser untuk menyediakan interaktivitas. Data fetching di Next.js modern dilakukan langsung dalam komponen server menggunakan async/await, menggantikan pattern getServerSideProps atau getStaticProps dari era Pages Router.

Sistem routing Next.js juga mendukung parallel routes menggunakan @folder convention, intercepting routes dengan (.)folder, dan nested layouts yang memungkinkan persistence state UI saat navigasi antar halaman. Middleware yang berjalan di Edge Runtime memberikan kemampuan untuk melakukan autentikasi, redirect, dan manipulasi request sebelum mencapai route handler. Semua fitur ini menjadikan Next.js sebuah platform yang lengkap untuk membangun aplikasi web production-ready.

Konsep inti Astro, sebaliknya, berpusat pada Content-first dengan Islands Architecture. Dalam Astro, halaman secara default adalah .astro files yang merender menjadi HTML murni — tidak ada React, tidak ada Vue, tidak ada JavaScript framework apapun yang dikirim ke browser kecuali secara eksplisit diminta. Komponen Astro menggunakan sintaks yang mirip JSX namun lebih sederhana: script dan style di-scoped secara otomatis, dan ekspresi JavaScript hanya berjalan di server selama proses build.

Islands Architecture adalah konsep revolusioner yang menjadi jiwa Astro. Alih-alih menghidrasi seluruh halaman sebagai satu aplikasi SPA (seperti pendekatan tradisional React/Next.js), Astro memecah halaman menjadi "pulau-pulau" interaktif yang terisolasi satu sama lain. Setiap pulau bisa menggunakan framework UI yang berbeda, dan hidrasi hanya terjadi pada komponen yang benar-benar membutuhkan interaktivitas. Directive client:load menghidrasi segera saat halaman load, client:visible menunggu sampai komponen masuk viewport, client:idle menunggu browser idle, dan client:only menghidrasi tanpa server rendering (seperti CSR murni).

Komponen utama dalam ekosistem Next.js meliputi: routing system berbasis file system, built-in Image component dengan optimasi otomatis, API routes untuk backend logic, middleware untuk edge computing, serta integrasi mendalam dengan React ecosystem termasuk TanStack Query, Zustand, dan sebagainya. Next.js juga menyediakan next/font untuk optimasi font dan next/link untuk prefetching route, menjadikannya framework yang sangat batteries-included.

Komponen utama dalam ekosistem Astro meliputi: Astro Content Collections untuk mengelola konten Markdown/MDX dengan type safety, Astro Integrations untuk menambahkan framework UI dan tooling, View Transitions API yang terintegrasi untuk animasi navigasi tanpa JavaScript tambahan, serta astro:assets untuk optimasi gambar. Astro juga memiliki konsep "partials" dan "fragments" yang memungkinkan pengambilan bagian halaman secara terpisah, ideal untuk HTMX-style architecture.


Penerapan Praktis

Skenario 1: Membuat Blog Pribadi dengan Static Content

Untuk blog sederhana, Astro menawarkan pengalaman yang sangat streamlined. Berikut cara memulai proyek Astro:

npm create astro@latest my-blog
cd my-blog
npm run dev

Output yang dihasilkan:

🚀  astro  v4.16.0 started in 42ms

  Local:   http://localhost:4321/
  Network: http://192.168.1.5:4321/

Membuat halaman blog di Astro sangat langsung:

---
// src/pages/index.astro
import Layout from '../layouts/Layout.astro';
import { getCollection } from 'astro:content';

const posts = await getCollection('blog');
---
<Layout title="Blog Saya">
  <h1>Artikel Terbaru</h1>
  <ul>
    {posts.map((post) => (
      <li>
        <a href={`/blog/${post.slug}`}>
          {post.data.title}
        </a>
        <time>{post.data.date.toLocaleDateString()}</time>
      </li>
    ))}
  </ul>
</Layout>

Perhatikan bahwa tidak ada state, tidak ada effect, tidak ada hidrasi — hanya template yang merender menjadi HTML. Bandingkan dengan pendekatan Next.js yang memerlukan pemahaman tentang server vs client boundary:

// app/page.tsx
import Link from 'next/link';
import { getBlogPosts } from '@/lib/posts';

export default async function Home() {
  const posts = await getBlogPosts();

  return (
    <main>
      <h1>Artikel Terbaru</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.slug}>
            <Link href={`/blog/${post.slug}`}>
              {post.title}
            </Link>
            <time>{post.date}</time>
          </li>
        ))}
      </ul>
    </main>
  );
}

Meskipun kode Next.js juga relatif bersih, developer perlu memahami bahwa komponen ini adalah Server Component secara default, dan setiap komponen client yang diimpor akan membawa JavaScript bundle.

Skenario 2: Aplikasi Dashboard Interaktif

Untuk dashboard yang membutuhkan banyak interaktivitas real-time, Next.js menjadi pilihan yang lebih natural:

npx create-next-app@latest my-dashboard --typescript --tailwind --app
cd my-dashboard
npm run dev

Output:

   ▲ Next.js 14.2.0
   - Local:        http://localhost:3000
   - Environments: .env

 ✓ Ready in 1.8s

Contoh dashboard page dengan client-side interactivity:

// app/dashboard/page.tsx
'use client';

import { useState, useEffect } from 'react';
import { RefreshCw } from 'lucide-react';

interface Metric {
  label: string;
  value: number;
  trend: 'up' | 'down';
}

export default function Dashboard() {
  const [metrics, setMetrics] = useState<Metric[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchMetrics();
    const interval = setInterval(fetchMetrics, 30000);
    return () => clearInterval(interval);
  }, []);

  async function fetchMetrics() {
    setLoading(true);
    const res = await fetch('/api/metrics');
    const data = await res.json();
    setMetrics(data);
    setLoading(false);
  }

  return (
    <div className="grid grid-cols-4 gap-4">
      {metrics.map((m) => (
        <MetricCard key={m.label} {...m} loading={loading} />
      ))}
      <button onClick={fetchMetrics}>
        <RefreshCw className={loading ? 'animate-spin' : ''} />
      </button>
    </div>
  );
}

Dengan Astro, Anda bisa mencapai hal serupa menggunakan React island, namun prosesnya lebih verbose karena perlu setup integrasi terlebih dahulu:

npx astro add react
---
// src/pages/dashboard.astro
import Dashboard from '../components/Dashboard.tsx';
---
<h1>Dashboard</h1>
<Dashboard client:load />

Skenario 3: Situs Dokumentasi dengan Pencarian

Situs dokumentasi adalah use case di mana Astro benar-benar bersinar. Astro memiliki integrasi resmi dengan Starlight, sebuah toolkit dokumentasi yang siap pakai:

npm create astro@latest -- --template starlight
🚀  Starlight  v0.25.0

  Add your first doc page:  src/content/docs/getting-started.mdx
  Start dev server:         npm run dev

Dengan konfigurasi minimal, Starlight sudah menyediakan pencarian full-text, navigasi sidebar, i18n support, dan tema yang responsif — semua dengan payload JavaScript yang sangat kecil. Next.js bisa mencapai hasil serupa menggunakan Nextra atau Fumadocs, namun dengan overhead JavaScript yang lebih besar.

Skenario 4: E-commerce dengan Hybrid Rendering

E-commerce membutuhkan kombinasi halaman statis (landing page, product info) dan dinam