Engineering writing
Build-logs and deep dives on the things I actually ship — multi-tenant SaaS, Next.js, payments, and AI integration.
AI-assisted UI validation: automating visual testing that survives layout change
Traditional E2E tests break the moment a layout shifts. Drawing on my MS thesis in AI-assisted UI validation, here's how to use vision models to validate UI intent — not brittle selectors — in a real CI/CD pipeline.
End-to-end tests that don't flake: a Playwright setup for complex React apps
Flaky E2E tests are worse than no tests — they train the team to ignore red. The Playwright practices that make end-to-end tests reliable: web-first assertions, role-based locators, controlled network, and no arbitrary waits.
Handling file uploads at scale with S3 presigned URLs
Routing uploads through your API server wastes bandwidth and memory and caps your file size. How to upload directly to S3 with presigned URLs — secure, scalable, and off your server's critical path.
Automatic Open Graph images in Next.js: better click-through without a designer
Every shared link is an ad for your page — a blank or generic preview wastes it. How to generate branded, per-page Open Graph images automatically in Next.js with the ImageResponse API, so every URL shares beautifully.
How to run a technical audit on an early-stage SaaS
A structured way to assess a young SaaS codebase for the things that actually threaten the business — security, scalability, performance and cost — and turn findings into a prioritized plan instead of a wall of complaints.
Real-time AI streaming with Server-Sent Events and TypeScript
Why AI chat should stream, and how to implement token-by-token streaming end to end with Server-Sent Events and typed TypeScript clients — including cancellation, backpressure and error handling.
Building an AI recruiter: matching that runs toward the candidate, not a search box on top of listings
Most job boards make candidates search, over and over. A build-log on RadiologyJobs' AI-recruiter layer: plain-English intent, postings scanned as they arrive and pushed to saved searches, and an employer dashboard built for bulk hiring.
Zero-downtime database migrations: shipping schema changes without a maintenance window
A naive migration locks a table and takes production down. The expand-and-contract pattern that lets you change schema safely while old and new code run side by side — no maintenance window, no dropped requests.
Deploying microfrontends on AWS with Module Federation, S3 and CloudFront
The deployment half of microfrontends: hosting independently-built React apps on S3 behind CloudFront, wiring Module Federation remotes, and shipping each microfrontend on its own pipeline without breaking the others.
Domain-based multi-tenancy: one repo, four markets, zero hardcoded country logic
How Taxi.club launched across France, UK, Italy and Spain from a single Next.js + NestJS codebase — resolving the tenant from the Host header and keeping country behavior in config, not branches, so a new market is data and not a deploy.
Getting reliable structured JSON out of LLMs with FastAPI and Pydantic
Parsing free-text from a model into your app is fragile. How to force LLMs to return schema-valid JSON every time using structured outputs, function calling, and Pydantic validation — so the model becomes a dependable part of your pipeline.
Programmatic SEO in Next.js: generating hundreds of landing pages the right way
How to generate large sets of high-intent landing pages from data in Next.js — one dynamic route, generateStaticParams, structured data and per-page OG images — without tripping Google's scaled-content-abuse policy.
What actually makes a senior software engineer
Seniority isn't years or syntax — it's judgment about the decisions that are expensive to change, owning outcomes instead of tickets, and making systems that survive in someone else's hands. What I've learned leading delivery across a nine-product portfolio.
PostgreSQL performance tuning for SaaS: the indexes that fix your slow endpoints
That slow API endpoint is almost never the framework — it's a missing index or an N+1 query. A practical guide to reading EXPLAIN, choosing the right indexes, and fixing the query patterns that quietly kill SaaS dashboards.
The CTO's dilemma: sharing code between a Next.js web app and a React Native mobile app
How to launch web and mobile on one budget by sharing business logic, types and API contracts across a Next.js and React Native monorepo — plus the parts you should not share, like auth-token storage.
Server-side conversion tracking: recovering the revenue GA4 can't see
Most paying customers were missing from conversion reports. A build-log on why client-side GTM drops events, and how server-side Measurement Protocol with deduplication and 3DS-aware tracking made conversion the source of truth again.
Securing LLM apps: defending against prompt injection in production
Prompt injection is the new injection attack, and your AI feature is exposed the moment it reads untrusted text or calls tools. A practical defense model — privilege separation, output handling, and tool guardrails — for real LLM apps.
The MVP blueprint: how to scope and ship a production-grade SaaS in four weeks
A senior engineer's method for shipping a real SaaS MVP fast without building throwaway code — scoping the smallest valuable slice, making the load-bearing decisions early, and shipping weekly.
Node.js vs FastAPI: choosing the right backend for your next product
A senior engineer's honest comparison of Node.js (Express/NestJS) and FastAPI for a new product — where each wins, where the ecosystem decides it, and why 'use both' is often the right answer.
Multi-currency billing done right: ECB FX sync and cent-accurate invoicing across 18 locales
A build-log of European commerce across six countries: syncing ECB exchange rates on a cron into persisted prices, cent-accurate multi-currency invoicing across 18 locales, and keeping billing auditable when rates move mid-session.
Fixing Core Web Vitals in Next.js: a performance playbook that moves conversions
LCP, CLS and INP aren't Lighthouse vanity — they're revenue. The concrete Next.js techniques I use to make pages load instantly: server-first rendering, image and font strategy, bundle discipline, and killing layout shift.
When (and how) to transition from a React monolith to microfrontends
Microfrontends are a scaling tool, not a default. A senior lead's guide to knowing when a React monolith actually warrants splitting, and how to do it safely with Module Federation, shared types and independent deploys.
Building a context-aware AI chatbot with a vector database (RAG done right)
A generic chatbot hallucinates; a retrieval-augmented one answers from your actual data. How to build RAG properly — chunking, embeddings, a vector database, and the retrieval quality work that decides whether it's useful.
Building a render-to-print pipeline with BullMQ, Puppeteer and content-hash caching
How I built hands-off personalized-book fulfillment: a queue-driven Puppeteer render on Redis/BullMQ, content-hash caching so identical orders never re-render, and HMAC-verified print webhooks to a fulfillment partner.
The Next.js technical SEO checklist for SaaS that actually ranks
SEO on Next.js is engineering, not a plugin. The concrete checklist I use to rank SaaS products: rendering strategy, Core Web Vitals, metadata and canonical/hreflang, structured data, and an internal-linking graph that avoids orphans.
Architecting a production-grade AI SaaS with Next.js and FastAPI
Most AI tutorials stop at the API call. This is the production architecture: a Next.js frontend, a FastAPI service for heavy model work, a queue so the UI never blocks, and streaming responses done in TypeScript.
How to add AI to your SaaS without runaway costs
A practical playbook for shipping LLM features that users trust and finance approves — narrow use case, retrieval grounding, right-sized models, caching, token budgets and evals.
Build-log: a multi-tenant, WPS-compliant payroll system
How I built Paylio — multi-tenant payroll with strict tenant isolation, integer-safe money, and locale-accurate invoicing across markets. The decisions that keep payroll correct.
What actually matters running the Next.js App Router in production
Lessons from shipping multiple products on the Next.js App Router — rendering per route, client components at the leaves, caching on purpose, and enforcing tenant scope on the server.
Payment webhooks the hard parts: idempotency, retries and reliability
Why payment webhooks break in production and the patterns that make them safe — signature verification, deduplication, idempotent handlers and queues. From real PSP integration work.
Multi-tenant SaaS: RLS vs schema-per-tenant vs database-per-tenant
The three ways to isolate tenant data in a SaaS, the real trade-offs, and how I choose — from someone who ships multi-tenant systems in production.
How I built a real-time, cookieless analytics console in Next.js
A build-log of the first-party analytics behind this site: cookieless tracking, a Postgres pipeline on a least-privilege role, and a real-time admin dashboard — no Google Analytics.