Ask HN: What would be your stack if you are building an MVP today?
Specifically the backend. I'd love to hear your reasons. Do you keep one eye on what the stack would be post MVP?
1. Old schoolish (VPS - Maybe DO, Django/Flask/Rails/Remix/Next with postgres)
2. Supabase etc with JS/TS on either side of the network
3. Lambda/Cloud functions with Firebase/Dyanamo DB/Cosmos DB etc
4..n. What else and why?
735 comments
[ 3.4 ms ] story [ 418 ms ] threadBut also if I was slightly less old I think I would be heavily into Python at this point especially as far as the ability to easily leverage data and AI tools and libraries.
But again, my suggestion is go with what you are familiar with. And if you are less old and are excited about a new language or framework, that seems perfectly valid to me. The hard part about programming is staying motivated. So if new stuff helps with that then great. I
One more take is that you should start by defining the problem in detail before you make up your mind on the architecture and technologies that you will employ. If there is a particular technology that is well suited or has a ready-made solution, you should consider that.
For personal projects, reactjs or vuejs or solidjs, tailwindcss, nodejs. Depends though, sometimes there are projects that demand the strengths of golang or rust.
With this setup you can permanently host for next to nothing until you get users, do zero devops or ops, and have something that will scale up (wont be the fastest thing but it will be OK and will scale)
You could switch out NextJS for a static site generator too, but NextJS is pretty convenient and is a superset of a static site generator with everything wired up nicely using React.
That said, there's a time and place for experimenting and learning new stuff. And I am interested in trying Elixir at some point. But to "get stuff done" in the near term? Yeah, it's going to be mostly Java/Groovy, Grails, and some Javascript. Hell, I might even break out jQuery just out of sheer familiarity, if I got stuck doing something using vanilla JS.
We were discussing this in our CLI catchup this morning. It seems the Dashboard/Studio is the main culprit here. We'll fix it
2. Supabase for Postgres and Authentication.
3. Astro as a framework for front-end, deployed on Vercel, running in Hybrid mode.
With all of these in-place, I can extend my existing components to accommodate any needs. It scales very well in the beginning as I move very fast, and anecdotally scales very well regardless of size.
The only missing parts here is support for timed jobs, but that can probably be done with Fly.io machines in the future.
I personally don’t think that if you’re building an MVP you should be worrying that much about how to store users in the database and add RBAC and building a way to add middleware and a storage layer and all of that crap. It’s not worth it, your application is not a special snowflake.
Edit: Should say that with that I mean serving HTML via Django. Usually I would use Bootstrap for layout. Very occasionally I’d add an API for some interactivity but I think for most MVPs interactivity is likely to be a secondary concern until later.
https://django-ninja.rest-framework.com/
It's absolutely wonderful. I would use that in a MVP, and do the F/E in NextJS + Typescript.
Django and it's batteries included philosophy is perfect for creating full stack applications. The best thing about Django is that almost every problem you face has been answered by the community.
The community tools like DRF/Django-Ninja/Crispy-forms/Django-environ etc are top notch and it's very easy to extend your application.
7/5 would use Django again.
This is something I realized pretty quickly when toying with migrating my side project from Flask to Django last year. Everything I wanted to know how to do, I could google with “Django” as the first term, and figure out how to accomplish. Anything that took longer than 2 mins to figure out how to do was generally a matter of not knowing how to phrase the question.
It’s made me a huge Django advocate.
I see a lot of people talking about Elixir, etc. on this thread, but I’m based in the U.K. and I’ve never seen a company locally using Elixir so even if it’s really cool, it’d be a bad idea for me to choose it absent a very very good reason. If I choose Django then even if I can’t find a Django developer, I can likely find people who know Python and the barrier to entry is pretty easy.
Also there are plenty of Ruby/Rails Devs who have embraced Elixir/Phoenix.
But it’s a classic network effect problem; adoption drives jobs which drives learning and further adoption. Without a big corporate sponsor like a FAANG co, Elixir/Phoenix doesn’t have the mindshare of other languages/platforms.
The scale is just not there to make it worthwhile in evaluating for any company to adopt other than a FAANG or really major employer IMO
Django shines at creating a nice project scaffold with all the things you need to do rapid development. It has first class support for DB, unit testing, schema migrations, good enough templating system, performant ORM and can be easily debugged. The documentation is top notch and the best thing is the community. Due to its longevity I found that almost all the issues I had were resolved by a simple Google query or visiting the docs.
It’s very easy to add functionality like social auth with few lines of code.
I’ve also not found anything like Django admin in any other framework. I would highly recommended Django for an MVP.
Not a dig on Rails, like "Oh, Rails is so bad they don't even have..."; rather, Rails is extremely capable, and so are Rails devs, so I legitimately don't understand why this isn't there already, 15+ years after Django.
Edit: and it' still maintained !
Similar situation with authentication, where devise has been a mainstay for over a decade, but it's not always the best fit for everybody so core rails still just has the basic plumbing to build it yourself (with the low-level has_secure_password).
1. you get a lot of out of the box rails like glue jsut like rails or django but the runtime perf is way faster. you can get away without even using caching in prod for awhile
2. supabase is written in elixir
3. lambda could functiosn have their place but loc you in to a cloud provider. I can move my elixir mvps accross providers with no issue and I won't get any surprise bills.
> pubsub and websockets which are important for any new kind of software product
... not really. By far most people (probably by a huge margin) are doing fine building 1000s of new products per week without either those things.
Further I think you are right.
I'm a backend/infra developer, and I had been dreading having to learn a new front end framework because the work flows just look hideous. This looks like I can sidestep most of that problem entirely.
phoneix channels -> django channels and actvecable but phoenix's version is much more powerful
liveview -> livewire, hotwire. both are copies of liveview but neither of them are as powerful since only liveview can spinup a persistent thread PER user allowing active stateful sessions that can push and recieve events from the client.
Livewire has started at pretty much same time as LiveView and AFAIK both projects influenced each other over the years. Both authors are in contact and the frameworks are quite a bit different because Livewire (in PHP) does everything over http so it has to employ different tactics than LiveView that can run over websockets.
Hotwire on the other hand is from Basecamp who have been using this approach forever. They just packaged their experience into a framework they released. Theoretically hotwire is the oldest of the three.
I am saying this because i don't think you need to use LiveView. All of them are super productive and are used for many real projects. They are just a bit different and better at different things.
[0] https://pocketbase.io/
It's boring but it works. It also scales as far as your wallet can handle.
https://github.com/learn-anything/learn-anything
Reasoning behind the stack is that I feel productive in Solid and it's plenty fast on first load and as SPA when fully loaded. I love the component model and JSX.
ChiselStrike is new to me but I was looking for something that lets me declaratively manage my schema. I checked https://entgo.io (it produced too many Go files to my liking), also Prisma (https://www.prisma.io), found it bit complex to get started with.
I also checked https://www.edgedb.com and it's nice but with ChiselStrike I can deploy it with LibSQL (fork of SQLite) and replicate it so responses should be plenty fast and I can build on top more easily.
For native apps will use SwiftUI composable architecture when it comes to it. React Native code sharing seems nice but Solid doesn't have a React Native alternative yet sadly.
Why:
- has almost everything that I need usually in mature gems - battle tested in production
- speed of development
Rails is the fastest development platform I've tried so far, it is predictable, well crafted, structured yet flexible. You can't go wrong with it.
Every now and then I try something new on a side project or I have to work on some other codebase for my customers, and nothing so far has tempted me to move out of rails for my serious projects
Would you care to say any more about your experience with Vue? I've heard a lot of good things about Vue and had it on my mental "things to learn one day" list for a while. Would be really interested in hearing any counter-points from somebody who hasn't enjoyed working with it.
I use .net mvc with a razor templating engine. But this can be used with any backend.
It makes it super easy for me to maintain all my UX in server-rendered HTML templates. I get a clean SPA with super high development efficiency with MINIMAL javascript.
The best part was I could hire any developer and they know how to work in basic HTML/JS/CSS.
Edit: Reading more, I might need to spend time looking into HTMX/Hotwire as a replacement for PJAX at some point.
What has you bother to introduce unpoly when Hotwire is included by default? Aka, what are the main things missing/better that drive you to use unpoly.
I'm not saying you should replace Hotwire with anything else - I wouldn't do it given it's the default or defacto solution.
But all of these tools (pjax, htmx, unpoly and hotwire) work perfectly well outside of Rails too. So if you're not using Rails and you're, for example, using Django which doesn't have a default solution then you can pick one of them, and I think Unpoly is a very nice one.
They had a similar issue as Python, albeit not nearly as bad, with their upgrade from version 2 to 3. It required some rewriting. They also introduced a new core concept with the "composition" API, which completely changes the way Vue apps are written. Luckily once you made a few required changes you could continue writing apps like you used to, ignoring the new composition API. I'm assuming at some point we'll be forced to change, which will suck.
One thing we do, which I don't think is as common when using Rails with a heavy frontend like Vue or React, is that Rails is not in API mode. That is Rails still handles routing, pages are still rendered in ERB, and then each page is its own little Vue app. So we can use Rails, Ruby, etc to initially hydrate the pages and inject stuff by calling to_json on it. This also means we can let Rails and Devise handle login and session, which I absolutely hate doing with a pure JS frontend.
Routing and session management are something I think Rails is extremely good with. This also means that if a section or sections of the site are pretty simple (password reset for instance) we can just render the page in ERB, no JS required.
Regardless, I still like Vue and it has a pretty decent ecosystem. If I had to go back and start again I'd probably just go with React. It clearly has the most support (and most jobs) on the front end.
Also IMHO, a flexible type system like Typescript makes development faster than without it. You can refactor faster, it catches silly mistakes, and you don't have to write as many tests.
Rails does a lot of great things for you, but IMHO ultimately it's stuff you don't really need. If there's any chance that the application will grow beyond a few developers I think it hurts more than it helps.
Simply not true.
I've consulted on multiple teams across products built with Rails. Products that supported hundreds of millions of requests and generated a similar levels of revenue.
Rails scales - programmer productivity, traffic. It scales.
It's not true that I think it hurts more than it helps?
Thoughts? :)
my experience has taught me the exact opposite: people have accepted the poor experience of real time applications (client side crashes that bring down the entire page, half-baked routing that is essentially just rebuilding the browser navigator, inconsistent client vs server rendering processes). developers tend to completely stick their head in the sand when these issues are occurring. there's complete classes of problems that simply go away when you're not building an SPA.
> Also IMHO, a flexible type system like Typescript makes development faster than without it. You can refactor faster
in the long run, yes, but in the short term you're probably not going to get your mvp out faster because you chose TS
People complain about that stuff all the time.
>stick their head in the sand when these issues are occurring. there's complete classes of problems that simply go away when you're not building an SPA.
Well, yes. If you don't actually build a real time application you won't get the benefits of a real time application.
>in the long run, yes, but in the short term you're probably not going to get your mvp out faster because you chose TS
Once there's even a moderate level of complexity (i.e. 2-5 devs for 1+ months) the type system helps you catch issues. Even if it only saves you one 4 hour debugging session you come out ahead.
That assumes you sit down and write out your MVP without any significant refactoring. If you do have to make changes then TS will save you significant time there.
It also assumes that you're not writing tests that duplicate what a type system does. If you do write those tests then again I think you're slower.
Rails does have the advantage of there generally being one "Rails way" of doing things. That can short circuit a lot of design discussions and other sorts of bikeshedding. But you can also just not do that and, IMHO, come out better.
A rails application can be just as "real time" as any SPA, I don't think that definition really means anything. You get a distinct set of problems that come with SPA's that don't exist in a traditional server side rendered app that have nothing to do with how "real time" the app feels.
Also something brought up was a conversation regarding Alpine vs Stimulus. At first sight Alpine looked a lot easier, but Stimulus seemed it would scale better and be easier to maintain at the end, plus we expected it to have less problems with Turbo than Alpine given those were made to work together.
An important difference we found, is that Stimulus can "react" to value changes (https://stimulus.hotwired.dev/reference/values) while with Alpine it was not clear how a component, or some external code would trigger an update by changing a "prop" or an "attribute" of the element. We know we could use stores and events, etc but that's what I meant with stimulus being easier to scale long term.
But it's very progressive. For example, you can just use Turbo to get the "SPA like" navigation between pages (no full page reloads) and that's for free, just including it will bring in that behaviour, plus caching when navigating back, link preloading (so when you click the content it's already there), etc. All of this very easy to control/configure via html data attributes.
Integrating the "Turbo frames" feature is also pretty easy, just wrap content in <turbo-frame> custom tags and the library will do the replacement without page reloads when you submit a form. Similar situation with "Turbo stream", etc.
This is an excerpt from the main documentation site at https://turbo.hotwired.dev/handbook/introduction :
"...You don’t need any backend framework to use Turbo. All the features are built to be used directly, without further abstractions. But if you have the opportunity to use a backend framework that’s integrated with Turbo, you’ll find life a lot simpler. We’ve created a reference implementation for such an integration for Ruby on Rails...."
Same story with Stimulus. You can add it to any framework, it's just a frontend library.
Having said that, there are some "helpers" that you can have in the backend that will make things more idiomatic and avoid some boilerplate, etc. And Laravel being such an amazing framework with such a great community, has a great integration library here: https://github.com/tonysm/turbo-laravel
I couldn't be happier with this stack. With Laravel + Hotwire + Tailwind + Laracasts I feel I'm unstoppable.
A Laravel app hosted with Laravel Vapor (AWS Lambda) with a MariaDB database. Would allow me to get up and running quickly, at low cost and without having to worry about scaling for a long time.
Using Tailwind and VueJS or AlpineJS for the frontend.
The goal of the MVP is ascertaining product market fit, everything else is waste. Use what you know and optimize later. If your MVP can handle 1m calls a second, you have failed (unless it was natively supported by the framework)
The question wasn't "what is the fastest stack" or "of all stacks which is the fastest for you" but rather akin to "what is the fastest stack for you". Which is often the one that you are productive in.
It's almost always not worth learning a new stack to prototype something unless the goal is to learn the new stack.
* which stack will still be around in 1/2/5years?
* which stack Will other teammates or future devs be productive in.
I’m still searching for a very light, productive open source stack that is well accepted and if not future proof at least we’ll backed.
I have clients that still use Excel spreadsheets for their database instead of using a real one just because their data was initially stored there and they never changed. New features were added incrementally over time and it became costly to break everything for a complete rewrite. So they limp along forever because management won't let them do it right until it absolutely breaks.
But to answer your question more directly, it does happen, it's just uncommon. Where I've seen it done successfully, the rewrites have been piecemeal, not all at once, so that definitely helps with the buy-in factor.
I've found that combination to give me amazing DX and appropriate speed of development.
Comes with a built-in low-config UI/API for CRUD on the database, and easily extendable with Vue.js and Express endpoints.
Additionally, should the need arise for something more custom later on, all your data is in Postgres rather than a backend as a service
https://directus.io/
- Server-side rendered app with Golang
- If interactivity is required: maybe Vue.js or jQuery
That's it.
If you are not scared of diving a bit into Rust, I'd a 100% recommend it.
[0] https://github.com/shuttle-hq/shuttle [1] https://docs.shuttle.rs/resources/shuttle-shared-db [2] https://docs.shuttle.rs/resources/shuttle-static-folder