Building in public
Contents
This first post in the series covers what the site is, how its code is organised, and what each tool behind it does. It also covers how the posts in the series are written, and the dev log they're written from.
New terms get a short plain-English explanation in brackets.
Goals
- Describe what building in public means, and how this series does it.
- Describe how the site's code is organised into apps in one repository.
- Tell which tool behind the site is responsible for what.
- Describe how the posts in this series are structured.
1. Building in public
This series follows the building of this site, from an empty domain to a working blog. Each post covers one stage: what was built, why it was built that way, and what went wrong along the way.
That's called building in public [sharing work while it's in progress, rather than only showing the finished result].
I teach a range of technologies, and building this site keeps teaching me new things. When I learn something, I want to share it, and these posts are where I do that.
Tutorials often leave out the parts where things break. This series includes them, with the actual error messages, what caused each one and how it was fixed. A deploy that fails because of a misspelled command, or a Worker name that doesn't match its config, is a more useful example than a setup that worked the first time.
2. What the site is
2.1 Two apps in one repository
The site has two parts so far: the landing page, and this blog. Both are part of one app. A second app, a private platform for writing and managing posts, is planned but not built yet. Until it exists, posts are Markdown files stored alongside the site's code.
Both apps live in one repository [a project's files, together with a record of every change ever made to them, kept by git]:
portfolio/
apps/
client/ the public site: the landing page and this blog
management/ the private writing platform (planned, empty for now)
docs/
devlog.md a log of every meaningful change
writing-style.md how the posts are written
package.json lists the apps as workspaces
That's called a monorepo [one repository holding several apps or packages].
The two apps will share the site's theme and the code that reads posts, so keeping them in one repository means that code is written once rather than copied. Each app is still built and deployed on its own.
npm supports this directly, through workspaces [npm's way of managing several packages in one repository]. The root package.json lists the folders that are apps:
"workspaces": ["apps/*"]
Running npm install at the root installs the dependencies for every app at once, and npm run dev -w client runs a script in just one of them.
2.2 The tools behind it
You don't need to know these yet. Each one is explained properly in the part of the series where it first matters.
| Tool | What it does for this site |
|---|---|
| Next.js | A framework for building websites with React. It handles the pages, the routing [which URL shows which page], and building the site for production. |
| Cloudflare Workers | Where the site runs. A Worker is code that Cloudflare runs in the data centre nearest to whoever is visiting, rather than on one server that's always on. |
| OpenNext | An adapter that converts a Next.js app so it can run on Workers. |
| git | A version control tool [a tool that records every change to a project's files, so the full history is kept and any change can be undone]. Each saved change is a commit [a snapshot of the changed files, with a message saying what changed and why]. |
| GitHub | A website that hosts git repositories. The repository on my laptop is copied there with a push [sending your commits to GitHub], which backs it up and lets other services, such as Cloudflare, read it. Every change is made on a branch [a separate line of commits], and reviewed in a pull request [a page on GitHub showing every changed line, to approve before it's merged] before it goes into main, the branch that goes live. |
| Markdown | The format the posts are written in: plain text, with symbols such as ## for headings and - for list items. |
| Claude Code | An AI coding assistant. It writes most of the code, while I decide what to build, review every change, and handle the parts it can't reach, such as Cloudflare's dashboard. |
The next post, Building, deploying and CI/CD on Cloudflare Workers, covers how these fit together: how the site is built, how it runs on Cloudflare, and how a merged pull request goes live.
3. How the posts are written
3.1 Each post is a lesson
Each post in this series is written much like the lessons I write for my classes, a little less formally:
- It opens with a summary of what the post covers, and a short list of goals.
- Each new term is explained in plain English, in brackets, the first time it appears, like monorepo above. If you're new to web development, you should be able to follow along. If you're not, the brackets are short enough to skip.
- The examples are the real ones: the actual error messages, config files and commands from building this site.
- Where a post relies on documentation, it quotes it and links to it, and lists every source at the end.
- It ends with a summary of the key ideas, one at a time.
3.2 The dev log
The posts are written from a dev log [a running record of changes to a project, with the reasons for them]. It's a file in the repository, docs/devlog.md, and every meaningful change to the site gets an entry: a new feature, a configuration change, a new dependency, or a decision about how something should work.
Each entry has the same parts:
## 2026-11-09: Folders define the blog's structure
**What:** Posts moved from one flat `content/blog/` folder into ...
**Why:** A flat folder doesn't show which posts belong together, ...
**Teach it:**
- **One source of truth** [one place where a fact is recorded, ...]. ...
**Status:** Tested: ...
- What names what changed, and which files.
- Why gives the reason, or the trade-off.
- Teach it lists the ideas behind the change worth explaining to someone learning it, with the same plain-English brackets.
- Status says honestly what was and wasn't tested.
Writing the entry at the time of the change means the reasons are recorded while they're still remembered. The posts are then written from the log, rather than from memory.
4. The Foundations series
Foundations covers the first version of the site, in three parts:
- Building in public (this post): what the site is, how its code is organised, and how the series is written.
- Building, deploying and CI/CD on Cloudflare Workers: what building and deploying involve, how the site runs on Cloudflare Workers, and how every merge to
maingoes live, with each problem that came up while setting it up. - How this blog is organised: collections, series and tags, how they're stored in folders and checked before publishing, and how to structure content like this yourself.
5. Summary
Building in public means sharing the work while it's in progress. In this series, that means each stage of the site, including what went wrong and how it was fixed.
One repository can hold several apps. The public site and the planned writing platform share a repository, using npm workspaces, so shared code is written once while each app still deploys on its own.
Each tool has one job. Next.js builds the site, OpenNext adapts it for Cloudflare Workers, Workers runs it, GitHub holds the code and its review process, and the posts are Markdown.
The posts are lessons, written from a dev log. Every change is recorded with what changed, why, and what's worth teaching, and the posts are built from those records.
6. Sources
- Next.js Docs, Next.js Docs
- Cloudflare Docs, How Workers works
- npm Docs, workspaces