DEV Community

Cover image for I Decided to Build It. Then I Had to Actually Decide How.
Iris Khan
Iris Khan

Posted on

I Decided to Build It. Then I Had to Actually Decide How.

Last time, I decided to stop overthinking and start building Fontly, a free copy-paste font generator. Before writing a single line of the actual tool, I had to make a decision I thought would be quick and ended up being the thing I spent the most time on: the tech stack.

Here's how that thinking actually went.

Starting point: "just make it a static site"

My first instinct was the simplest possible option: a plain static site. No framework, no build step, just HTML/CSS/JS. For a small tool like this, that felt like the obvious beginner-friendly choice, and honestly, most "how to build your first project" advice points exactly there.

For a single page with one tool on it, that instinct isn't wrong. But the more I thought about where this project needed to go, the more that plan started to strain.

Where plain static started to break down

A few things I kept running into when I actually mapped out what Fontly needed, beyond just "the tool works":

  • This isn't going to stay one page: To be findable at all, a font generator needs supporting content: explainer pages, FAQs, maybe category-specific pages down the line, and hand-writing and hand-linking a growing pile of HTML files gets messy fast, with no structure keeping it consistent.
  • SEO isn't just meta tags: Clean semantic markup, sitemaps, fast load times, and consistent page structure all matter, and doing all of that by hand, correctly, on every new page is exactly the kind of repetitive work that's easy to get subtly wrong as a beginner.
  • Content and code kept wanting to be separate: The actual words on the page (headings, FAQ answers, descriptions) are things I want to be able to edit and expand without touching layout code every time.

That last point was the real turning point. I didn't need "a framework" for the sake of having one, I needed a way to manage content that wasn't tangled up with markup.

Why Astro specifically

Once I framed it as a content-management problem rather than an app-building problem, Astro made sense for a few specific reasons:

  1. Content collections: Astro lets me define structured content (pages, FAQ entries, future blog posts) separately from how they're rendered, so adding a new page later means adding content, not rewriting HTML.
  2. Ships minimal JavaScript by default: Unlike a full app framework, Astro renders to static HTML and only sends JavaScript for the parts that actually need interactivity, like the font-conversion tool itself. That matters for both load speed and SEO.
  3. SEO fundamentals are built in, not bolted on: sitemap generation, clean output, and a structure that doesn't fight against good practices by default.
  4. It's still simple underneath: The interactive logic is still plain TypeScript/JavaScript, Astro isn't replacing that, it's just handling the structure and content around it in a way that scales better than hand-written HTML would have.

The honest tradeoff

This wasn't a free upgrade. Astro means a build step, a bit of a learning curve, and more moving pieces than plain HTML/CSS/JS, genuinely more than I needed for day one. I went with it anyway because I was planning for where the project needed to go (more content, better SEO structure, room to grow) rather than just what got something on screen fastest.

Version control: Git and GitHub, before there was much to version

I set up Git and pushed to GitHub before I'd really written anything worth backing up. That felt slightly premature at the time, but a few reasons made it worth doing early instead of "later, once there's real code":

  • Cursor makes mistakes, and I make more: Since I'm leaning heavily on an AI coding assistant while still learning, I wanted the ability to undo a bad change without panicking, so I could commit often and roll back if needed.
  • It's the foundation everything else plugs into: Automatic deployment (more on that below) needs a repo to deploy from. Setting it up early meant that piece was just already there when I needed it, instead of being one more thing to configure later under pressure.
  • Habit-forming: As a beginner, if I don't build the habit of committing early, I don't build it at all. Starting on day one made it the default instead of an afterthought.

Nothing fancy here, just a repo, sensible commits, and a .gitignore so generated files and dependencies don't get tracked.

Hosting: why Cloudflare Pages specifically

For hosting, I wanted something that matched the "boring and reliable" philosophy of the rest of the stack. I picked Cloudflare Pages for a few concrete reasons:

  1. Git-connected deploys: It builds and deploys straight from my GitHub repo: push to main, and the live site updates automatically. No manual uploads, no separate deploy step to remember.
  2. Built for static/content sites like this one: Since Astro outputs mostly static files, Cloudflare Pages is a natural fit, it's designed around exactly that kind of output rather than needing a server running.
  3. Fast by default, globally: Cloudflare's network means the site loads quickly regardless of where a visitor is, without me having to configure a CDN separately, which matters for both user experience and page-speed-related SEO signals.
  4. Generous free tier: For a project at this stage, I don't want infrastructure cost to be something I'm thinking about yet. Cloudflare Pages' free tier is enough that I can put that concern aside entirely for now.

The combination, GitHub for version control and Cloudflare Pages for deployment, means my workflow is just: write code, commit, push, and the live site updates on its own a minute later. No manual steps in between to forget or mess up.

What's next

With that decision made, the next posts get into the actual build, starting with hosting and workflow decisions, then the tool itself.

Anyone else gone back and forth between "keep it simple" and "build it for where it's going"? Where do you usually land?

Top comments (0)