Ask HN: Starting a project today, which web framework would you use?

94 points by betimd ↗ HN
If you will start your project today (medium to large application) which web framework technology would you pick: - Asp.Net Core - Node + Angular - Node + React - Django or Flask - Rails - Laravel or Zend - Play Framework - Other

157 comments

[ 3.2 ms ] story [ 203 ms ] thread
Node.js + Loopback + Angular2 + MySQL
This is identical to my stack. Never thought I'de see loopback and angular 2 here, they're rather unpopular from experience.
Depends on the case:

- Do I want to use the latest technology?

- Do I want to bootstrap fast?

- Do I want to experiment/learn or do I want to build a business?

Depending on these questions, everyone has to decide on their own. If it would be me, I would take MERN stack (MongoDB, Express, React and Node).

Yes, latest technologies. I started this thread because almost all web frameworks had a big improvement year and they're somehow converging in a lot of features and concepts.
Asp.Net Core or Flask.. why? Becuase I know them.
Django if front end is complex (lots of forms, complicated templating, need to have a free admin interface for out of the box).

Or if the front end is simple, I'd just write it in Go using core net/http library.

To make it more maintainable, I'd probably split the application into two components, so backend could be API written in Go and front end a Django app.

Rails: stable ecosystem, just heroku it
The selection is because of rails or heroku?
Both. It's easy to develop and also to deploy, which is something you want in a project.
Both. It's easy to develop and also to deploy, which is something you want in a project.
Rails: stable ecosystem, just heroku it
Mojolicious (Perl), Spring Boot (Java / Kotlin) or plain Go. Depending on productivity, performance and hardware constrains.

If it's the typical CRUD site I'd use Django (Python) if I worried about finding developers, otherwise sticking to good old Catalyst (Perl) or perhaps giving Phoenix (Elixir) a try.

Why Spring Boot? Just curious. I work with it daily and have grown to detest it.
If you stick to the script its ok. But the script sucks right? I prefer dropwizard + libs, always end up googling how to do X with spring boot, where X is a bit off the beaten path
> I work with it daily and have grown to detest it.

What exactly do you hate? (I feel weird liking Spring quite a bit, and would like to get in on the hatin' ...)

To be as concise as I can, I would say that Spring Boot is a framework which minimizes the amount of "code" you have to write at the cost of everything else.

And this means that it's hard to understand what is going on under the covers, hard to debug (partly due to metaprogramming bananza), slow to start, uses too much CPU, uses huge amounts of stack, has all bells and whistles turned on by default etc etc. It gives you all errors at runtime. Encourages you to make your app too configurable (hard to test all configs). Reimplements a bunch of tools and libs badly (like one-jar). Its also intrusive like all frameworks. Requiring a custom test runner is not a feature, Spring! For these type of reasons you cannot easily integrate it with other frameworks.

And that is just from the top of my head.

> "all bells and whistles turned on by default etc"

Arguably a little unfair? Spring boot makes it pretty trivial to just pick and choose the components you need for a project, especially with the https://start.spring.io/ tool.

> Requiring a custom test runner is not a feature, Spring!

I'm guessing this is a reference to using Spring's test runner to support Spring's dependency injection mechanism? No one forces you to use this so it's a stretch to say its 'required', but for certain tests it will save time over manually mocking etc, and often only applies to integration tests anyway. You can absolutely unit test without it.

> "It gives you all errors at runtime."

I'm sure it does, if you have errors.

> "Encourages you to make your app too configurable"

Spring boot apps are only as configurable as you make them, much like any other application. At least Spring tries to provide a standardized methodology/pattern for externalizing configuration parameters. I fail to see the 'encouragement'.

> you cannot easily integrate it with other frameworks.

It's java at the end of the day - there's a ludicrous number of third party frameworks it will play nicely with.

> slow to start, uses too much CPU

Sure JVM applications rarely have 'instant' startup for various reasons, but is a handful of seconds really a problem? 'Uses too much CPU' - I don't really think this is fair either - Spring Boot applications can deliver very efficient solutions.

Not going to argue it's the perfect choice for every project, but no framework is.

Isn't spring boot "thread-per-request"? Some people care about that kind of performance-related stuff.

Also, I think "It gives you all errors at runtime.", should have been "It doesn't give you the errors other frameworks are able to give you at compile time." -and I kind of agree, if memory serves "Spring" is sort of synonymous with "reflection", which isn't exactly performant either.

EDIT: Wow, just read my comment and realized it comes across like I really hate Spring. I don't, I think it's nice. It's great for web apps that have human users; for services that are consumed by other services, I would probably go for something else.

Spring? If you need Java DI you will find Guice fixed the warts.
Does it have Auth and so much more Spring has to offer?
What's "thread-per-request" to you exactly?

By default, Spring Boot uses an integrated Tomcat in standalone mode. That Tomcat is configured to use a worker threadpool with a default size of 200. In addition to that you can make Controller methods "asynchronous" (as in free the worker thread as soon as possible) by simply wrapping the methods content in a Callable<T>, which amounts to wrapping it in a lambda method. Calling methods asynchronously is trivial as well, you just need to annotate them with @Async and wrap your result in an AsyncResult<T>.

If you follow the reactive/async/callback/functional cargo cult you can use the brand-new, already usable Spring 5.x spring-webflux. As they describe it: "fully reactive and non-blocking. It is suitable for event-loop style processing with a small number of threads"

> plain Go

How's Go with web applications that render HTML content? I've had a lot of fun building microservices with JSON REST APIs in Go lately, but I have not done anything that emits HTML. I'm afraid that as soon as you generate HTML, stuff gets messy and you need to include bajillion modules with all this CSS/JS crap.

If what you're trying to achieve is to pump out some HTML, Go has built-in safe HTML templating. The template syntax isn't glamorous (in fact it can be very unpleasant at times), but with it you can catch type errors at parse time, and the ability to bind custom functions on your templates comes in handy.

Usefully, too, any type that implements the Stringer interface can be dropped into a template and will come out of it as a string without any additional fussing. If your app implements a number of custom types, it's actually possible to get Go templates to look relatively sane.

ASP.NET Core + Angular probably
I'd love to be able to recommend ASP.NET Core, but there have just been too many changes and U-turns. I have spent too many hours shaving the yaks of changing project formats, features missing from the old ASP.NET stack, warring dependencies, and half-finished implementations of related projects like Entity Framework Core.

I _do_ believe they'll get there, but it's been painful maintaining apps built with these technologies over the past couple of years.

Which issues did you run into with EF Core? I've been dipping my toes in the water and was on the fence about investing time in their offering after seeing their long-ish roadmap or just switching to Dapper.
My knowledge of the state of the art in *Core is likely out of date, partly because I have stopped trying to keep up. But last I checked, lazy loading wasn't supported, it lacked a find-by-pk method, seemingly with the knock-on effect that it didn't have any sort of identity map or anything resembling real object-graph management. I have live apps running on it, it's mostly fine, but the overriding sense I have of this stuff since the great open sourcing is of barely contained chaos. Starting from scratch today, the feeling might be different, I don't know.
I come from a javascript world so changes are the default for me. Kidding aside, I haven't really felt any pain except some small issues but I started using it in RC already.
Spring Boot with spring-data + MySQL + vue.js
Meteor with React: https://www.meteor.com/
I am making a website based on this and the experience is amazing. I literally started learning a week back, pivoted from firebase (after 7000% fiasco), and have been kicking myself, why I wasn't aware of this before.

Meteor is smooth. And react makes me feel good.

You moved away from firebase?
I think there is just one sane choice: I'd use the one that I know best, and the one that has huge number of users (which means it's more battle tested).

In my case it would be Django + PostgreSQL.

Depends on the project, but most likely just Node + express + TypeScript on the backend (so no "framework" in the traditional sense).

On the frontend, React + MobX + TypeScript.

This of course means it would be a single-page application.

Benefit of using TypeScript on both client and server is that you get to automatically share the schema of the data they're exchanging (and maybe some more code as well, like validation). For free. And when you change the structure of something - and you will - you get immediately alerted to any issues on both sides (e.g. this property is now required, and you omitted it in this function!). This is huge because maintenance is often more difficult than writing the initial version - and I don't even mean the initial released version.

Also you get to potentially reuse some of the code in the future for a React Native based mobile app.

I'm also eyeing GraphQL and Apollo a bit, but I don't have enough experience with them to use them in a "real" project just yet.

I would do pretty much exactly what OP suggests. I might just go for React+Redux instead of MobX, but that's not too important.

What I'd like to hear is arguments as to why I might want to consider other options. Why Elixir, compared to the above solution? Why Phoenix, or for that matter Django? Or for the front-end-ish side: why MobX instead of what seems to be a more industry-standard Redux? Why Node.js and Express instead of the alternatives (Django, Rails, but also Hapi and Sails)?

> Benefit of using TypeScript on both client and server is that you get to automatically share the schema of the data they're exchanging (and maybe some more code as well, like validation). For free.

How do you do this? Do you have a separate NPM package that just contains your schema/validation code? Or do you keep your backend and frontend code in the same repository?

Same repository, 3 different directories (client, server, shared). This also makes it easy to have shared docs, dockerfiles, and other things needed for the complete setup on any machine.

But you can also just do this with a git submodule for example, or any other method that will physically get you the shared files there.

Thanks for answering.

I've always wanted to try breaking projects down into separate NPM packages, but I usually end up using git submodules. Path of least resistance and all.

Not sure what you mean by NPM packages, but I don't publish anything to NPM (not even a local repository).

On the other hand, the client and the server obviously each have their own package.json, with their own dependencies, etc.

> Not sure what you mean by NPM packages, but I don't publish anything to NPM (not even a local repository).

Break your applications into separate Node modules and publish them to a private NPM.

Now that I type it out, it sounds like more trouble than it's worth.

Pure Go on the back plus jQuery on the front.
even a complex app, large web app?
Facebook is a large web app, Google Docs is a large web app, but the projects I have been working on - not so much.
Rails. No question.

In my 7 years of using this framework I have come across nothing that comes even close to in terms of LOC, ease of pickup and quality of the end product.

(comment deleted)
Play Framework with Scala. Very simple and super scalable.
I started one recently with Preact + Mobx. Very happy with it
My current stack:

Backend: Go (standard library mostly, httprouter, and some homegrown libraries for stuff like dependency injection, configuration etc.)

Frontend: TypeScript (with React and Redux/mobx)

Other than that, I think using something like Kotlin, Swift or Elixir could be interesting in the backend, too.

I really like Elixir. Learning to write & test concurrent code has certainly been adventure! It's probably been a good warmup for testing microservices.
Rails + JQuery + Postgres + Heroku

Why? It works. It's not gonna have crazy changes. It's simple. There are a million relevant resources to help learn how to do x, or help you if you get stuck. It's easy to hire skilled people that know this stuff back to front.

btw - you don't start a medium to large project. You start a small one, build incrementally, and see what happens. If you have success, then you can spend money building in whatever you like.

Backend: laravel

Frontend: vuejs or react with ssr on both

I may use many languages and frameworks in one project if needed. I will start with Django because I'm good in that skill set.