Ask HN: Which stack for prototyping?
As a former developer, I have had countless of project ideas and choosing the tech it's going to be written in has always been a [unnecessary?] long topic, often leading to procrastinating and giving up on the idea.
I often hear (and claim) the argument that "one should use the stack they [the team] are the most comfortable with". While I strongly agree, I find my personal [developer] stack to be slightly outdated (as a system engineer, lots of Python, some Node with Express, and some irrelevant languages - C, scripting, ...).
Focusing only on the development side, what would be YOUR goto stack for very quick prototyping/MVP, say for a webapp/saas service?
Long term code support doesn't matter much here, the goal being able to bring ideas to life very quickly. Let's say 10k users max (or much less).
Some recommendations I've had:
- Node: Nest + Next.js - modern and popular stack with quick prototyping possibilities
- Elixir/Phoenix - attractive ecosystem, developer oriented
- PHP: Laravel + Livewire/Blade - very quick prototyping and social features
- Python: Django - because I'm already very comfortable with Python
99 comments
[ 3.3 ms ] story [ 128 ms ] threadFor this part I've been recommended "tailwind ui" and it looks very promising!
They tend to be higher quality and less packed with loads of random JS libraries than the ones on the big theme marketplaces.
https://htmx.org/examples/
I would be willing spending a bit of time learning a tool today if it can save me tons of time in future project ideas - read: would allow me to actually DO work on these ideas.
C# with ASP .NET Core (because i am most comfortable in .NET)
cloud: Azure (easy to use, has in built auth), and you can limit your credits, so you won't end up with crazy monthly bill like AWS
One of the best things you can do is use Postgres as the backend.
I am getting to a similar conclusion to you though, where other tools were good for prototyping and the node stack really better for the real projects (post-prototyping).
Keep this in mind whenever someone decides Rails is fine for a quick prototype and then leaves you to deal with production.
I am of the unpopular opinion that Rails "many opinions" are confusing as hell to someone who doesnt breathe Rails due to the sea of implicitness: Symbols just appear you are supposed to know where from, debug requires context dumps, gems are an unholy mess of registering hooks and overloading core apis. Combined with "slow as a dog", I really dont see what there is to love here.
I suppose the next step would be to rewrite this app in Go or in Elixir? ;-)
I think the reason this productivity exists is the all batteries included approach. For example, if I build a Rails gem, I can include data persistence through ActiveRecord and that code becomes less code that the developer using my library would have to write. Multiply that out by the various core libraries and the time savings can become significant.
I would also point out that for very early stage startups, the biggest problem is speed of development with only one to two devs. If they can't get the features out to reach product-market fit, it doesn't matter how good the performance of their application is.
While I don't like Symbols yes you are expected to know Ruby to at least a basic level if you wanna write Rails. It's like me saying in Node you are supposed to know Promises/async. Of course you are.
Also what were you using to support the concurrency before the switch? There are quite a few solutions out there you could have tried before doing a rewrite. Seems to me like you guys just wanted to write Node, which is fine, but it probably cost you quite some time.
Personally, I've been thinking of a project to create Next API routes directly from Prisma models, so effectively something similar to Django Rest Framework to connect Next and Prisma.
Is your project mostly database admin? The django admin can probably get you something useful fast. Is your app less database driven, or you need more flexibility? Flask is a good bet. Dealing with "live" data (chat apps, etc)? An asyncio project like quart or aiohttp might be best, coupled with a database that supports subscriptions/changefeeds. Alternatively flask with server-sent-events and redis might work better. If the project was mostly an API I'd likely use fastapi.
You can combine a lot of these servers in the same app with wsgi "application dispatching", although generally support for mixing asyncio frameworks and traditional frameworks isn't great.
Unfortunately there isn't a one size fits all solution right now, some frameworks will do some stuff better then others.
Blitz is built on top of Next.js and gives you postgres for free, in addition to auto-generating CRUD routes on schema changes. It's trying to be like Rails.
I've used Next.js with firebase for multiple prototypes.
Either way, I use python (FastAPI) and vue.js to keep the front-end and backend separate. That way, if you're working in a small team then responsibilities are easily separated and helps with scaling too, e.g. when you reach 10k users. There's also a great range of libraries available so prototyping is quick on both ends.
As for deployment, I use docker and a digital ocean droplet. That way, you can deploy easily as and when needed.
https://andybrewer.github.io/mvp/
-- Ruby: Roda + Sequel + SQLite (or any db)
- Frontend
-- Node: SvelteKit + ViteJS + TailwindCSS
- FullStack (monolithic)
-- Ruby: Roda + Sequel + ViteJS + TailwindCSS + SQLite (or any db)
It's whatever you are most comfortable in, and can move the quickest.
It's the stack where you don't have to re-learn how to do things you know are possible.
So with that in mind, it's probably not the latest and greatest technology (except if you happen to have been living and breathing it for the past few years). It's probably got some warts that you don't like but for which you are also very competent at overcoming.
If you are leading a team and need to decide that for them, try to find out which stack each member has gotten the most done in (in current or previous job), and average it across the team. It might be helpful to set expectation that this is not the most glorious technological project of their lives but that the goal is a rapid developement project with the goal to replace parts with something more robust once they get validated on the product/user side.
Wow am I glad I learned JavaScript in 2012/2013.
A few years later, I was most comfortable building web servers with Node/Express.
Once again, wow am I glad I learned RoR and then Elixir/Phoenix instead of halting my education and sticking with what I was most comfortable with back then.
It's been a huge productivity boost in multiple domains.
My personal developer stack is getting slightly dated as my main focus over the past few years has been onto dev/sysops, seeing tons of new exotic tech being used now and then.
I am really open on learning something new today if it can help me be more efficient in building my ideas in the future!
There is a local maxima around what you already know due to the cost of learning something else, but it's much shallower one than many, including my past self would have guessed.
With web there are a lot of transferable skills: http, DOM, chrome debugging, general problem solving etc. so there is that too. If I try nextjs and it does something odd I can still debug it.
I mean JavaScript pff... that's so last decade.
/s
You're not going to rapidly prototype anything with Rust for your first 12 months working with the language, depending on your motivation and your ability to write missing parts for security middleware. However, once you've gone through that, you can be just as productive with an async Rust stack as you can with a Python one. Your prototype will also be ready for the "no time to refactor" mandate that makes it your production system. Actix-web framework and async libraries for postgres, redis, and rabbitmq are all mature and well-documented. I realize you said quick prototype/MVP, but all of this comes at little additional cost once you know how to adopt and integrate quickly.
Building a service? Go.
Need a light UI for the service? Go + Go html templates.
Need a command line tool? Go.
Building an interpreter or transpiler? Go.
That’s just me though. The reason that’s my answer is I’ve been writing a lot of Go lately.
Answers I might’ve given at another point in my career:
- Rust - I’d still reach for this but I find it a little slower to work in for prototyping.
- C#
- F#
- Ocaml
- D
- Pascal
I know JS/TS, I find they're generally counterproductive in dissecting the problem I'm trying to solve. I might use them for rapid UI prototyping, if it's a very simple app.
What made you pivot from .NET and Rust to Go? Is this a question of creature comfort, where you're just more accustomed to it nowadays and/or prefer the ecosystem? Does Go stimulate/force you to think about the problem differently and if so, how?
I actually still quite like .NET on the whole. But the job I took after Microsoft had me writing Rust and Go.
I should note the list is in no particular order. If it were ordered newest to oldest, it’d be:
- Go
- Rust
- F#
- C#
- Ocaml
- D
- Pascal
Languages I’ve used heavily but wouldn’t for prototyping are C and C++. Most of my time at Microsoft was 67-75% C/C++ and the rest some form of .NET.
For frontend I try to stick again to just HTML and Vanilla JS, if I know the frontend will be more complex then I go straight to Elm
* Typescript + Vue on the front end (with nuxt) - NO SSR but nuxt precompiles the pages for me so I don't get the SEO hit. Front end can be served from any CDN basically for free.
* Node for the rest API with a custom, very simple and declarative framework that wraps HTTP, this only replies in JSON (also typescript)
* ArangoDB for all database needs. Has key value store, document store, graph store, so best of all worlds. I can use it like a RDBMS where it matters because graphs support relationships so no data duplication AND no need to normalize.
I can basically do anything with those, from quick prototypes, to a very low traffic website to serving millions (managed k8s, horizontal scaling comes into play then).
I would choose a different backend (Go, Kotlin, F# but that's just me) and PostgreSQL or MySQL.
As mentioned: for you probably Python+Django (rendering pages, not an API), if you want/need a dynamic front-end maybe Vue+Firestore (or the like), 3rd choice Vue+Django.
From personal experience I can say it's very easy to get 'caught up' in the back-end tech and lose focusing on the front-end/product/customer.
I'm not a fan of PHP, I've never used any of the python frameworks, and while I can use Ruby on Rails it would usually not be my first choice - not unless I was building a simple CRUD application.
Perl gives me the amazing CGI::Application framework, a lot of libraries for integrations, and a standard approach to writing tests.
Golang is the new-hot, it's good for writing servers and services, also has a testing-centric development approach, good support for templates and a simpler deployment approach than most dynamic languages.
Still, my preferences tell you little except what I can/will use. The answer is usually to always pick the framework/think you're most familiar with OR the thing that you want to learn next.
Year 2000 called, it wants its webdev paradigm back.
"Come and take it!" ~ Serverless frameworks, Lambda, etc.
With this stack you can quickly build a API, connect it to bubble and show people your idea in a way that's actually working. Later on you can move all your API data off bubble and replace the front end with whatever you want.
I found it the cheapest and easiest way to build something very quickly.
Twilios: https://imgur.com/a/iACVPvU
Stripe: https://i.imgur.com/esOq0dB.png
ETC
Reiterating "personal choice."