Tech

A selective view of the technologies I trust most in production. This is less a catalog of everything I have touched, and more a record of the tools that keep showing up when the work needs to be clear, durable, and ready to ship.

The priorities here come from the work itself. Across recent roles and projects, the pattern is consistent: Go for service design, TypeScript and Next.js for product surfaces, Docker and Kubernetes for delivery, and Python when the problem turns analytical.

I still value breadth, but this page favors recurrence over novelty. If a tool appears here, it is because I trust it enough to keep reaching for it under real constraints.

For the surrounding context, the experience page shows where this stack was used, and selected work shows what it produced.

Default frontend stack

TypeScript product surfaces

This is the part of the stack I reach for when the product surface needs to stay fast to build, easy to reason about, and stable after the first release.

Next.js with the App Router is the center of gravity. It gives me a clean way to mix server-first rendering, typed application code, and pragmatic delivery without turning the project into ceremony.

Around that, I usually keep the UI layer restrained: Tailwind CSS for control, shadcn/ui and Radix UI for accessible primitives, then TanStack Query, Zustand, NextAuth, tRPC, and Zod when the product needs stronger client-state, auth, transport, or validation boundaries.

  • TypeScript
  • Next.js
  • React
  • Tailwind CSS
  • shadcn/ui
  • Radix UI
  • TanStack Query
  • zt
    Zustand
  • NextAuth
  • tRPC
  • Zod

Backend and systems work

Go services and delivery

The more a system needs clear boundaries, operational reliability, and predictable long-term behavior, the more likely I am to move toward Go and explicit service design.

The backend work I enjoy most is not just writing handlers. It is shaping services so the model stays understandable under pressure: domain boundaries that make sense, interfaces that age well, and deployment paths that do not become a source of drama later.

That usually means Go, DDD-flavored service structure, OpenAPI-driven contracts, and infrastructure that is boring in the right way: Docker, Kubernetes, VPS environments, Linux, and familiar relational storage.

  • Go
  • DDD
  • OpenAPI
  • Docker
  • Kubernetes
  • PostgreSQL
  • Prisma
  • Redis
  • Turso
  • Linux
  • Git

When the problem is analytical

Data and applied AI

Python remains the tool I use when the work shifts from product flow into analysis, experiments, and lightweight machine learning.

I do not treat data work as a separate identity from engineering. It is another way of making decisions concrete: inspect the shape of the data, build the smallest useful model, and give the result an interface people can actually use.

Most of that work stays practical. Pandas, scikit-learn, and Streamlit cover a lot when the goal is analysis, iteration, and clear delivery rather than research theater.

  • Python
  • Pandas
  • scikit-learn
  • Streamlit
  • Data analysis
  • Machine learning

Tools I keep close

Operational defaults

A good stack is not only frameworks and runtimes. It is also the smaller tools that make execution cleaner, review easier, and maintenance less expensive.

For testing and reliability work, I prefer lightweight tools that pull their weight. Vitest and Playwright are usually enough for fast feedback and end-to-end confidence without inflating the setup.

For day-to-day work, I still prefer the terminal as a first-class place to think. Bash, Zsh, Neovim, and VS Code all have their place, but I lean toward the tools that stay out of the way once the real work starts.

  • Vitest
  • Playwright
  • Bash
  • Zsh
  • Neovim
  • VS Code