Skip to content

Uses

Hardware, software, and tools I use every day.

Hardware

My main machine is a MacBook Pro M1 — the one I reach for everything. It handles local dev, Docker containers, and build pipelines without breaking a sweat. I don't run an external monitor at my desk; the built-in display is good enough and I move around too much to justify the setup.

For input I use an Apple Magic Keyboard (full-size with numeric pad) and a Magic Mouse. Not the most ergonomic setup, but it stays out of the way and pairing is instant when I switch between machines.

Headphones are Sony WH-1000XM4 — essential for deep work in a busy office. Nothing fancy on the audio side beyond that.

Editor + Terminal

My editor is VS Code with the following extensions doing real work day-to-day:

  • Volar — Vue 3 language support (replaces Vetur)
  • ESLint — inline lint feedback, especially useful for the flat config setup in this project
  • Prettier — format on save; I configure it to run on .vue, .ts, .md
  • GitLens — blame annotations and history navigation without leaving the editor
  • REST Client — quick HTTP requests from .http files without opening Postman

Theme is One Dark Pro. Font is JetBrains Mono at 14px with ligatures enabled — the ligature for => and !== alone justify the install.

Terminal is iTerm2 with the Minimal theme. I spend most of my time in the integrated VS Code terminal for project work and only switch to iTerm2 when I need multiple persistent sessions (e.g., dev server + wrangler + a watch script running in parallel).

Shell + CLI

Shell is zsh with oh-my-zsh. Active plugins: git, zsh-autosuggestions, zsh-syntax-highlighting. Prompt is Powerlevel10k — the lean config, not the full glyphs-everywhere version.

Tools I actually use and would miss if they were gone:

  • git — obviously
  • wrangler — Cloudflare Pages deploys and local preview; used daily during this site's build phases
  • jq — piping JSON from API responses without opening a browser devtools panel
  • fzf — fuzzy history search (Ctrl-R) and cd autocomplete; changes how you use the shell
  • ripgrep (rg) — faster grep; I alias grep to rg on all machines
  • curl — for quick API checks before writing the actual fetch call
  • npm / node — Node 22 pinned via .node-version, managed via nvm

Core dev stack

At Privy I work primarily as a System Engineer, which means Go services and infrastructure are a big part of the day job. This site is TypeScript/Nuxt, but my actual polyglot reality:

  • Languages: TypeScript (frontend + Nuxt tooling), Go (backend services at work), Shell (automation, CI scripts)
  • Runtime: Node.js 22 (pinned via .node-version — Cloudflare Pages Build v3 reads this file, not package.json#engines.node)
  • Frameworks: Nuxt 3 + Vue 3 for this site; Echo or standard net/http for Go services
  • Databases: Cloudflare D1 (SQLite) for this site's content layer via Nuxt Content v3; PostgreSQL and Redis at Privy
  • Infrastructure: Cloudflare Pages for this site (Nitro cloudflare_pages preset); Docker + Kubernetes in the Privy environment

Package manager for this project is npm locked to 10.9.2 via corepack. There was a yarn.lock in the repo at one point — removed to eliminate toolchain confusion.

AI tools

Claude Code is in my daily workflow for this site's build. I use it via the GSD (Get Shit Done) command system which produces planning artifacts and then spawns executor agents to implement them. The value isn't "write code for me" — it's that the planning/execution loop surfaces decisions before they become bugs and keeps context across multiple sessions.

For in-editor completions I use GitHub Copilot. It's most useful for filling out repetitive TypeScript types, generating test cases I'd otherwise skip, and autocompleting Tailwind class strings where the pattern is obvious. I turn it off in markdown files where the suggestions are usually wrong.

Where AI genuinely helps:

  • Rubber-ducking a design decision out loud before writing any code
  • First drafts of documentation (then edited — AI prose is too generic to ship raw)
  • Generating the boilerplate of a new pattern (then I read it and understand it before committing)

Where I don't trust it:

  • Security-sensitive code — I read every line
  • Anything touching the Cloudflare D1 schema — the nuances of D1's SQLite dialect bite if you're not careful

Hosting + deployment

This site runs on Cloudflare Pages with Nuxt 3 and the Nitro cloudflare_pages preset. The build output is a _worker.js bundle that Cloudflare's edge network executes. Deploy command is wrangler pages deploy ./dist via the pages:deploy npm script.

Deployment tool is wrangler v4 (pinned in package.json). The local preview workflow is npm run pages:preview which builds and runs wrangler against the dist/ output — much closer to production than npm run dev.

Two Cloudflare dashboard settings that must stay OFF on this project (they're enabled by default and both break Vue SSR hydration): Rocket Loader and Email Address Obfuscation. They can't be set via wrangler.toml — they live in the dashboard under Speed and Security respectively.

For other personal projects I use Fly.io for small Go services where I need persistent compute. Nothing elaborate — just a couple of apps that need to stay awake without a serverless cold-start penalty.