I recently dived into a world I knew nothing about, not even the language: Modern web development with Next.js. After completing the official tutorials, I was hit with decision paralysis when trying to start an actual project. The solution? Opinionated templates like T3.
So, I wanted to learn Next.js. This required learning the underlying framework (React), a new language (TypeScript), and even an entire ecosystem (npm). I also needed to learn about hosting, databases, APIs, and a million other things I vaguely understood but not enough to actually implement. Sounds easy!
Of course Next.js has different versions. It also has completely different ways of architecting a project, each of which has an unconnected official tutorial (pages router or app router). It also has 4 ways of displaying content. Do I want SSG? SSR? CSR? ISR? WTF!
Aaaand that’s before we even get to the various SDKs and tools required, each of which has multiple alternatives. For an ORM do I want Drizzle, or Prisma? For authentication do I build it myself, use NextAuth.js, or a paid solution like Clerk? For the UI do I build it with CSS modules? Sass? Tailwind? A UI framework library?
I have no idea what on earth I’m doing.
I have 50 decisions to make, and no way of knowing which is an unchangeable commitment and which doesn’t matter. OK, so I need a starter project to make some of these decisions for me.
Since my initial exploration into Next.js / React was via Vercel’s official tutorials, their templates gallery seemed a good place to start. I spent a few hours looking through the projects, and they always fell into one of four camps:
- Skeleton (example): Templates that essentially gave me less than I ended up with at the end of the official tutorial. I’m a bit clueless on where to go first, and there’s too little here to really help.
- Skeleton plus X (example): Almost all the third party templates follow this format. They provide a basic landing page plus whatever feature the company happens to offer. No better than a basic skeleton.
- Cluttered (example): Templates that weren’t from a company often suffered from the creator adding random utilities they wanted. These probably help an experienced developer, but for a beginner just add pointless complexity and confusion.
- The kitchen sink (example): Some templates tried to provide everything you could possibly need, and end up becoming word / code soup. The example provided has a “Features” list that is essentially gibberish for a new developer. Who needs “Automated ChatGPT Code Reviews” or whatever “CVA” might be, I just want a modern template to start with!
I committed some time to a couple of these templates (especially Precedent), and left feeling a little burnt out and lost. I felt adrift in a sea of a thousand options, with only random opinions from companies and articles to guide me.
Whilst the scattered articles, GitHub repos, and tutorials are helpful for someone learning a specific feature or library, for someone trying to learn the entire thing from scratch a more complete solution is needed.
Luckily, I’d long followed someone called Theo AKA “T3” on Twitter / X. I followed for his general tweets about tech, and didn’t know he was influential in Next.js / React, nor that he was primarily a video creator. When I was looking on Reddit for template recommendations, someone recommended him, and I discovered he has a very popular template!
After being burned on the various Vercel templates, I was sceptical initially. However, T3 seemed to have a clear goal: providing the core functionality, and drawing a strict line about what you need to choose. More importantly, all of these decisions were documented, instead of just “it’s here because I want it to be”.
Having these choices documented meant I could make an educated decision about whether I agreed with them. For example, “Bleed Responsibly” discusses his approach to bleeding edge tech, and how it needs to be considered. It shouldn’t be used for core functionality (e.g. database), but is fine to use if it’s easy to migrate away (e.g. tRPC). Similarly, the non-negotiable stance on TypeScript and type safety provided some reassurance that this isn’t a “wild west” template that will have unsafe or unnecessary code scattered around.
After some light customisation during the installation process (essentially “do you want to use feature X?”, I chose yes for all), you have a mini-site! It has a database, can read and write data, and already feels like it can do something useful. From this, it’s easy to imagine the first steps in creating your own project on top.
Finally, the documentation is absolutely excellent. Not only is the mindset and decision-making described in detail, there are sections that provide more information and help than I could ever ask for:
- Folder structure: Describing the overall file structure in detail to avoid getting lost.
- Library introductions: Absolutely crucial in helping me understand the project, libraries like Prisma are described in just enough detail. Code examples from the actual project are used, helping them make sense in context.
- Recommendations: Once T3 has gained your trust, it uses this to help guide your next steps. Importantly, it provides multiple options for each problem, and encourages you to avoid using things unless you actually need to. A breath of fresh air coming from “kitchen sink” style projects!
- Community: There’s a Discord server with 20k members, and the discussions are mirrored online for easier searching.
All of these combined meant I went from completely lost and considering learning something else, to having a project that made sense, that I felt confident in, and I was ready to start building on. Wahoo!
All of this confusion without any real authoritative source felt somewhat familiar throughout. Finally, I realised… this is what it felt like to first learn Android 10 years ago!
In the earlier days of Android development, Google was far less opinionated than they are now. They didn’t provide guidance on databases (Room), asynchronicity / threading (Coroutines), architecture (MVVM), or much besides the absolute basics of putting images and text on the screen.
With Android, a lot of the developers were coming from a Java perspective (like myself), so inevitably brought over a lot of the conventions. For example, RxJava and similar libraries became obvious choices due to the amount of existing knowledge. Whilst most of these libraries became somewhat standardised, they were all from different sources, so there was no guarantee they would work well together. Similarly, they didn’t necessarily make sense in the context of Android.
After a few years, Android developers ended up essentially using Java libraries, with various fixes and workarounds glued on top. This was fine, but often ended up with far too many options for simple functionality like using a SQLite database. Some developers like myself ended up building their apps (e.g. Pixel Blacksmith) on top of total dead-end ORMs that are now abandoned like Sugar ORM (don’t use this!).
Once an authority, or in this case the authority, steps in and makes recommendations, it’s a massive relief. Developers don’t need to learn 5 different ways to complete a simple task, they can just learn the Google-endorsed way and they’ll be at home in most codebases.
Google is now very comfortable defining “modern Android development”, including the language, libraries, IDE, and various project settings. Excellent.
Discovering T3 and instantly wiping away the endless decision paralysis around Next.js felt like the same story, told in a days not years and entirely within my own head.
By providing an answer, with rationale, developers can actually get started on writing code. Whilst experienced developers can absolutely debate whether library X or Y is better, as a beginner you just want to be told which one to start with. You’ll likely end up learning both eventually, and making this decision is far easier when you understand the other moving parts.
Both Google and T3 are very opinionated. This is completely intentional, and provides a “happy path” for getting basic functionality working. Sure, you might need to swap out libraries if you have a niche need, but realistically the vast majority of apps (web or mobile) have identical base requirements. You need to fetch data, you need to store data, you need to display data, and you need to update data.
I’m absolutely envious of developers who enter the Android ecosystem when it is already mature, as I did with Next.js. When a technology is new and exciting it’s essentially chaos, with countless alternatives for every part of your app, and no way to tell which will become dominant in five years. Joining late lets you skip learning multiple similar approaches, and just learn the one that the community has embraced.
Once a baseline of understanding has been achieved, it’s drastically easier to compare different options.
T3 kept me interested in Next.js / React / Tailwind / Prisma. Google kept me from straying away from Android for long.
As you’ve probably realised from the contents of articles on here, I’m usually not particularly opinionated on choosing certain libraries over others. If it works, and is widely adopted, it’s probably good enough. I’d much rather learn a whole new ability than learn how to store data in yet another ORM library!
However, publicly discussing & debating these opinions is useful for the long term health of an ecosystem. It’s just not what a beginner necessarily needs to read.
All the time saved comparing libraries and approaches on my current project is extra time to carry on developing within the T3 stack, and ignore (for now) all the alternatives!