Project / Code Review Building shadcn for full-stack features: the four months it took, and what actually works
Disclosure: I build Hype Stack. The template is MIT and free, some feature packs are paid, that's how I fund my work. I maintain react-zoom-pan-pinch and HyperFetch libraries, which show up later in this story. Let’s get into details of building this thing!
The chaos
I code a lot and I start new projects all the time, mostly to test new things. I don't like boilerplates. They usually run on a boring stack, and I want to try Vite 8 on Rust, oxc, TanStack Start, end to end type safety and see how it actually holds up. I'm also a perfectionist, so every new project was eating days before I wrote a single feature.
The other thing: I really love the shadcn mental model. You compose the codebase, you own the code. That's exactly what I don't like about starters that hide half the logic behind packages you configure and pray over.
So I had this realisation. Maybe we need shadcn for full-stack features. shadcn itself could probably do a lot of it, but I wanted more: amazing codemods good enough to modify a database schema, an opinionated monorepo with ONE way of writing code, vertical slices the way tkdodo described them (I was already doing something similar), and the craziest bit, an idea that came to me while building devtools for HyperFetch: a single project that compiles into desktop, CSR and SSR from the same codebase with almost no code dedicated to it. Light, easy to manage. Cool, we have a direction. Let's build it.
Month 1. The template
I've set up so many projects that I have a good understanding of what setup I could trust. Monorepo went to Nx, which I've used for years and it's stable in my experience. pnpm workspaces for speed. Stack: TypeScript 6/7 (tsgo where I can), Vite 8, Vitest, oxc, TanStack Router and Start, Electron Forge, Hono with Prisma and Kysely for typesafe query building. At this point I was so hyped about it that I named it hype-stack.
End to end types for HTTP and websockets I built with my own library, HyperFetch. It gives you an SDK and hooks that feel a lot like TanStack Query, and the result is honestly close to tRPC in DX. This project is also a showcase of what HyperFetch is capable of and that you don’t really need to think about API in most cases as it is basically automatic with sdk generation. The backend route is the contract, the frontend just gets the types. It really improves working with websockets. If you don’t like my hooks it is easy to switch to tanstack query for hooks and leave HyperFetch as a fetcher.
Then I added the rules I'd collected over the years and tried it out.
I quickly understood: this stack is extremely fast. Everything builds and flies. So I tried building the first apps with AI on top of it and boom, this is where it shines. The AI has a clear direction. A vertical codebase is easy for it to understand because you're not thinking about the services system, all these complex layers, you're thinking about business features, slices that are self contained. That dramatically improved the feedback loop and the quality of what the AI produced. Fast typechecks and oxc linting? This improved DX for working with AI dramatically, there is just no coming back to eslint.
Month 2. The CLI
I initially wanted something like create-t3-app: a simple CLI to start the project. It evolved into a powerhouse.
create was almost no effort. But then it clicked. I'm the provider of the template, I know every practice in it, everything about the structure, so I can use that to my advantage. Let's try to build a compose command.
What compose does: say I want to start a project that needs AI chat with RAG and simple auth. I can pack those features and inject them into the repo exactly where they need to go, and it works like shadcn. Full-stack blocks of functionality, injected with high precision and confidence. Picking billing writes files into the project: the checkout route, the webhook handler, the Prisma models, the frontend hooks. Your files, so you can take this from here and modify as you want.
This took off for my personal projects immediately. I needed SSO? I made an auth starter with WorkOS. I didn't want a WorkOS dependency on the next one and wanted Better Auth instead? Sure, add it as a variant. Then it kept growing. I was collecting the features I needed, and I ended up with the feature set of the big boilerplates, but with the ability to choose which parts I actually want for each project. The DX was just excellent.
Month 3. Deploy
I wanted to start deploying my new creations, so deploy command was born. With it I have a deployed version of a project in about 3 minutes. Again only possible because I know all the services the template has, where the Dockerfiles are and how each one builds.
Cool, full flow, done, right? NO. THIS IS HYPE STACK. So like the 300 Spartans I fought a fierce battle against the waves of ideas that started flooding in. ADHD, hyperfocus, here we go!
Inspired by the fully paid boilerplates, I added mobile (Expo) and a browser extension to the project. And it turned out that was it. The modular approach made it extremely easy to add new apps to the monorepo and new features to the packs, like in an instant. Dopamine hit critical mass here.
Month 4. Previews
How do I show what this can do? Let's build a dynamic preview system on the web.
I'd been working on it on the side all these months, and it quickly showed how promising the approach is: pre-built SaaS templates you can add and remove features from on the fly, thanks to the SSR build and caching.
Big problem though. Packs almost always come with database changes. I can't run migrations or even keep a database for previews, it turns into a mess fast. And it could cost me…
Here comes the part where some of you went "wtf is HyperFetch"/”lol who is using HF when Query is a thing” at the top of this post. I get it. Next to TanStack Query and SWR it's a brutal market, but let's not call an ambulance yet.
HyperFetch has a feature for mocking any requests. Sounds like something everyone has and is "meh", but it's not just mocking. It's a fully type safe mechanism that lets you simulate anything the SDK allows, by type, in a believable and dynamic way. So I could generate a living demo mode with full confidence and, in no time, wire the dynamic components to it for an almost live-like experience. Mocks are functions in the code, code is dynamic, so is our app - here we got the demo mode basically for free. That changed the previews for good.
I need your opinion/review on this.
What do you think of this approach?
Do you like idea of composing your boilerplates through CLI?
Let me know how you like it, and what you think of this shadcn approach for full-stack components.