{
"$type": "site.standard.document",
"description": "feat: migrate blog from Hugo to Astro 5",
"path": "/posts/migrating-from-hugo-to-astro/",
"publishedAt": "2026-01-20T00:00:00.000Z",
"site": "https://read.ryancowl.es",
"tags": [
"Code"
],
"textContent": "Back in 2024, I set up this site with Hugo and was impressed by its speed and simplicity. But as I continued to work with it, I found myself wanting more flexibility, particularly the ability to use interactive components and modern JavaScript tooling. I decided to check out Astro, a framework that promises to deliver fast, content-focused websites with the flexibility to use your favorite UI framework when you need it.\n\ntl;dr: I migrated my Hugo site to Astro 5 using the Vitesse theme and switched from DigitalOcean to Netlify for deployment. The migration was pretty straightforward, and I gained access to Vue components, better TypeScript support, and a more familiar JavaScript ecosystem.\n\n \n\nWhy migrate?\n\nHugo is great for what it does. It's fast, has great templating, and handles Markdown content well. But I'm always curious to explore new tech stacks, and I found myself wanting:\nModern JavaScript tooling - TypeScript support, npm packages, and familiar build tools.\nInteractive components - The ability to use Vue, React, or Svelte components when needed.\nFlexibility - More control over the build process and easier customization without learning Go templates.\n\nAstro checks all of those boxes and still ships fast, static sites by default.\n\n \n\nWhat is Astro?\n\nAstro is a modern static site generator that ships zero JavaScript by default but allows you to add interactivity only where you need it. It supports multiple UI frameworks (Vue, React, Svelte, etc.) in the same project and uses a component-based architecture that feels familiar if you've worked with modern JavaScript frameworks.\n\nKey features that sold me:\nContent Collections - Type-safe content management with Zod schemas. Zod lets you define the shape of your data (like \"title must be a string, date must be a date\"), and TypeScript enforces it at build time. Now I don't have to worry about typos in frontmatter breaking my site.\nView Transitions - Smooth page transitions without a full SPA\nMDX support - Markdown with the ability to import and use components.\nIslands Architecture - Only hydrate interactive components on the page. \"Hydration\" allows us to take static HTML and make it interactive by attaching JavaScript event listeners. Astro only does this where you explicitly ask for it, keeping most of the site fast and static.\n\n \n\nThe migration process\n\nStep 1: Choose a theme\n\nRather than starting from scratch, I decided to use the Vitesse theme as a starting point. It's an opinionated Astro starter that comes with:\nAstro 5 and Vue 3 support\nUnoCSS for styling\nTypeScript in strict mode\nContent Collections pre-configured\nDark mode built-in\n\nI cloned the theme repository and removed the Git history to start fresh:\n\nThis gave me a solid foundation without having to configure everything from scratch.\n\nStep 2: Update content collections\n\nThe Vitesse theme already had Content Collections configured, but I needed to adjust the schema to match my Hugo frontmatter. I updated to support my existing post metadata:\n\nThis gives me type safety and auto-completion for all my content's frontmatter.\n\nStep 3: Migrate content\n\nThe content migration was pretty straightforward. Hugo and Astro both use Markdown files with frontmatter, so I simply:\nCopied my content from Hugo's directory to Astro's directory.\nUpdated any Hugo-specific shortcodes to MDX components where needed.\nAdjusted frontmatter dates to match Astro's expected format.\n\nMost posts only required minor changes (adjusting date formats, updating a few Hugo shortcodes to MDX components). The shortcodes actually became cleaner as Astro components.\n\nOne nice thing about both Hugo and Astro is that they both support Markdown with YAML/TOML frontmatter, so the content files are largely compatible. The main difference is that Hugo uses Go templating and shortcodes, while Astro uses JSX-like syntax and MDX components when you need dynamic content.\n\nStep 4: Configure deployment\n\nI decided to switch from DigitalOcean to Netlify for hosting. Netlify has great Astro support and a generous free tier for static sites. The setup was simple:\nPushed my code to GitLab.\nConnected the repository to Netlify.\nNetlify automatically detected the Astro project and configured the build settings.\n\nThe Vitesse theme already included the adapter in , so no additional configuration was needed. Every push to the main branch now triggers an automatic build and deploy.\n\nStep 5: Port Plausible Analytics\n\nI was already using a self-hosted Plausible Analytics instance on my Hugo site, so I just needed to port the script over to Astro. I added it to my base layout ():\n\nSince I self-host Plausible, the script points to my own domain instead of plausible.io. The migration preserved all my existing analytics data so I didn't need to start tracking from scratch.\n\n \n\nBuild performance\n\nI was curious how Astro's build times would compare to Hugo. The results:\nHugo build time: ~150ms\nAstro build time: ~2.5s\n\nHugo is definitely faster at building. However, Astro's build time is still quite reasonable, and the developer experience improvements more than make up for the slightly longer builds. HMR during development is instantaneous, which is what I spend most of my time doing anyway.\n\n \n\nWhat I gained\n\nBetter DX\n\nWorking in the JavaScript ecosystem feels more familiar to me than working with Go. I get to use npm packages, TypeScript, ESLint, and other more familiar tooling.\n\nVue components\n\nI can now add interactive components where I need them. For example, I can create a component and drop it into any page:\n\nType safety\n\nContent Collections give me compile-time checking for frontmatter. If I forget a required field or misspell a property, my editor tells me immediately.\n\nModern CSS and theming\n\nThe Vitesse theme came with UnoCSS pre-configured, giving me the benefits of utility-first CSS with better tree-shaking and customization than Tailwind. Tree-shaking means unused CSS gets removed from the final bundle, keeping file sizes small. Dark mode support is built-in and works beautifully.\n\nBetter deployment experience\n\nNetlify's integration with Astro is smooth. They include build previews for pull requests, automatic deployments, and great developer experience out of the box.\n\n \n\nWhat I gave up\n\nBuild speed\n\nHugo's Go-powered builds are noticeably faster. For large sites, this could be significant. For my small blog, the difference is negligible.\n\nMaturity\n\nHugo has been around longer and has a larger ecosystem of themes and plugins. Astro is newer but growing rapidly.\n\nSimplicity\n\nHugo is simpler in some ways. It's a single binary with no node_modules. Astro brings the complexity (and power) of the modern JavaScript ecosystem.\n\n \n\nShould you migrate?\n\nIf you're comfortable with Hugo and don't need JavaScript interactivity, stick with Hugo. It's excellent at what it does.\n\nConsider migrating to Astro if you:\nWant to use modern JavaScript frameworks and tools\nNeed interactive components on some pages\nPrefer working in the JavaScript ecosystem\nWant better TypeScript support\nAre building a site that's more than just a blog\n\nFor me, the migration was worth it. Using a well-crafted starter theme like Vitesse meant I could focus on migrating content rather than configuration. I ended up with a setup that gives me more control without losing the speed and simplicity I liked about Hugo.\n\n \n\nResources\nAstro Documentation\nMigrate from Hugo to Astro Guide\nVitesse Astro Theme\nUnoCSS Documentation\nAstro Content Collections Guide\nNetlify Astro Deployment",
"title": "Migrating from Hugo to Astro"
}