WRITING / 29 ENTRIES

Notes from the build.

Web development, remote work, and what I learn shipping products — written down so I (and maybe you) don’t relearn it twice.

FEATURED

ALL ENTRIES

10AUG
LinuxServersDebugging

Disk Fills Up at 3am: How to Actually Diagnose It

df -h says 0 bytes free. Nothing obvious changed. Here's the sequence of commands I run — in order — to find the actual cause before it becomes a repeat incident.

7 min read
13JUL
SecurityFlaskPython

JWT Refresh Tokens: Where Short Expiry Goes Wrong

Short-lived access tokens feel secure. Refresh tokens that last 30 days and can't be invalidated mean your sessions are effectively permanent. Here's where that assumption breaks — and what the implementation actually looks like.

8 min read
29JUN
FlaskPythonnginx

Flask Rate Limiting Behind nginx: You're Rate-Limiting the Wrong IP

Flask-Limiter looks correct in development. Behind nginx in production, request.remote_addr returns the proxy's address — so your per-IP limits apply to a single bucket shared by all users.

7 min read
23JUN
PythonSQLAlchemySecurity

SQL Injection in 2026: What SQLAlchemy Still Can't Protect Against

SQLAlchemy's ORM parameterizes filter conditions and insert values. It does not parameterize column names, table names, or any raw SQL you write with text(). Four patterns appear regularly in Flask apps where the ORM assumption silently breaks.

7 min read
15JUN
Vue.jsTypeScriptGSAP

Vue 3.5's useTemplateRef Makes DOM Animation Code Cleaner

The old ref<HTMLElement | null>(null) pattern works, but TypeScript fights you at every null check that can never actually happen. useTemplateRef removes the noise and makes composable-level DOM access finally clean.

6 min read
08JUN
Vue.jsVue 3Web Development

Vue 3.4's defineModel: The v-model Boilerplate Is Gone

Building custom form components in Vue 3 meant writing the same four lines every time: modelValue prop, update:modelValue emit, computed getter, computed setter. defineModel collapses all of it into one macro call.

6 min read
01JUN
NuxtVue.jsMigration

Migrating from Nuxt 3 to Nuxt 4: What Actually Broke

I migrated this portfolio from Nuxt 3 to Nuxt 4 over a weekend. The big changes are well documented. Here's what caught me off guard — and the order to do it in.

7 min read
25MAY
NuxtVue.jsWeb Development

What Nuxt 4 Actually Changed (and What to Do About It)

I built this portfolio on Nuxt 4 instead of 3. Most tutorials are still written for 3. Here's what bit me — the srcDir default, the import.meta.client migration, and why compatibilityDate exists.

6 min read
18MAY
Vue.jsWeb DevelopmentTypeScript

Drag-and-Drop File Upload in Vue 3 Without a Library

Every PDF tool on this site needs a file drop zone. I built one without a library — and spent more time on the dragenter/dragleave child-element bug than on everything else combined.

6 min read
11MAY
GSAPLenisNuxt

The Two Lines That Make Lenis and GSAP ScrollTrigger Work Together

GSAP ScrollTrigger reads window.scrollY. Lenis overrides window.scrollY. The result is animations triggering at the wrong position — until you sync them through the GSAP ticker.

7 min read
11MAY
Vue.jsComposablesNuxt

Vue 3 Composables: The Right Pattern for Wrapping Third-Party Libraries

Every time I reach for a complex third-party library in Vue, I wrap it in a composable. Here's the full pattern — lifecycle, singletons, SSR guards — from building the PDF tools on this site.

7 min read
09MAY
PDF ToolsImage ToolsTutorial

Convert Images to PDF (and Back) Without Installing Anything

A practical guide to bundling photos into a single PDF, extracting images from PDFs, and resizing them — all from your browser, all without uploads.

6 min read
07MAY
PDF ToolsTutorialFile Size

How to Compress a PDF Without Wrecking the Quality

Why PDFs balloon to 50MB when they shouldn't, what compression actually does to your file, and how to shrink one without turning the text into mush.

7 min read
05MAY
PDF ToolsPrivacyTutorial

How to Merge PDFs Without Uploading Them to a Random Website

Most online PDF mergers want your files on their servers. Here's how to combine PDFs locally — fast, free, and without sending your documents into the void.

6 min read
27DEC
Remote JobsCareerSoftware Development

How Software Developers Can Actually Get Remote Jobs in 2025

Remote jobs are more competitive than ever. This guide breaks down what really works for developers trying to land remote roles in 2025.

11 min read
05OCT
GSAPNuxtAnimations

Smooth Scroll Animations with GSAP and Nuxt 3

Learn how to create buttery-smooth scroll animations using GSAP's ScrollTrigger plugin in a Nuxt 3 application.

6 min read
18SEP
TypeScriptVue.jsType Safety

Mastering TypeScript in Vue 3: A Practical Guide

TypeScript and Vue 3 are a perfect match. Here's how to leverage TypeScript's power without fighting the framework.

6 min read
10AUG
Vue.jsDark ModeUX

Implementing Dark Mode with System Preference Support

Build a robust dark mode system that respects user preferences, persists across sessions, and handles system theme changes.

5 min read