How I built this site
The decisions behind building this portfolio with Astro, Sanity and AI-assisted development, and why AI speeds up the work without making the calls.
By Daniel Shires · October 26, 2026
I wanted this portfolio to be more than a collection of case studies. It’s a place to share my work, explore ideas and document what I’m learning along the way.
That means the site needs to do a few things well: make the work easy to find, keep the experience simple, and make publishing and experimenting straightforward.
I approached building it the same way I approach product design: start with the needs, make deliberate decisions about the system, and keep unnecessary complexity out of the experience.
01 — Start with the right foundations
The site is built with Astro, which generates the pages ahead of time. That keeps the experience fast without needing the browser to assemble every page when someone visits.
I use React for the interactive parts: the light and dark theme, the homepage status line, the avatar experiment and a handful of controls. Everything else stays as simple as possible.
The principle is straightforward: use complexity where it creates value, not by default.
Tailwind handles styling, Inter provides the main typography, and IBM Plex Mono gives labels a more technical feel. A small set of colour variables controls the light and dark themes.
These decisions give the site a consistent visual language without making every new page a design exercise.
02 — Keep the experience focused
The navigation is deliberately short: Home, Projects, Thinking Out Loud, About and Experiments.
Each section has a clear purpose. Case studies present finished work; Experiments gives unfinished ideas room to develop. The two don’t need to pretend to be the same thing.
The navigation stays in place as the main content changes. Swup handles those transitions, with animation kept out of the way.
Visually, the site uses a near-white or near-black background with a subtle grain texture. It’s enough to give the interface some character without competing with the work.
The goal isn’t to make the interface invisible. It’s to make sure it supports what people came to see.
03 — Separate content from code
A portfolio changes over time. New projects get published, writing develops, and photographs come and go. Updating those things shouldn’t require rebuilding the site by hand.
Projects, writing, photographs and albums live in Sanity, a content management system. I can edit them through a Studio interface at /studio, while Astro turns that content into the pages visitors see.
Each content type follows a consistent structure, with fields for things like titles, dates, descriptions and images. That makes the content easier to manage and the site easier to extend.
The About page is a deliberate exception. Its introduction, experience and links live in the codebase because they’re closely tied to how the site presents me professionally.
I can also connect writing to shared concepts, customise search and social metadata, and exclude content from the sitemap when it shouldn’t be indexed.
The underlying idea is to make common changes easy without making the system harder to understand.
04 — Use AI to accelerate the work, not make the decisions
I use Cursor and ChatGPT throughout the development process. They help me explore approaches, write code, troubleshoot problems and move from an idea to a working experience more quickly.
But speed isn’t the same as good judgement.
Before a substantial change, I establish the constraints and ask for a plan. I want potential issues surfaced early, not after the implementation is finished. For smaller changes, I keep the scope narrow and reuse the patterns already in place.
I also review the result in the browser. A change that works on one page can still break another page using the same component. I check the relevant routes and follow the experience as a visitor would.
The tools help me build faster. Decisions about the audience, the experience and what should ship remain mine.
05 — Make shipping predictable
Netlify builds and deploys the site using Node.js. During the build, the project is checked and the static pages are generated. Type errors stop the deployment rather than slipping through unnoticed.
Images are processed with Sharp and served in AVIF format to reduce their size. Content is fetched from Sanity during the build, so the browser doesn’t need to assemble the writing and projects on the fly.
I also keep old routes working. For example, /journal redirects to /writing, preserving links after the section changed.
Publishing follows the same principle. Once I publish a new piece in Sanity, the site needs another build before the change appears publicly.
That small delay is a worthwhile trade-off for a simpler, statically generated experience.
What I learned
Building this site reinforced a principle I use in product design: a good system makes the right things easy and the wrong things harder to do accidentally.
The navigation has a clear purpose. Content and presentation have distinct responsibilities. Interactive elements earn their complexity. Reusable patterns keep the experience consistent.
AI has made it easier for me to move between design and development, but it hasn’t removed the need to make deliberate decisions, test assumptions and check the finished experience.
I don’t consider the site finished in the sense of being fixed. I’ll keep adding work, trying ideas and adjusting the system as I learn.
What matters is that it has a solid foundation to evolve from.