SvelteKit + Supabase.

It’s the opposite of what a lot of people recommend. It’s not battle tested. Both of these technologies are still maturing BUT:

I can write everything in JS/TS, I don’t have to get good at Ruby PHP or Python

Postgres is a great skill to learn.

Supabase is portable and can be self hosted, and its JS client is easy to use for DB manipulation and stuff like object storage.

For me, building a true full stack web app (not a todo list tutorial but something with real custom features) was going to be a learning process because I’ve been so heavily front end focused. So I decided to try to learn with the most modern tools available. It’s mostly worked out. I’ve had to ask for help on Discord a lot, especially with Supabase.

I have this idea for a blog post called “it’s just a CRUD app” that kind of challenges this idea that CRUD apps are brain dead simple. When you look at the myriad of options for building and deploying one. We’re talking like 50+ frameworks. Methodologies like dependency injection, micro service and monolith patterns. Yeah maybe it’s simple if you have been doing it for 15+ years and are comfortable with your stack but if you’re newer to the game, there’s a lot of complexity at play and the best choices for your situation are not obvious. Before moving to Supabase I was using NestJS because I was convinced I needed this framework with guard rails, but I hated it. So moving off that caused a lot of churn.

Edit: I also wanted to mention that the biggest split amongst all these recommendations IMO is how the backend and frontend interact with each other. Some of these frameworks will render frontend views for you. Then you're dealing with a very classic web app. Then you hear other people in this thread talking about HTTP handlers, and it's clear they're talking about the backend existing as a REST API, which IMO is a bad pattern to use for your own app. REST APIs should be used for exposing your service to third parties.

But there's a third way, that's becoming popular amongst the "bleeding edge" with things like Next.js and SvelteKit that have a "backend for frontend" where they have to run a node/deno based server anyways to do on demand SSR and hydrate. Having a separate backend, especially a separate backend that is just a REST API leads to a ton of redundant code and confusion.

So instead with ORMs like Prisma, people setting a persistent DB connection on this backend server and accessing/manipulating the DB directly with some kind of client. I think this approach came to prominence alongside the rise of GraphQL. That's basically the way Supabase works - they have a JS client and you interact with it in a similar way you would Prisma or TypeORM. They even have an article about how their client can be used in a similar enough way to GraphQL that it's not worth using GraphQL instead.

Instead of traditional controllers where you would stash a lot of business logic (including authorization), the idea is you leverage PostgreSQL's advanced features to help with that. I'm not a huge fan of this for multiple reasons. So you kind of have to make your own decisions on how much abstraction you're going to put on top of their client.