Field notes

Blog

Real engineering, written from production scars — not theory.

What it means to be a full stack engineer in the AI era

What being a full stack engineer in the AI era looks like after six years and 50+ products: owning the system end to end while AI agents write more of the code.

Read →

UX patterns for AI features: streaming and graceful failure

UX patterns for AI features from a real in-app assistant: paced streaming, agent status, record cards, confirm-before-create and graceful failure.

Read →

Prompt injection: securing LLM features in web apps

Prompt injection explained for web developers: securing LLM features with untrusted-input handling, least-privilege tools, permission gates and safe output.

Read →

Offline-first point of sale with IndexedDB and Dexie

Building an offline-first point of sale with IndexedDB and Dexie: local-first writes, a sync queue, idempotent server endpoints and the edge cases a POS hits.

Read →

Peer-to-peer file transfer in the browser with WebRTC

How WebRTC peer-to-peer file transfer works in the browser: WebSocket signaling, data channels, chunking with backpressure, and keeping files off the server.

Read →

Streaming LLM responses with Node.js and Server-Sent Events

How to stream LLM responses to the browser with Node.js and Server-Sent Events: an Express endpoint, status events, client readers, pacing and Nginx buffering.

Read →

Letting an AI agent test your Flutter app

How to let an AI agent test your Flutter app with Marionette, an MCP server that taps, types and screenshots a debug build, plus the keys and habits that help.

Read →

Running slow AI jobs in the background with queues

How to run slow AI jobs in the background with queues: a Postgres job table, workers with retries and backoff, run logging, alerts and status updates for users.

Read →

Context windows, memory and why AI agents forget

Why AI agents forget: how context windows work, where the token budget goes, and how summaries, retrieval memory and external state keep long runs on track.

Read →

Adding AI features to an existing SaaS without a rewrite

How to add AI features to an existing SaaS without a rewrite: a clear service boundary, tenant-scoped data, per-tenant rollout and humans confirming changes.

Read →

LLM API rate limits, retries and timeouts in Node.js

How to handle LLM API rate limits, retries and timeouts in Node.js: classify errors, back off with jitter, honor Retry-After and add a circuit breaker.

Read →

Multi-tenant SaaS architecture: lessons from four platforms

Multi-tenant SaaS architecture lessons from hospital, vehicle, compliance and retail platforms: tenant isolation, query scoping, access gates and defaults.

Read →

Deploying AI-powered Node.js apps on AWS

Deploying AI-powered Node.js apps on AWS: secrets for model API keys, GitHub OIDC deploys, and the ALB, Nginx and Node timeouts that break long LLM calls.

Read →

Human-in-the-loop AI: where people should stay in the loop

Human-in-the-loop AI design: how to decide where people review model output, route work with real signals, and build accept, edit and reject flows that last.

Read →

Caching LLM responses with Redis

How to cache LLM responses with Redis in Node.js: building exact-match cache keys, choosing TTLs, invalidating on change, and the caveats of semantic caching.

Read →

Keeping LLM API costs under control in Node.js

Practical ways to control LLM API costs in a Node.js backend: per-feature token tracking, budgets, Redis caching, model tiering, batching and user quotas.

Read →

Logging and observability for LLM features

LLM observability for production apps: log prompts and outputs with PII care, track token usage and latency, link calls with trace ids, and alert on failure.

Read →

Image processing pipelines with Sharp and S3

How I build image processing pipelines with Sharp and S3: validate uploads, re-encode only when needed, generate previews and keep originals private.

Read →

Building an LLM recommender that respects hard constraints

How to build an LLM-powered recommender that respects hard constraints: code enforces budget and compatibility, and the model only ranks and explains.

Read →

Writing specs that AI coding agents can actually follow

How to write specs AI coding agents can follow: clear scope, verified names, checkable acceptance criteria, edge cases and a definition of done they can run.

Read →

How to evaluate an LLM feature before you ship it

How to evaluate an LLM feature before you ship it: build a golden dataset, start with code assertions, use LLM-as-judge carefully, run regression evals in CI.

Read →

Deploy to AWS from GitHub Actions with OIDC, no stored keys

How to deploy to AWS from GitHub Actions with OIDC: the IAM identity provider, a role trust policy scoped to one repo and branch, and the workflow that uses it.

Read →

Building an AI MVP: what founders should scope first

A practical guide to building an AI MVP: pick one narrow job, check your data early, define how you will measure quality, and estimate cost per user first.

Read →

Adding AI features to Flutter apps without leaking API keys

How to add AI features to Flutter apps without leaking API keys: proxy every model call through your backend, authenticate users and rate limit per user.

Read →

Scraping product listings and extracting data with an LLM

How to scrape product listings politely and turn messy retailer pages into structured data, using rules first and an LLM with schema validation for the rest.

Read →

AI agent or deterministic workflow? How to choose

AI agent or deterministic workflow? A practical way to decide who owns control flow, when each one wins, and the hybrid pattern I default to in production.

Read →

How to roll out AI coding assistants across a team

A team lead's playbook for rolling out AI coding assistants: usage rules, shared conventions for agents, spec-first work and code reviews that keep the bar.

Read →

Generative AI for fashion imagery: model, pose and clothing

How I'd structure a generative AI fashion imagery pipeline that composes model, pose, background and clothing inputs into consistent, reviewable images.

Read →

AI document review: checking policies against a template

How I approach AI document review on a compliance platform: OCR uploaded policies, compare them to a template section by section, and explain each pass or fail.

Read →

Hybrid search: combining keyword and vector search for RAG

Hybrid search for RAG in Postgres: combine full-text keyword search with pgvector similarity and merge the two result lists with reciprocal rank fusion.

Read →

Spec-Driven Development in the age of AI coding assistants

Why Spec-Driven Development matters more with AI coding assistants: numbered specs, amendments, branch-per-spec and reviews that check the code against intent.

Read →

AI agent guardrails in production: permissions and approval

Guardrails for AI agents in production: permission gates before any database work, step and token budgets, confirm cards for writes, and audit logs to replay.

Read →

Prompt engineering for developers: a practical checklist

A prompt engineering checklist for developers shipping LLM features: role, context, constraints, examples, output format and evaluation, with TypeScript code.

Read →

Embeddings explained for web developers

Embeddings explained for web developers: what the vectors are, how cosine similarity works, and practical uses in search, dedupe and recommendations.

Read →

Shipping an AI assistant as a browser extension

How to ship an AI assistant as a browser extension with Manifest V3: service workers, content scripts, keeping API keys on the server, and store review.

Read →

Machine-readable engineering conventions for AI agents

How I make engineering conventions machine-readable for AI coding agents: rules grouped by platform, served from an MCP server, owned and reviewed by people.

Read →

Prompt chaining vs one giant prompt: when to split LLM calls

Prompt chaining vs a single prompt: the trade-offs in quality, latency, cost and debuggability, and the rules I use to decide when to split LLM calls.

Read →

Building a voice AI assistant with speech-to-text

A practical guide to building a voice AI assistant with speech-to-text: capturing audio, transcription, the LLM step, latency, and the dashboards around it.

Read →

Reviewing AI-generated tests: what to check before merging

A checklist for reviewing AI-generated tests: tests that mirror the implementation, logic mocked away, missing edge cases, and assertions that can never fail.

Read →

Chunking strategies for RAG: how to split documents

Chunking strategies for RAG compared: fixed size with overlap, structure-aware splitting and semantic chunking, with a TypeScript chunker and tuning advice.

Read →

Reliable JSON from LLMs: schema validation in TypeScript

How to get reliable JSON from LLMs in TypeScript: structured output modes, Zod schema validation, error feedback retries and a safe fallback path.

Read →

Model Context Protocol (MCP) explained for developers

Model Context Protocol (MCP) explained: how servers expose tools, resources and prompts to AI agents, how stdio and HTTP transports work, and what to secure.

Read →

How to block AI training crawlers with robots.txt

A practical robots.txt setup that blocks AI training crawlers and keeps search engines allowed, plus the limits of a voluntary opt-out and what enforces it.

Read →

AI pair programming for backend work: helps and fails

Where AI pair programming speeds up Node.js, TypeScript and PostgreSQL backend work, and where query plans, migrations and data decisions still need a human.

Read →

AI face-analysis app architecture: Flutter, Node.js, Python

How I'd architect an AI face-analysis app with a Flutter client, a Node.js backend and a Python model service, with privacy designed in from the first sprint.

Read →

Vector search in PostgreSQL with pgvector

How to set up vector search in PostgreSQL with pgvector: the extension, a vector column, HNSW or IVFFlat indexes, cosine distance queries and TypeORM.

Read →

Building a tool-using AI agent in TypeScript from scratch

Build a tool-using AI agent in TypeScript from scratch: the agent loop, Zod-validated tool calls, a step limit and error handling, with no framework needed.

Read →

How to validate LLM output before it reaches users

A layered approach to validating LLM output: schema checks, structural rules, cross-document consistency and safe failure paths before anything ships.

Read →

Using AI in code review without lowering the bar

How I use AI in code review as a team lead: what to hand the model, what stays with a human reviewer, and how to keep review standards from quietly slipping.

Read →

Running a Python AI microservice alongside a Node.js backend

How I'd split a product between a Node.js backend and a Python AI microservice: clear boundaries, timeouts, health checks and deploys that stay boring.

Read →

Retrieval-augmented generation (RAG) in Node.js

A practical guide to retrieval-augmented generation (RAG) in Node.js: ingest, chunk, embed, store in Postgres, retrieve, and prompt with cited sources.

Read →

Agentic AI explained: tools, loops and guardrails

Agentic AI explained for engineers: what an agent actually is, how the tool-calling loop works, and the guardrails that keep multi-step LLM systems safe.

Read →

Two-stage LLM pipeline: turning discovery notes into specs

How a two-stage LLM pipeline turns messy client discovery notes into an internal spec first, then into client, design and dev handoff documents.

Read →

Why I chose TypeORM over Prisma

A pragmatic look at why I picked TypeORM for a solo-maintained Node.js backend at scale, and when Prisma is the better call.

Read →

Spec-Driven Development: what it is and why I rolled it out across my team

How writing the spec before the code cut rework, sharpened reviews, and made shipping predictable for my team.

Read →

How I scaled a fitness platform to 60,000 users — solo

The database indexes, Redis caching, and N+1 fixes that took Buffdudes from slow to stable at 60K users.

Read →

Deploying Node.js to AWS Elastic Beanstalk with CI/CD

How I wired GitHub Actions to AWS Elastic Beanstalk and RDS, fronted by Nginx and Redis, for zero-downtime Node.js deploys.

Read →