Astro 6 for Beginners: A WordPress Developer's 2-Day Learning Diary

A WordPress developer's honest diary of the two days it took to get hands-on with Astro 6 for the first time: local dev, VS Code, pages, and layouts, plus the Content Collections, GitHub, and Vercel mistakes that came in the weeks after.

Quick answer

Is Astro hard to learn for beginners?

Astro has a learning curve if you're coming from WordPress because the workflow is local-first: Node.js, terminal, localhost, GitHub, and deployment. But the core concepts click fast once you understand that your laptop is the development server and Astro builds static output from files.

Astro 6 learning diary dashboard showing local development, Content Collections, GitHub, Vercel, and WordPress context
First-hand experience: Based on direct hands-on use. I'd researched Astro after one of my WordPress sites got too heavy to keep fast. This is the diary of the two days I finally sat down and got hands-on with it for the first time, documenting every mistake in real time.

I’ve been building WordPress sites since 2013. Client blogs, WooCommerce stores, coupon sites, affiliate sites. I’ve done all of it. I know the WordPress dashboard the way I know my own kitchen.

One of those sites, a price comparison site, got too heavy to keep fast no matter what I threw at it. That’s what pushed me to research Astro in the first place. Researching a framework and actually building with it are two different things, though. I kept putting off the “actually build something” part.

Then I finally sat down to do it. I thought: how hard can it be? I already know what Astro is supposed to do. I’ll follow a tutorial, spend an afternoon, have something running by dinner.

Two days later, I understood how Astro actually works: local dev, pages, layouts, the mental model shift away from WordPress. Not a finished site. Just enough to stop feeling lost. The full site you’ll see through this series (the blog, reviews, comparisons, and guides) came together over the weeks that followed, as I worked through the rest of this series.

This is the diary of those first two days.


Day 1: The Setup Problem Nobody Warns You About

The first thing that tripped me up wasn’t code. It was workflow.

With WordPress, I work directly on a server. Open cPanel or an SFTP client, edit the file, save it, reload the browser. Done. The “dev environment” is the live server.

Astro doesn’t work like that. You run everything locally first, on your own machine, then push to GitHub, then deploy. That sequence felt backwards to me at first.

Even before I touched any code, I had to make peace with the idea that my laptop is now a development server.

If you’re setting up Astro today, check the official Astro installation guide first. Astro currently requires Node.js 22.12.0 or higher, and the docs recommend VS Code with the official Astro extension.

If Node.js is missing on your machine, use the official Node.js website instead of random installer links.

The first actual mistake: the folder name.

The better command is to pass the project name directly:

npm create astro@latest astro-content-lab

But the first time I tried Astro, I didn’t know that shortcut. I only ran:

npm create astro@latest

Astro asked where to create the project and showed a default name like ./steadfast-spiral. I hit Enter without reading it carefully.

Result: a folder named steadfast-spiral on my desktop instead of astro-content-lab.

Astro installer prompt showing a default project folder name before the project is created
The installer asked for a project name, and I almost missed it. That small detail led to the wrong folder being created on my desktop.
A terminal screenshot showing the Astro installer prompt and the default folder name selection
The CLI was asking for a destination, but I did not read the default path closely enough. That mistake changed the project location before I even started coding.

Fix was simple:

mv steadfast-spiral astro-content-lab
cd astro-content-lab

Lesson learned: either pass the project name in the first command, or read what Astro is asking before pressing Enter.


The Dev Server Confusion

After installation, I ran npm run dev and saw this in the terminal:

astro  v6.4.7 ready in 499 ms
 Local    http://localhost:4321/
 Network  use --host to expose
watching for file changes...

Then nothing happened. The terminal just sat there. I waited. Still nothing.

I assumed something was broken. I stared at it for a few minutes wondering if I should restart.

Then I realized: this isn’t a loading screen. It’s a running server. I was supposed to open my browser and go to http://localhost:4321/.

This is obvious if you’ve done local dev before. It wasn’t obvious to me.

In WordPress, Apache or Nginx is already running somewhere on your hosting account. You don’t think about the server because it is hidden behind cPanel, a dashboard, or a hosting panel.

In Astro, the terminal window is the server during development. Close it, and localhost:4321 dies immediately.

It felt strange at first: the website was alive only because one terminal window was still open.

Important note: keep that terminal window open the whole time you’re working.

A terminal window showing the Astro local development server running on localhost
The dev server is only alive while that terminal stays open. That was the moment I realized the browser and the terminal were part of the same workflow.

Choosing an Editor, and Finding the Terminal Inside It

I’ve been using Textmate for years. Quick file edits, nothing fancy. Works fine for WordPress template files.

For Astro, I moved to VS Code because the project is folder-based, component-based, and much easier to manage with a real project sidebar. If you’re new to this workflow, the step-by-step version is in my first Astro project setup guide.

The command to open a folder in VS Code from your terminal is:

code .

Simple. Except it didn’t work for me at first. The terminal said zsh: command not found: code.

The fix was the one-time VS Code shell command setup. I also recommend installing the official Astro VS Code extension for syntax highlighting and editor support.

But the bigger discovery was the terminal inside VS Code.

VS Code with the integrated terminal open beside the project files
The built-in terminal in VS Code made the workflow feel familiar immediately. It let me run Astro commands and Git commands without leaving the editor.

I already use terminal on my VPS: SSH in, run commands, manage servers. That’s my comfort zone. When I found the integrated terminal in VS Code (Ctrl + `), I realized: this is the same thing. Same commands. Same workflow. I can run npm run dev in one terminal tab, open another tab for Git commands, and stay inside VS Code the whole time.


Day 2: Pages, Layouts, and the <slot /> Mystery

Pages in Astro clicked fast. Create a file in src/pages/, get a URL. No routing config. No WordPress permalink settings. Just a file.

src/pages/index.astro   →   /
src/pages/about.astro   →   /about
src/pages/blog.astro    →   /blog
VS Code showing a new Markdown blog post file inside the Astro project
The first markdown post file made the content workflow feel concrete. It was the first moment I could picture a real page being generated from a file instead of a database entry.
The local blog post rendering in the browser at localhost after the Markdown file was created
Seeing that markdown file appear as a working page in the browser made the setup feel less theoretical and much more real.

Layouts took longer to understand. The concept is simple, a shared HTML wrapper so you don’t repeat <html><head><body> in every page. But the <slot /> tag confused me.

What does <slot /> do exactly?

Short answer: it’s a placeholder. Whatever you put inside <BaseLayout> in your page file goes where <slot /> is in the layout.

// BaseLayout.astro
<body>
  <Header />
  <slot />   ← your page content goes here
</body>
VS Code showing the BaseLayout component structure with the slot placeholder
The layout file looked simple once I saw it as a shared wrapper. The slot was the key that made the rest of the page structure click.
// about.astro
<BaseLayout title="About">
  <h1>About</h1>        ← this goes into the slot
  <p>This is me.</p>    ← this too
</BaseLayout>

The moment I understood that, everything else made sense. Think of <slot /> like a socket: the layout is the wall, and each page plugs into it.

The mistake that cost me 20 minutes: I edited BaseLayout.astro, saved the file, reloaded the browser, and saw a blank white page. Panicked.

The fix: I hadn’t actually saved the file. VS Code had an unsaved dot indicator in the tab. One Cmd + S later, everything was back.

Check your file is saved before you assume something is broken.

That covers the two days I set out to document: the point where Astro stopped feeling like a foreign language. Everything from here happened over the following weeks, as I kept building astro-content-lab into an actual content site. I’m including it because the mistakes are just as real, even if the timeline is longer than “2 days.”


Content Collections: Where Astro 6 Diverges From Older Tutorials

This is the section that will save you the most time.

Content Collections are Astro’s way of managing structured content (blog posts, reviews, guides) with schema validation. Think WordPress Custom Post Types, but in files instead of a database.

When I set them up, I ran into a wall of errors. Not because Content Collections are hard. Because Astro 6 removed the automatic legacy Content Collections behavior that many older tutorials still rely on.

The official Content Collections guide is the source I trust now. For old projects or old tutorials, the Astro v6 upgrade guide explains the compatibility changes.

Here’s the Astro 6 reality:

1. The config file moved.

Old location: src/content/config.ts
New location: src/content.config.ts (outside the content folder, at src/ level)

If you put it in the wrong place, Astro shows this error:

LegacyContentConfigError: Found legacy content config file in "src/content/config.ts".
Please move this file to "src/content.config.ts"

Astro’s own error reference says the same thing: move the legacy config file to src/content.config.ts and ensure each collection has a loader defined.

2. Collections need a loader now.

Old tutorial pattern:

const posts = defineCollection({
  schema: z.object({ ... })
})

Modern Astro 6 pattern:

import { glob } from 'astro/loaders'

const posts = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/content/posts' }),
  schema: z.object({ ... })
})

3. post.render() is legacy behavior.

Old tutorial pattern:

const { Content } = await post.render()

Modern pattern:

import { render } from 'astro:content'

const { Content } = await render(post)

4. post.slug is legacy behavior.

Old tutorial pattern:

params: { slug: post.slug }

Modern pattern:

params: { slug: post.id }
The browser error showing a missing slug parameter when generating dynamic routes
The missing slug error looked like a routing problem, but it was another Astro 6 compatibility issue tied to legacy slug handling.

5. Astro.glob() is removed.

If you’re fetching files without Content Collections, use import.meta.glob() instead. Astro’s Astro.glob reference page also notes that Astro.glob() was removed in Astro v6.

The browser error showing Astro.glob is not a function in the Astro blog page
That error looked like a bug in my page component, but it was really a sign that Astro 6 had removed the old glob API I was using.

6. When you add a new collection, restart the dev server before debugging for 40 minutes.

This one got me twice. Add a new collection → the terminal says "collection does not exist or is empty" even though you did everything right.

My best explanation: when you change collection definitions, Astro’s dev server may still be working from generated metadata in the .astro cache folder. Restarting the dev server or removing .astro forces Astro to rebuild that internal content state.

Fix:

# Option 1
rm -rf .astro
npm run dev

# Option 2
Open content.config.ts, add a space anywhere, save. This forces Astro to reload

I don’t treat this as a permanent Astro bug. I treat it as a normal “restart the dev server before debugging for 40 minutes” lesson.


The First Push to GitHub

A few weeks later, once Content Collections finally clicked, I had a working content site:

  • Home, About, Blog pages
  • Content Collections for posts, reviews, comparisons, guides
  • Dynamic routes: each content file gets its own URL automatically
  • A Header component shared across all pages
  • Deployed on Vercel
A local Astro page showing the site structure with Home, About, and Blog navigation
By this point the local site felt real. The pages were no longer just files in a folder; they looked and behaved like a small website.
A local page comparing Astro with WordPress in the browser
That page was one of the early proof points that the content model was starting to feel natural, even though the project was still very bare-bones.

The first git push felt underwhelming. The terminal printed some lines, said “done”, and that was it.

git add .
git commit -m "first commit"
git push -u origin main

Then I went to astro-content-lab.vercel.app and the site was live.

The GitHub repository page for the Astro content lab project
The first push was the moment the project stopped being just a local experiment and became something I could share and deploy.

I’ve built hundreds of WordPress sites. I’ve transferred files via FTP, configured cPanel, wrestled with SSL certificates. But there’s something different about pushing code to GitHub and watching Vercel build and deploy it automatically in 30 seconds. No control panel. No FTP. No manually clicking “install SSL”.

If you are new to this workflow, GitHub stores the code, and Vercel deploys the site. Pushing to GitHub by itself is not the same as publishing a website.

I’m not going to say it changed my life. But I did sit there for a minute just refreshing the live URL.

I spent 10 years editing WordPress theme files in cPanel. Then I pushed to GitHub and Vercel did the rest in 30 seconds. Totally normal.


What I Actually Learned

Coming from WordPress, the biggest adjustment wasn’t the syntax. It was the mental model.

In WordPress: the server is always running. The database stores your content. You edit in a browser. Everything happens online.

In Astro: your laptop is the server during development. Content lives in files. You edit in VS Code. The “online” version only exists after you build and deploy.

That shift feels wrong at first. Then it feels right. Then you wonder why WordPress needs a database for a blog that hasn’t changed in three months.

The things WordPress does automatically (admin panel, login, database, URL routing) Astro makes you understand. That’s not a weakness. It’s the whole point.

If you want the cleaner setup version of this story, read the step-by-step Astro setup guide. This diary is the messy version. The guide is the organized version.


The Source Code

Everything built in this article is in the GitHub repo. Each commit maps to a specific feature.

GitHub: github.com/doancongtuan/astro-content-lab
Live demo: astro-content-lab.vercel.app

This repo will continue to evolve as the series progresses: CSS, Tailwind, real images, SEO, TinaCMS, and eventually a mini CMS backend. If you clone it now, you’re cloning the starting point. Check back for each article to see it grow.

If you want to see what everything in this diary eventually produced, start here:

  • Clone the GitHub repo
  • Open the live demo
  • Compare the early commits with the later ones

That is the real value of this series: the trail of mistakes behind the finished code.


Frequently Asked Questions

Is Astro harder than WordPress to set up?
The initial setup feels harder because it's different, not because it's more complex. WordPress gives you a hosting panel and a browser-based dashboard. Astro requires Node.js, a terminal, and a local dev server. Once that mental model shifts, it becomes straightforward, especially if you've already used a terminal before.
What do I need to know before learning Astro?
Basic HTML, CSS, and JavaScript is enough. You don't need React. You don't need deep Node.js expertise. If you've ever managed a VPS over SSH, the terminal workflow will feel familiar. If you haven't, it takes a day to get comfortable.
How is Astro 6 different from older Astro tutorials?
Astro 6 removed the automatic legacy Content Collections behavior that many older tutorials still rely on. Modern projects use src/content.config.ts, loaders like glob(), render(entry) instead of entry.render(), entry.id instead of entry.slug, and import.meta.glob() instead of Astro.glob().
Do I need React to use Astro?
No. Astro uses its own .astro component format which is closer to HTML than React. You can add React, Vue, or Svelte components later if needed, but for a content site (blog, reviews, guides) you don't need any framework at all.
Where can I deploy an Astro site for free?
Vercel is one of the easiest options. Connect your GitHub repo and it auto-deploys after every push. Netlify and Cloudflare Pages work just as well. For a static Astro site, the free tier on any of these is usually enough to get started.