wojciech.io
All insights
Insight Astro MDX i18n Build vs Buy AI Workflow

From Framer to Astro: the build vs buy decision behind this site

The honest trade-offs behind rebuilding wojciech.io: why I moved from a visual builder to Astro, what MDX and i18n changed, and which debt I accepted on purpose.

Wojciech Łuszczyński

Wojciech Łuszczyński

GTM Architect & Growth Operator · Now · 19 May 2026

TL;DR — Key insights

  • Framer was not the wrong tool. It was the right tool for visual iteration, then the wrong control plane for a growing portfolio system.
  • Astro made sense because the site became content, routes, components, deploy rules, and agent-editable source code.
  • The i18n layer is intentionally boring: real URL routes, shared page components, and data attributes where a full i18n library would be unnecessary overhead.
  • MDX is the leverage point: articles can carry diagrams, stats, callouts, and proof components without becoming one-off landing pages.
  • There is debt in the system. It is named, bounded, and acceptable until the site becomes a larger publication.
  • The real build-vs-buy question was not cost. It was control, compounding, and what needed to be editable by agents.

Most rebuild stories are too clean.

They make the old tool look naive, the new stack look inevitable, and the migration look like a straight line from “no-code limitation” to “proper engineering.” That is not what happened here.

I did not move this site from Framer to Astro because Framer was bad. Framer did what I needed at the time: it bought visual speed. I moved because the job of the site changed.

The site stopped being a set of polished pages and became a small operating surface: public positioning, proof, apps, writing, language variants, redirects, deploy checks, and a workflow where AI agents can make changes without guessing inside a visual editor.

That is a different build-vs-buy decision.

3
Languages
English, Polish, Italian
1
Content source per page
Shared Astro page components
MDX
Article system
Components inside long-form writing

The decision was not about cost

The lazy build-vs-buy frame is price.

“Framer costs money. Astro is free. Therefore Astro wins.”

That is a bad argument. A codebase is never free. It asks for maintenance, local setup, build failures, dependency updates, routing decisions, and judgment. A visual builder charges a subscription, but it also removes a lot of operational surface area.

The real question was this:

What do I need to control, and what can I safely rent?

For the first version of the site, renting the visual layer made sense. The bottleneck was not routing or article architecture. The bottleneck was getting a sharp public surface online quickly.

For the current version, the bottleneck changed. I needed versioned content, MDX, reusable article components, real language URLs, predictable redirects, and a repo that Claude Code and Codex could inspect, patch, build, and verify.

At that point, the builder was no longer just a builder. It was the control plane.

And I wanted the control plane in code.

What Framer bought me

Framer bought speed of composition.

It is good at the thing it is designed to do: let one person make a page feel finished without building a design system from first principles. For a personal site, that is real value. Most personal sites do not need a framework. They need taste, focus, and a deadline.

The problem appears when the site starts accumulating operational requirements:

  • long-form technical writing;
  • a structured article index;
  • RSS and sitemap behavior;
  • canonical URLs and redirects;
  • language routes that can be shared and indexed;
  • code-reviewed changes;
  • reusable proof components;
  • deploy previews;
  • production verification;
  • AI-assisted maintenance.

None of those make a visual builder “bad.” They just move the center of gravity away from visual composition and toward system design.

Buy the builder

right early
  • Fast visual iteration
  • Low setup cost
  • Less infrastructure to own
  • Good for a small number of polished pages
  • Best when non-technical editing is the main constraint

Build the system

right now
  • Versioned content and components
  • Real routing and redirects
  • MDX articles with custom primitives
  • Build and deploy verification
  • Better surface area for AI agents and code review

What Astro changed

Astro fit because the site is mostly static, but not simplistic.

I do not need a full application framework for a public portfolio and writing system. I need strong file-based routing, components, content collections, MDX, and output that Cloudflare Pages can serve cheaply and reliably.

Astro gives me that shape without forcing the site into a client-side app.

Positioning homepage, about, work
Content system MDX, RSS, sitemap
Deploy layer GitHub, Cloudflare Pages
Agent workflow patch, build, verify
The rebuild moved the site from page surface to operating surface

The important part is not that Astro is trendy. It is that Astro made the site legible.

Routes live in src/pages. Shared page content lives in src/components/pages. Articles live in src/content/insights. Design tokens live in CSS. A build either passes or it does not.

That is the kind of structure an agent can work inside.

MDX is where the site compounds

Plain Markdown would have been enough for simple posts. It was not enough for the kind of writing I want this site to carry.

The articles are not just essays. They often need:

  • diagrams;
  • comparisons;
  • callouts;
  • stats;
  • process flows;
  • screenshots;
  • do/don’t sections;
  • proof cards;
  • CTA blocks.

If every article hand-rolls that markup, the site becomes a graveyard of one-off HTML. If the components are available inside MDX, the article system becomes a small publishing product.

That is the leverage.

The practical result is simple: I can write an article about a system and drop in the same primitives I use to explain products and workflows elsewhere.

The i18n decision: deliberately boring

The site now ships in English, Polish, and Italian. The i18n implementation is not a beautiful internationalization platform. It is a practical system for the current scale.

There are two patterns:

  1. The homepage uses a typed dictionary in src/i18n/translations.ts.
  2. The main pages use shared Astro content components with data-en, data-pl, and data-it attributes, switched by a small script based on the URL.

Every localized page has a real route: /pl/about/, /it/apps/, and so on. The root English pages remain canonical.

The important decision was URL-based language, not localStorage-only language. A shared link should carry the language with it. Search engines should see language variants as real pages. Users should not depend on whatever state exists in their browser.

Do
  • Use real language URLs for pages people share
  • Keep page copy in one shared Astro component
  • Accept a small amount of markup noise when it avoids a larger framework
  • Name the point where the pattern stops scaling
Don't
  • Duplicate root and localized pages by hand
  • Add i18next because the architecture wants to look grown-up
  • Hide language state in localStorage and pretend links are portable
  • Translate insights before there is a real publishing reason

Is the attribute-based approach elegant? Not especially.

Is it correct for roughly a dozen public pages with three language variants and one owner? Yes.

That is the part people skip in architecture discussions. A simpler system with a known edge is often better than a more formal system that adds process before the process exists.

The debt I accepted

There is debt in this rebuild. I accepted it on purpose.

The i18n layer has two patterns. Homepage copy lives in a typed dictionary. Page copy lives in shared components with data-* attributes. Insights are English-only. The MDX component map is manual. There is no CMS. Non-technical editing means opening the repo.

That is debt.

But debt is not automatically a problem. Unnamed debt is the problem. Debt that nobody can see, nobody can price, and nobody knows how to unwind.

This debt is visible and bounded.

The current architecture is honest about the scale:

  • one owner;
  • a small number of public pages;
  • English-only insights;
  • a need for fast agent-assisted patches;
  • a preference for source-controlled changes;
  • no editorial team.

For that shape, the debt is cheaper than the abstraction.

How AI changed the build decision

AI agents changed the calculus, but not in the lazy “AI built my website” way.

The useful change is that code became easier to operate.

Claude Code can implement a larger batch when the direction is documented. Codex can inspect the repo, make focused patches, run npm run build, check output, and verify production. Both tools work better when the system is text, files, components, and tests.

A visual builder can be fast for a human. A codebase is more inspectable for an agent.

That mattered here because the site is not meant to freeze after launch. It should keep absorbing articles, proof, components, app links, page edits, and deploy checks.

Human judgment taste, scope, approval
Repo context docs, components, content
Agent patch edit, build, verify
Production check custom domain is the truth
The agent loop works because the system is inspectable

The human role did not disappear. It became more important.

When agents can produce faster, weak direction produces more weak output. The job is to keep the judgment layer tight: what belongs on the site, what should be cut, what sounds like me, what is proof, and what is just decorative structure.

When I would not choose this stack

I would not choose this architecture for every site.

I would stay in Framer, Webflow, or another builder when:

  • the main job is visual campaign pages;
  • the editing team is non-technical;
  • pages need to be composed quickly by marketing without a repo;
  • there is no long-form technical publishing system;
  • route control and source history are not important;
  • the site is better served by design speed than engineering control.

I would choose a heavier framework or CMS when:

  • there are many editors;
  • every article needs multiple translated versions;
  • content workflows need review states and permissions;
  • pages are generated from large structured datasets;
  • authenticated user behavior becomes central;
  • editorial velocity outgrows Git.

Astro is the right middle for this site because the site is static enough to stay simple and structured enough to need code.

The operator rule

Here is the rule I would reuse:

Buy speed when the surface is the product. Build control when the system behind the surface is the product.

Framer bought speed for the first version. Astro bought control for the current version.

The move was not a rejection of visual builders. It was a recognition that the site had changed jobs.

The public page is now only the visible layer. Under it sits the actual system: MDX, components, routes, i18n, deploy checks, crawler access, production verification, and a workflow where agents can make changes without breaking the shape of the site.

That system is worth owning.

The debt inside it is also worth naming.

That is the honest version of the migration.


Related: How I rebuilt my portfolio with Astro and Cloudflare Pages · Cloudflare migration: what you get beyond hosting · GTM Tools: Build vs Buy Decision Framework for Operators

About the author

Wojciech Łuszczyński

Wojciech Łuszczyński

GTM Architect and Growth Operator building AI-native revenue systems for B2B SaaS and technology companies. I connect positioning, SEO, content, paid acquisition, CRM, automation, analytics and AI workflows into practical growth infrastructure.

Newsletter

Get the next one first.

When I publish a new article on AI systems, GTM architecture, or growth operating models — you'll be the first to know.

Subscribe