Technology

My "Full Stack" Stack

Diwaker Gupta
· 4 min read
Send by email

After much trial and error, this is the stack I've settled on for building "full stack" apps (mostly side projects and such):

  • Bun: bundler, test runner, package manager, Javascript runtime (Node replacement), HTTP and API server all-in-one. Bun is AWESOME!
  • React: UX foundation
  • Chakra UI: Rich components on top of React
  • sqlite: storage

I've setup a starter template for my own use. You can use it by running bun create diwakergupta/bun-react-chakra.

Read on for how and why I arrived at these.

Context

First, some background on where I'm coming from. I've been an "infra" person for much of my career. Over the last 6 years I've managed multiple teams and products building web apps, Chrome extensions, mobile and desktop apps (in addition to the usual APIs, devops / infra type of stuff). So I had some sense of the landscape, but not deep first hand knowledge (relative to my systems experience).

Since leaving Hiro, one of the things I wanted to do was to get my hands dirty building full-stack apps. I did build a few projects where my typical stack was: sqlite for storage, API server in Go (typically with go-chi) and vanilla HTML with Alpine.js (for data fetching etc) + Bulma CSS for style. But I was relatively unfamiliar with the modern front-end ecosystem.

Some of my goals

  • Build familiarity with the modern frontend ecosystem: React, Next and such
  • A stack that supports client + server functionality in the same repo: makes it much easier to work with LLMs on projects
  • Have fun learning some cool new tech!

Process & Observations

I didn't follow a clean, linear process. It was meandering and messy. Some notes and observations:

  • The landscape of frontend tech is vast and ever evolving. There's just too much out there and it can get be overwhelming for newcomers. If you're not in exploration mode like I was, I would suggest starting with an opinionated starter stack and stick with it if you can (ala create-react-app or its many variants)
  • Even in a "standard" setup, there are so many moving pieces. For instance, it's pretty common to find these in a starter template: React, Node, npm / pnpm / yarn, Next.js, Turbopack, eslint, prettier, postcss, tailwind, shadcn. Many of these have their own config files, conventions, even CLIs. Exactly how each piece fits together, how they're connected to each other etc, is a lot to take in! LLMs were very helpful in making sense of it all.
  • Just as I was starting my exploration, a major supply chain attack impacted several popular NPM packages, followed by an even bigger attack. All this made me pretty nervous about installing a ton of NPM packages and tools. Compared to other ecosystems I'm familiar with (Go and Rust, recently), the supply chain felt shakier in NPM-land.
  • I'm biased by my training, and I'm guilty of not taking Javascript as a "serious" language – the lack of types, all sorts of weird behavior, poor concurrency etc. I must admit that the combination of Typescript with modern tooling (esp. Bun) has been pleasantly surprising. I can see my self reaching for bun script.ts over Python etc for one-off scripts and tools.

Why React?

I briefly looked at Svelte and Vue, but React is just so dominant that it was easier to just go with it. One obvious benefit is that all the AI tools are also very fluent in React. I'm sure LLMs could be very competent with other frameworks, but there was no compelling reason to explore the alternatives.

I also decided early to avoid using Next.js. First, I wasn't sure if I actually need it and wanted to keep things simple. Second, I wanted to see how far I could go with React + Bun before I reached for yet another tool in my toolkit.

Why Bun?

As I said before, Bun is AWESOME. Why?

  • Bun replaces a whole bunch of tools!
  • Bun is a Javascript runtime. Using node? bun is a drop-in replacement.
  • Bun is a test runner. Using vitest or jest? Just run bun test.
  • Bun is a package manager. Using npm or pnpm or yarn? Just use bun install.
  • Bun is a bundler. Using vite or parcel or webpack or turbopack? Just use bun build.
  • Bun is for building! It provides an HTTP server, sqlite driver, postgres driver, S3 driver and so much more. If you want to build some simple APIs and feel express / fastify etc are overkill but node APIs are too low-level, Bun gotchu.

And, Bun is FAST! ⚡ If you don't believe the numbers, just try it for yourself.

Why Chakra?

As seems to be the fashion these days, I started my exploration with Tailwind. It's clearly very popular and powerful. But having to specify so much CSS to get something decent looking was too much work, and I quickly found myself needing richer, higher-level, ready-to-go components.

So the next step was shadcn/ui, which also seems to be fashionable these days. It's comprehensive for sure! But even with that combo I kept running into issues: changing the look and feel of the whole app required making too many changes in too many places; even simple things like adding dark mode felt very brittle and things broke in surprising ways (e.g. in my case I wasn't using next.js, and shadcn's dark-mode support assumes / requires next.js). The LLMs kept tripping up

Finally I decided to chuck all that and give Chakra a try. I was familiar with Chakra from work, and had heard good things about it from our engineers. It hits the sweet spot for me: solid library of pre-built components, looks good out of the box and easy to customize (on the dimensions I cared about).


So there you have it! I'm pretty happy with this stack for now.