
My Tech Stack in the Age of AI
Towards the end of 2023 I began teaching myself Golang because I was so dead inside from writing React and frontend related code. You can only change the color of a button for a stakeholder so many times before you want to choke them out. I also started spending more time with Svelte and SvelteKit during that same stretch.
That shift happened to coincide with something else: the LLM gold rush. The models pouring out of every lab were trained on billions of lines of Python, TypeScript, React, and Next.js. Which means they are very good at generating code in those languages. It also means those billions of lines of code carry every bad pattern, outdated convention, and half-baked Stack Overflow answer that has ever existed on the internet.
I made a deliberate choice to step off that conveyor belt. Here is what I landed on and why.
SvelteKit + TypeScript
SvelteKit does not feel like it is trying to do everything at once. That sounds like a low bar, but after years of Next.js, it is actually a meaningful one. I can opt into the features I need for a given project and ignore the ones I do not. The ecosystem is mature, the documentation is solid, and there is a dedicated Svelte MCP server with solid resources for use with LLMs. Writing Svelte after years of React is the difference between assembling furniture with the right tools versus a butter knife.
TailwindCSS + Shadcn-Svelte
Tailwind has been in my stack since 2021 and it is not going anywhere. At this point it is the default utility CSS solution and LLMs have been trained on it so heavily that it is often the first thing they reach for. That works in my favor. I used shadcn/ui when I was working on Next.js projects and found a Svelte port, Shadcn-Svelte. Nice component primitives and low overhead. It gets the job done for cheap and I can customize what I need.
DrizzleORM + libSQL / Turso
Most applications do not need a Postgres cluster. A SQLite file can carry a surprising amount of weight before you ever need to think about scaling up, and Drizzle makes working with it feel clean without burying you in abstraction.
The part I am most enthusiastic about is the testing story. I do not mock the database anymore. I spin up a test.db, run actual database transactions against it, and tear it down when the suite is done. No mocks, no divergence between what tests say and what production does. There is a lot of ceremony involved in setting up a proper test database in Postgres. With Turso and libSQL that overhead is essentially zero.
Beyond the technical fit, I am genuinely a fan of what Turso is doing in the open source community. I am team Turso.
Tanstack Form + Tanstack Query
Tanstack Form and Tanstack Query are not things I reach for on every project. SvelteKit handles a lot out of the box. But when I want more client-side reactivity (complex form state, optimistic updates, fine-grained cache control) these two plug in cleanly alongside SvelteKit’s SSR without fighting it. They are opt-in tools for opt-in problems, which fits how I think about the stack overall.
Vitest + Playwright
The honest answer here is that my test suites have shifted in purpose. LLMs are doing most of the actual coding now, which means tests serve less as a design tool and more as a sanity check. Vitest covers the unit and integration layer, including those real database transactions I mentioned above. Playwright covers the critical user flows. When an LLM ships a new feature, I want to know immediately if it introduced a regression in something that was already working. That is what Playwright is for.
Docker
I run Docker in production via Fly.io and I have moved to using it for local development as well. The original reason was sandboxing LLM-generated code. I did not want an agentic workflow with write access to my host machine. That is still a big part of it. But supply chain attacks have become a near-weekly occurrence and running local development inside a container adds a layer of isolation that costs almost nothing to set up. Security by default rather than security as an afterthought.
dotenvx
dotenvx solved a problem I did not fully appreciate until it solved it: I was constantly forgetting to add new environment variables to Fly.io when I added them locally.
The way it works now: I commit encrypted .env files directly to the repository. My .env.keys file lives in Proton Pass. In production, the only thing I need to add is the private key for the given environment. At runtime, dotenvx decrypts the .env file and supplies the container with everything it needs. New environment variable added locally? Commit the updated encrypted file. The key already in production handles the rest. It has eliminated an entire category of deployment mistakes.
Cloudflare Workers + Fly.io
My personal site is a static SvelteKit build deployed on Fly.io. Cloudflare Workers serve a different purpose: one-off integrations that do not need a dedicated server. A good example is the Forgejo feed feature I wrote about recently. That integration has a minimal surface area and a Worker is exactly the right tool for it. I am not spinning up a full server for a feature that size. Full-stack applications with real server needs go to Fly. Everything else finds the smallest container that fits.
Golang
Go is still mostly my one-off microservice and CLI tooling language. I wrote about going to the Gopher side and nothing has changed that read. The direction I am most interested in exploring next is embedded software development, specifically writing small Go programs that run on a Raspberry Pi. Nothing production-critical, just tinkering in that space. It is a corner of the language that does not get talked about much and I am curious about it.
AI in the Workflow
I have been using Claude Code since its initial release and paying for the $100/month plan. Before Claude Code shipped, I had already decided to go all in on Anthropic. Two reasons: they had the best models for coding, and it was already obvious they were building an ecosystem specifically designed to capture developers. Better to buy in early than to spend energy switching between competing solutions every six months.
The agentic workflows, skills, and tooling that have built up around it have been genuinely good for shipping. Writing robust features and getting them to production with more confidence that the job was done right. That has been the real value. A lot of that comes down to understanding how to actually leverage these tools rather than just throwing prompts at them and hoping for the best. Two courses that genuinely moved the needle for me: AI Coding for Real Engineers by Matt Pocock and Principled AI Coding by Indy Dev Dan. Both are worth your time.
That said, I am also paying close attention to local LLMs. It is not complicated. The AI bubble is real and the VC money is not going to last forever, regardless of how convenient that would be for anyone depending on it. What happens to my workflow when $100/month becomes $1,000/month? The market will correct eventually. The fever will break. AI will find its actual place in developer and product workflows rather than the everything-everywhere-all-at-once moment we are in now. I would rather understand how local tooling works before I need to rely on it than scramble when the economics shift. Right now I am running qwen3.5:2b via my Umbrel home server with Zed. Humble beginnings. But eventually, with the right hardware, the goal is to not be dependent on someone else’s pricing decisions.
Wrap Up
This is my stack for the foreseeable future. I am not swapping things out every few months. A big part of that is having agentic workflows already dialed in for all of it. The setup cost is paid. Now I just build.
Until next time,
Cody