I get asked about my stack a lot, and I used to answer with whatever sounded current. That made my answers unreliable. A few months ago I started keeping a single inventory of what I actually build with, not what I think about building with. This post is that inventory.

It is not a prediction. It is what I use on this site and on the projects I ship in 2026.

Why a written inventory helps

When I do not write this down, three things happen:

  • I recommend tools I have not used in months.
  • I switch stacks mid-project because something new looks interesting.
  • I cannot explain why I chose one tool over another.

A written inventory fixes that. It is just a reference I can point to and update when my real choices change.

Languages and runtime

ToolRoleWhy I keep it
TypeScriptPrimary languageCatches shape errors before runtime; same language across frontend and Node scripts
JavaScriptBrowser and quick scriptsStill the runtime target; useful for small glue code and Gatsby configuration
Node.jsRuntimeHosting compatibility and the package ecosystem I already know
BashAutomationDeployment scripts, CI one-liners, and local shortcuts

I do not try to learn a new language for every project. TypeScript covers most of what I build. I reach for something else only when the project genuinely requires it.

Frontend framework and site generator

ToolRoleWhy I keep it
GatsbyStatic site generatorGraphQL data layer, fast builds, and image pipeline I already understand
ReactUI libraryComponent model I have used for years; huge ecosystem
Next.jsApp-like projectsBetter fit when I need dynamic routing, server components, or heavy client state

Gatsby runs this site. Next.js is what I reach for when the project feels more like an app than a content site. The decision usually comes down to whether the content or the interaction is the star.

Styling and design tokens

ToolRoleWhy I keep it
Tailwind CSSUtility stylingFast layout work without leaving the markup
Custom CSS variablesTheme tokensLight/dark mode and accent colors in one controlled layer
Theme UIBase primitivesConsistent spacing and typography defaults I can override when needed

I use Tailwind for speed and custom variables for control. I do not want a component library to own my tokens, so I keep the design system in CSS and apply it with Tailwind utilities.

Animation and interaction

ToolRoleWhy I keep it
GSAP + ScrollTriggerScroll-driven animationFine-grained control over reveal and parallax effects
CSS scroll-timelineProgressive enhancementNative performance where supported, no JS overhead

GSAP is my default for anything complex. CSS scroll-timeline is the fallback and enhancement I add when browser support is good enough.

Deployment, hosting, and services

ToolRoleWhy I keep it
NetlifyHostingBranch previews, redirects, identity widget, serverless functions
sharpImage processingReliable and pinned to avoid the upgrade churn I have hit before
Netlify IdentityAuthFits the hosting stack; simple widget for protected routes
Git + GitHubVersion controlStandard, familiar, good CI integration

Netlify is the simplest path from a Git push to a live site for my content projects. I use GitHub Actions when I need custom build or deploy steps.

Content and data

ToolRoleWhy I keep it
MDXBlog and page contentLets me write posts with JSX components and keeps content in version control
SupabaseQuick database prototypeFastest path to persisted state in a demo
JSON filesTiny data needsNo setup when the dataset is small and read-only

MDX is what you are reading right now. I only add a real database when the project needs authentication, real-time updates, or relational data.

Execution process checkpoint illustration for this section.

Where I intentionally deviate

SituationI switch toWhy
Tiny static landing pagePlain HTML + Tailwind CDN or ViteFaster boot than Gatsby for one-pagers
Heavy client-side interactivityNext.js App Router or Vite + ReactBetter fit for dynamic routing and app-like behavior
Long-running background taskDocker on a VPS or AWS LambdaNetlify functions are great for short tasks, not long workers
Quick database prototypeSupabase or a JSON fileFastest path to persisted state in a demo
Native mobile experimentReact NativeI am not great at it yet, but it is the fastest way to get a real app on a phone

The pattern is simple: I start with the default stack, then switch only when the project genuinely needs something else. Not when I am bored.

Tools I tried but did not keep

I have used a lot of frameworks over the last few years. Here is where some of them landed:

  • Prisma: Great DX, but I usually do not need an ORM on small projects. Raw SQL or a thin query layer is enough.
  • shadcn/ui: Good components. I use it as inspiration more than a dependency because I want to own my CSS tokens.
  • Bun: Fast. I use it for scripts, but I still deploy Node because hosting compatibility matters more than local speed.
  • Redux/Zustand: Rarely needed now. Server state or URL state usually covers what I used to put in global stores.

This list is not criticism. These tools are good. They are just not my defaults.

The most common mistake I make

The biggest mistake I make is switching tools before I understand the one I am using. I have abandoned perfectly good stacks because a new release got attention, then regretted it two weeks later.

The rule I try to follow now: use the default for at least two projects before switching. That gives me enough real feedback to know whether a tool is actually better for my workflow, or just newer.

Delivery workflow checkpoint illustration for this section.

Closing

A stack inventory is not exciting. It is useful. If you do not have one, write yours down. Keep it honest. Update it when your real choices change, not when your social feed changes.

If you want to see this stack in action, you are already looking at it.