Coding
I build software that works well, is maintainable, and lets me move quickly without sacrificing quality. The tools, patterns, and principles I rely on keep my work clear, reliable, and focused on outcomes.
Philosophy
These principles guide how I approach building software. They help me maintain clarity, momentum, and usability, keeping projects manageable without adding friction.
- Accessibility isn't optional - Everything I ship should work for everyone, full stop.
- Readable code wins - Good names, clear structure, and small modules beat “clever” every day.
- DX should feel smooth - Local dev, deployments, and CI/CD should be effortless.
- Performance comes from understanding - Focus on solid architecture first, then optimise where it actually matters.
- Ship fast without breaking things - Short feedback loops, feature flags, and reversible decisions keep velocity high.
- Testing should feel purposeful - I focus on validating real behaviour and key flows, keeping tests meaningful and lightweight.
Core Technologies
Here's what I use to build web applications every day:
Framework (React and Next.js)
Next.js has been my go-to since 2020, paired with React, TypeScript, and pnpm to keep projects predictable, fast, and maintainable. It gives me a solid foundation for both server and client-rendered workflows.
Data fetching happens mostly in server components, as close to where the data is needed as possible, with caching applied intelligently. For client-side updates, I rely on SWR or React Query, depending on the problem’s shape.
Forms are built with react-hook-form and Zod, providing a lightweight, type-safe approach that keeps user input reliable and easy to manage.
Styling (Tailwind CSS and shadcn/ui)
Fast, maintainable styling is key, and Tailwind CSS lets me achieve that without wrestling with traditional CSS pitfalls. Its utility-first approach keeps markup clean and predictable.
On top of Tailwind, shadcn/ui provides reusable components and patterns, giving a solid foundation for consistent design while still allowing customisation where flexibility is needed.
This setup makes building interfaces intuitive and iteration-friendly, letting me focus on features rather than fighting styles, and keeping the UI maintainable.
Database & ORM (PostgreSQL and Drizzle ORM)
PostgreSQL handles production workloads reliably and flexibly, giving confidence in data integrity across projects. Its relational features make modeling complex domains straightforward.
Drizzle ORM provides a type-safe, lightweight layer for database interactions. Queries remain readable and maintainable without unnecessary abstraction.
Together, they let me iterate on features quickly, handle schema changes confidently, and maintain a predictable data layer that scales with the project.
Deployments (Vercel and GitHub Actions)
Shipping reliably shouldn’t require thinking about deployment steps. Vercel and GitHub Actions automate builds and deployments, keeping the process smooth and predictable.
Automation allows me to focus on coding rather than manual tasks, ensuring changes are delivered consistently and safely.
This setup keeps the feedback loop tight, enables safe rollbacks, and maintains steady project momentum, letting me ship features with confidence.
Other Technologies I've Worked With
I'm comfortable using these tools when the project calls for them:
- HTML
- CSS
- MUI
- Node.js
- Express.js
- NestJS
- Prisma
- TypeORM
- Strapi
- MongoDB
- Azure
- Azure Pipelines
- AWS