Long time Django (and occassional rails) dev here.. I've messed with Node from time to time but never really been wowed by the fragmented eco-system around Express (or flask either for that matter).
This looks like a node framework that I'd really enjoy using - first time I see a framework that feels like it fits around ES6. For me personally, having a good ORM and models layer, coupled with migrations have been a deal breaker in choosing a framework, and I'm very happy to see that here.
Is everything written from scratch or are there dependencies? If so, it sounds like its actually quite an opinionated microservice architecture.. Lately I've felt like microservice and microframeworks have gone hand in hand :)
Most of it is written from scratch. For better or worse, I'm very systems-oriented, meaning I like to understand everything from the ground up and I spend a lot of time reinventing the wheel. (Probably why I studied Biochemistry.)
Very happy with the lessons I learned throughout the process and the end result. Experience with Django and Rails design patterns was a tremendous help.
Yeah, I really feel like its the 'gold standard' in framework design.
Still, I look at things in Django and get angry that they were not MORE opinionated, like Rails. Like, not having a decent REST abstraction out of the box is almost unforgivable in this day and age.
I think Django's evolutionary decision making has been nothing short of fucking awesome. They've consistently waited until a clear, mature 3rd party winner has emerged for problems before integrating them. When those solutions are integrated, they're battle tested and not going to bite you into the ass.
Django's team is very aware of where their weaknesses are, and they're working on them:
We've been awarded $150,000 to help fund the development of Channels, the initiative to rewrite the core of Django to support (among other things) WebSockets and background tasks, and to integrate key parts of the Django REST Framework request/response code into Django, such as content negotiation. Together, these projects will help considerably improve Django's role of backing rich web experiences as well as native applications.
Thats true, but look also at costs over time.. With the fragmented approach, 3rd party frameworks have been suffering big time. How do you normalize between apps that are using multiple different ways to do REST, and how do you handle versioning conflicts? I totally hear what you are saying though.
I found this a difficult line to toe during development. Where do I encourage developers to do whatever they'd like, and where do I enforce some sort of standard? I tried to pick a middle ground. I avoid helper functions where I can. Want to do something before you save the model? Learn ES6 inheritance patterns and write a save() method around the Parent#save.
Will still have to see where people run into the most trouble and go from there. But I would enjoy it if people could pick up Nodal and walk away confident they could build an ES6 app from scratch.
Django Rest-framework provides one of the best approaches for creating restful apis that any web framework has to offer. For me, using Django is inseparable from using Django Rest-framework. Its what makes working with Django great.
Nodal by comparison does a lot of great things like Django does, but without the robustness of a rest framework behind it, Nodal seems to have created another good framework but not something new and better.
Django Rest framework was not always great :) .. In fact, nowadays I prefer to use one called Django Restless.
My argument is just that REST is not the type of problem that should warrant having three competing libraries (see comment above).. It has been pretty fundamental to the way you build modern apps ever since SPAs became a big thing.
To think that Rails got many of these things right-ish in version 1.2 which was released in 2007 is pretty damn impressive and speaks volumes about the technical clairvoyance of the ruby/rails community.
I'm previously a Djangonaut too but recently I've been exclusively JS. I spent a few hours playing with this yesterday and I really like it.
It was pleasing (and a little surprising) that everything was almost exactly how I expected it to be. I watched the video, got started and rarely needed to go back to the API docs. It actually feels very light and natural despite the fact that it's already quite fully featured.
Yes thats correct. You had to pick third party libraries for these types of things, which wasn't that big of a deal since the community did a good job of rallying around good libraries.
There's nothing like ruby/rails (I love me some rspec!), but ultimately it came down to lang pref for me, and maybe performance (dev reload cycle mostly). Plus, python has a lot of very interesting stuff in machine learning and science.
A little off-topic, but I figured the people reading the comments here would be the best place to ask. Why use JavaScript on the server at all? I've developed on both the front end and back end, and written non-trivial server-side code in a number of languages, and I don't see any use-case where JavaScript is "best-in-class." It seems like whether you're aiming for ease/speed of prototyping, pure performance, a good concurrency model, or... any other task I can think of, there's a better tool for the job. There seems to be a decent number of people and companies using Node, though, so let me know what I'm missing!
- Yes there are better tools individually for prototyping, perf, concurrency ... but Node does pretty well on all this points, so it's arguably a strong all rounder
- Node's package manager npm is fantastic, and (imo) gets package management more right than 90% of other package managers
- There are 1000s of high quality actively maintained modules on npm to get you started on things (and 1000s of garbage ones, so you have to be careful)
- The "holy grail" web app architecture (server rendering of frontend JS components coupled with client side rendering in a SPA) is only possible by running some JS on the server
- Sharing JS UI components between the backend and frontend is a huge DX and productivity win
- Another huge maintenance win is using the same language across the whole stack (frontend, backend and devops/automation)
- With ES6, JS is slowly turning into a pretty cute language, check it out :)
- A nice level of cross-pollination between JS and those geniuses in the ClojureScript community is bringing some really nice functional programming approaches and projects to Node/JS
- You can use Node and JS to compile to both native desktop apps and native mobile apps. Having a centralised UI library of JS components that you can leverage for your desktop app, mobile app, frontend SPA and backend static rendering sounds pretty good to me!
I would just like to disagree on the "high quality" of modules. Personally I worked for a year in a very long lasting project about a specific type of social network. In the team I was the first one to push for the use of nodejs, react and mongo and... my god if I regretted it.
The quality of node package is very bad in general. Like the most part are totally garbage. I don't know from where you come and what you used before, I worked only with java, php and ruby for the backend and in those i found:
- far higher Documentation quality... like, node modules documentation is not even REMOTELY comparable: it is often extremely outdated, with very poor examples, the most of the times these example are not even working or are using functions deprecated since 3-4 versions of the module itself.
- a infinite amount of bugs and undocumented behaviors rarely already reported and, when reported, just ignored for months. I usually would find infinite workarounds instead of solutions
- extreme use of "I can do it better, so here my fork". I passed the big part of the time running from bug report to bug report and reading in the comments discussions about "The main maintainer of this package does not want to solve this problem of mine... so i made this other module, totally identical to this one but I just added this little hack, which totally broke the standard way of doinf things of this module, some functionalities I needed and never implemented the last 8-9 months of commits here." and chain this. Like this happened a dozen time each months when someone suggested "Why we don't try this module that says it solve our needs?"
Maybe your team chose bad modules? You seem to know what a bad module looks like (bad docs, bugs, many forks, hanging PRs, undocumented behaviour), so why did your team use ones like that?
It's true, you have to be careful ... there are so many npm modules that there are many garbage ones too. But there are many very high quality ones too. Be more careful about how you choose one, and if you can't find a good one for your needs, then don't settle for a bad one - roll the feature yourself, or adjust the functionality of your app. But in my experience there are high quality modules available for the major components of apps.
Doesn't mean there are any 'high-quality' ones appropriate for the specific task.
> Be more careful about how you choose one, and if you can't find a good one for your needs, then don't settle for a bad one - roll the feature yourself, or adjust the functionality of your app.
So now you're just contributing to the problem of yet another package in the ecosystem?
> Doesn't mean there are any 'high-quality' ones appropriate for the specific task.
Yes, which is why I said if you can't find one then roll the feature yourself.
> So now you're just contributing to the problem of yet another package in the ecosystem?
Nope, I didn't say write and publish a npm module. I said "roll the feature yourself", meaning just write it privately for your app. Having lots of packages isn't bad for the ecosystem, it makes Node and npm unique and amazing. But picking bad npm modules, which is entirely avoidable, is bad for your project - that's all I meant.
> Having lots of packages isn't bad for the ecosystem, it makes Node and npm unique and amazing. But picking bad npm modules, which is entirely avoidable, is bad for your project - that's all I meant.
Having an ecosystem where, say, 70% of the choices I make can be 'bad' is probably not a great ecosystem. I hope it shakes out in the next year or so and there's less choice. There's enough choices I have to make in my own application layer - having to make X more choices about code I didn't write and how all those pieces fit together (and how they'll be maintained going forward) just doesn't feel like a good long-term platform. But... people have the 'choice' to use it if they want ;)
Reducing the friction to publishing portable inter-related code modules to the world to near zero like npm has is an incredible thing. Everyone is still trying to understand the ramifications. The downside is that there's more garbage on there, but believe me, restricting your choice of module to the 30% of high quality ones is a trivial task for a experienced dev. If you want to criticise the platform on the basis that inexperienced devs use it and mess up sometimes that's up to you, but it seems pretty reductive.
I've heard a lot of observations about npm, but being unduly burdened with quality in package management has not yet been one of them!
Bundler and hex, for example, are faaaar better--just consider how long it took them to figure out shrinkwrapping, or flat structure to support Windows.
As a developer, doesn't it make you _itch_ when you repeat yourself? Do you feel that itch when you repeat the same application logic on the server as you do on the client? Getting the client-side validation in-sync with the server validation? This is where JavaScript is fan-fucking-tastic.
All of my recent projects have been isomorphic react apps. I build my app like it were a fully client-side single page web app, but I get server rendering when there's a new http request. Once the page has rendered, the web app takes over and uses history pushState. There are very few pieces of code that aren't used in both places. Once you get the hang of it, you very naturally create mockable interfaces that can be swapped depending on environment.
In my opinion, this is pretty much the only category that makes JavaScript "Best-in-class"; It's the easiest language to build isomorphic web apps.
* Babel
- ESNext
- JSX
* Gulp
* Browserify
- Incremental
* Express
* React router
* Rolled my own flux
- This was interesting because I didn't truly understand flux when I started
- I _get it_ now
The routes on the server are the same routes on the client. When the server renders, React/ReactRouter take over on the client and use history pushState.
And that's actually about it. There aren't any other major libs that change the nature of the project.
One thing I'm looking to do next is get hot reloading working and to somehow cut down on the initial compile times.
One language to rule them all. There is no way to handle complex UIs in the browser without JavaScript. So while you absolutely need JS developers, why not make the API/backned in the same language so that you can hire additional developers that know the same language your existing employees already do. From an employer's perspective, it's easier to manage and (re-)allocate resources if need be.
JavaScript is becoming the web darling (or it already is?), whether we like it or not. And with some nice syntactic improvements ES6 brings, I don't mind.
What I'm missing at our current place is being able to share business logic code between the client and server. Even simple things like validations that are run in both environments would be nice to not have to rewrite and maintain in two languages.
> One language to rule them all.
> JavaScript is becoming the web darling (or it already is?)
I wonder, will it be still as popular if WebAssembly let us use any programming language on the client? I mean post MVP WebAssembly with support of GC, DOM, and so forth.
I suspect the Javascript-or-death crowd are a (vocal) minority of web developers. Most will jump at the chance to use whatever language they please in the browser.
>There is no way to handle complex UIs in the browser without JavaScript
Dart, ClojureScript, TS (technically JS superset but still a considerable improvement) are just the ones I've used.
And I'd rather use both of them on server (Dart/Clojure) than JS.
There are other languages as well.
ES6 is a pain in the ass - no browser supports it and using transpilers + polyfills and the JS build/package tools to set that up is a PITA that only grows as you add dependencies and it bloats your code size to be comparable or larger than the compile-to-JS languages without making the language significantly better.
Why is transpiling ES6 any more of a PITA than transpiling Clojurescript? ES6 to ES5 is a one shell command with Babel. And TS is ES6 but with type annotations. And ignore all of the myriad of high quality plain JS modules on npm at your peril. I like Dart and ClojureScript too, but I've really enjoyed working on ES6 and ES5 projects too. I don't doubt your Dart and ClojureScript credentials, but your comment betrays ignorance of ES6 and the plain JS ecosystem.
You still need to include core.js to polyfil basically everything from standard library. And then you need to make sure Babel works with your framework (like Polymer or what not), and that's just the start of the interop hell that is using different JS libraries together. Rule of thumb - anything you add to your JS build system = increase in the likelihood of hair pulling when things break - and babel and core.js are two such things.
The value I get from ES6 compared to the CLJS change how much I'm willing to tolerate the PITA factor of the build system.
In dart I don't have to do any of that, just add few lines to pubspec.yaml with dependencies and transform directives and off I go. And every other library uses the same build system and the same package manager and the same standard library !
I have not found that to be the case. I run my code through gulp-babel and done. There is no runtime AFAIK, although there was one for traceur.
I have also had no real problems interopping with other big libraries. I think the biggest point of discontinuity would be the class keyword vs other class-like libraries (like coffeescript's implementation). Even that's not too bad, I'm able to extend those using es6 class syntax, I just need to be careful about calling super and setting up the constructor properly.
Yeah, but what % of frontend developers use Dart, CS or TS? Not as big as you think. And no browser supports any of them, yet, including ES6. So you always have to transpile to vanilla JS, whether you use ES6 or ClojureScript.
Don't get me wrong I think all those experiments (if I may) are nice, but if I were to develop an interface in Dart/CS/TS today, I'd have serious problems hiring people that know one of those tomorrow.
ES6 is pretty straightforward. You use Browserify or Webpack with Babel, and set it up to build with Gulp or Grunt.
I don't see how using Dart, TS, etc. make it any asier, and with the setup I just described, you're using Javascript top to bottom. I have an Angular project set up this way, and that allows me to run the unit tests in Node on the command line.
It's an improvement - but at this point ES6 is just another compile-to-JS language that needs to ship it's own standard library - except it's worse than all of the mentioned ones (it has no type checking, standard library is still meh, semantics are still good old JS semantics).
Same here; I guess it really depends on who your target market is. So far, all the ES6 I've written works just fine in Chrome, Firefox, Safari, Opera, and Edge. The only browser that breaks everything is Internet Explorer, but it seems like general consensus these days is that IE is only used in enterprise applications where you're locked into it.
I think ES6 is just in its in-between phase of adoption. The mainstream hasn't fully adopted it yet. As for the rest...
The Coffeescript converts have moved on from the 'one true language' now that ES6 cherry-picked most of the good parts and people started realizing that CS source maps are buggy/inconsistent.
Standards are for 'plebs' so they've moved on to the new shiney. By new shiney, I mean mimicing FP in Javascript and looking down on people who can't ELI5 monads and functors. Despite not being able to ELI5 monads and functors.
Typescript, is really geared toward OOP devs who live in an IDE and compulsively twitch an invisible set of CTRL-SPACE keys when they get nervous.
It's a well-known fact that Google is a OOP- heavy Java/C++ shop who have been developing algos in Java/C++ since their last CS course where they developed algos using Java/C++.
It's within their best interest to get all of there desktop devs to convert to writing desktop apps on the web before all that penis pills/local singles ad money runs out.
It's only a matter of time before we see the first JS AbstractFactoryFactoryServiceProvider class in the wild. Angular2 has made considerable progress on this front so far.
/satire
Honestly, I really enjoy ES6. The JS dev communities favorite past time is ragging on how ridiculously bad JS is. ES6 isn't bad so it's not worth talking about.
The new features introduced in ES6 are pretty conservative. They consist of good concepts poached directly from popular superset languages or sensible additions that fit in nicely with the usual JS style.
The really interesting additions are still in the specification phase. Additions, such as the new ES6 module and loader standard, decorators, native HTTP fetch, etc...
As long as new standards are being introduced, transpiling will continue to be a requirement. I think it's cool that people can create and use new supersets of JS. It beats having to listen to them whine about how 'Javascript isn't exactly like some other language that I really like to use.'
In a way it's the first democratic programming language. Instead of dictating what people should and shouldn't use, people are free to migrate around to different communities until they find one that more closely matches their worldview. Everybody follows the same baseline standard but there's a lot of legroom for differentiation.
Why axegrind over our differences when we can celebrate them and start working together.
Fair 'nuff. I probably fall into the "mimic FP" section above, as I REALLY like functional abstractions. Although I don't do much pure FP. And I don't look down on anybody who can't ELI5 monads and functors. Monads and functors are confusing.
It's all good. My comment was more of a friendly jab than a direct criticism. I agree that FP concepts are amazing.
I just don't see the utility in trying to translate pure FP concepts directly to JS. Same goes for the Typescript folks with OOP abstractions and design patterns. It's like watching a pissed off New Yorker rant about how the pizza shops in LA suck. Live a little and try a California burrito. It might change your life.
The point being, neither approach has provides measurable benefit to runtime performance/stability. They're nothing but really complicated abstractions whose sole intent is to protect devs from themselves. Why don't we build better tools to assist devs instead of inventing yet-another-feature-specific-language?
I think FP abstractions translated to JS could work as amazingly useful design patterns. Hopefully, decorators will make it a lot less painful to define higher order functions in JS.
Likewise, static type alike languages are very useful as a bridge to traditional OOP devs. I think gradual typing is a better long term approach.
...Don't you mean arrow functions? Decorators don't seem like they'd help with that.
And yeah, I don't think that monads are that useful JS. And OO is different in JS. Deal with it.
Also, if you use Strategy, Iterator, or Visitor patterns in JS by writing classes for said things, you deserve to be punched in the face really hard. Repeatedly.
That's not really an argument for writing server code in javascript, since you could instead find a way of transpiling your favourite language to javascript and use it on the client and server. I give you typescript, clojurescript, haste, and GHCJS as examples.
That would depend a lot on the story for using npm modules in your favourite language and your transpiled code. If it's not possible, it's a non-starter.
And why would you write ClojureScript to use on the server, when you could just use Clojure?
I don't want to restart a flame war but after choosing NodeJS for some projects based on specific modules not available in other languages (e.g: bitcore*) I am moving away or leaving it for very specific tasks. The code we wrote more than one year ago making an SQL transaction in 8 statements with async is difficult to understand and have some implicit stuff that you need to take into account. The other problem is not having a multithreading environment (in the official release) because you may want to respond to new tasks instead of blocking the event loop. I have seen timeouts because of this. Even if the recommendation is to do simple tasks, you can't enforce this when using hundreds of third party modules.
With the up-most respect, and we've all been there, but I would submit that maybe you just didn't write your Node code very well? Written properly, async code shouldn't be hard to understand. And there are tons of ways to spin up a new process or worker to execute a task without blocking the event loop of the main app. I mean, I could go away and use my limited experience to write a small project in Python to do a specific task ... but if it turned out to have deficiencies I wouldn't blame Python, rather my limited experience. Next time you need something written in Node, why not hire a experienced Node dev? And what is this recommendation to do simple tasks? I never heard that :)
If your developers only know JavaScript, they probably shouldn't be let anywhere near your backend. Any decent developer can rapidly pick up any other language.
I could not disagree more. Rapidly picking up any language is simply not possible (unless you're a genious). Because the language is not just the syntax; It's its history and evolution, design choices, documentation (or lack thereof), community (both kindness/aproachability and responsiveness), leadership, etc. It takes time. Which sometimes, as an employer, I'm not willing to invest in. Because money.
Plus you've somehow managed to state that JS developers are not decent enough.
1) Bad concurrency model -- callbacks, promises and futures are in general inferior abstraction model compared to green threads, actors, regular threads. Performance-wise it might do well in some scenarios but you are forced to use a more complicated abstraction to get that performance It is not worth it. In general it is appealing because it looks simple in small demos, as applications grow it becomes a mess.
2) npm modules are easy to use and that's great. Good model (well maybe except for deep nesting which breaks based on max path in say Windows, but I hear they are fixing that). The problems I found was that a lot of modules were of low quality. Code half-finished, buggy, developer moved on to something else, etc. Somehow it seems more so than say in the Python community.
3) Javascript is not the best language. There is a reason there is a "Javascript: The Good Parts" book. Because there are lot of crazy decisions made in it originally and a lot of bad "parts". If there was a choice between FORTRAN, Cobol and Javascript. I would pick Javascript hands down, but there are other languages out there today.
However. If all you know is Javascript and you want to write a small demo, then go for it. It will be the least friction.
So with all this complaining and whining, how about some constructive stuff. What language / frameworks might be more interesting / better.
1) Go : good concurrency model, supported by a large community, good performance. Lots of big companies use it.
2) Elixir : new kid on the block, fun, one of the friendliest communities. Probably best concurrency model -- actors. It uses Erlang's VM, so that part is rock solid, battle tested for many years. But not as many libraries. But can use existing Erlang libraries from it. Also best for reliability and fault-tolerance.
3) Python : easy to learn, lots of libraries, lots of material how to use it. This is my go-to language to get stuff done quickly. Try Python 3 if you start from scratch.
4) Clojure, Scala, Java: run on JVM. Battle tested, probably lots of libraries. Personally not as familiar with it, most enterprise and big sites out there run on the JVM currently.
If you want to level constructive criticism, then set aside language prejudice. Obviously, if you don't like javascript, move on.
It's great you like Python. Use a Python framework. You can point out Javascript's warts and we can laugh at the Python 3 migration. (And really, both of these criticisms are out of date. Javascript is _fine_ these days and Python 3 is moving towards backwards compatibility; sure Javascript has warts, but that's because it's backwards-compatible. You know, like... never mind.)
> Obviously, if you don't like javascript, move on.
I don't like many things and like other things. All in various degrees. So I shared my experience.
But you seem to be interested in what I like, so I'll share more. I would say, in general I am not really a "$X language" developer. A lot of people say "Oh, I am a Java developer" or "A Node developers". I am not a Python developer, or Erlang developer. I am a developer who solves problems. And languages are tools ( so far I used Javascript in the past, as well as Erlang, Java, C++, C#, and yes, even FORTRAN ).
The point about Python was that currently, most tasks I had to do, were made quicker and easier by using Python. Some are solved better by Erlang, some by C#.
Javascript and Node I found had enough negatives so it seemed helpful to share that too.
> Obviously, if you don't like javascript, move on.
I didn't know this was Javascript land and I wasn't allowed to come in without proper credentials. (See note about "friendly community" regarding Elixir in my original post, that wasn't by accident. I didn't want to say anything more about Node community, but I will now -- yeah it is not the friendliest, lost of insecurity and angst in it, which was another turnoff to me personally).
From the inside it's extremely friendly, easy-going and supportive. (Not at all saying this is you) but the JS community also gets a lot of hate from backend devs looking down their noses at us, making comments probably based on that one time a few years ago they tried to write some frontend JS to fix a widget and had a bad time, while remaining largely ignorant of the state of modern, professional JS development. So yep, you're right, this makes us insecure and defensive sometimes when dealing with outsiders.
On the flip side, I can see why developers in other languages may feel a bit defensive too. They see this language that they have a poor opinion of start to eat into everything, including server side, and potentially threaten livelihoods. Its an emotionally charged area. JavaScript: The Good Parts is getting on for a decade old, things have changed so much. With ES2015 and beyond JS is becoming a pretty cute language, it's slowly starting to enable a really nice functional style, try and write a project or two in it sometime, see what you think :)
The one language to rule them all reasoning is a red herring. We chose nodejs for our server code for an iOS app as do many others.
The reason why JS + node is popular is becasue it's pretty good at each of the metrics you mentioned. Even though it's not best in class at any one of those, it is well balanced for many tasks. Many other technologies are either too slow, too low level, too hard to scale, or too cumbersome to work with.
Node is too often conflated with JavaScript. This is understandable, considering JavaScript is the interface between the developer and the platform. But as crazy as this might sound, JavaScript is an implementation detail of the Node platform, not a defining characteristic. For instance, there's a project [1] that replaces JavaScript in Node with Lua.
But if you go back to the origin story of Node, it's all about libev (though it now uses libuv for the same purpose) and that pervasively-asynchronous mindset. JavaScript was chosen as the developer interface because it met the need to support that asynchronous philosophy. The result is that everything in the Node world is asynchronous and asynchronous is the path of least resistance for the developer. Other platforms that weren't conceived with this mindset often force developers to fight to be asynchronous.
> It seems like whether you're aiming for ease/speed of prototyping, pure performance, a good concurrency model...
It's a mistake to look at JavaScript as a fit for all of this. Instead, you should consider how the Node platform fills the need. For easy of prototyping, it's not JavaScript that makes Node excel, it's npm. The only package management system I've found that I prefer to npm is Rust's Cargo. And npm is still well ahead of Cargo in the richness of the package ecosystem. For pure performance, you can always write a native Node addon [2]. And, as mentioned, while JavaScript isn't concurrent at all, the Node platform provides the concurrency model in a way that has proven to be scalable but without most of the pain that comes with writing concurrent code. Writing concurrent code is hard...that's not news. The Node framework make writing concurrent code significantly easier by creating abstractions that hide the the fact that code is concurrent.
I know it's bizarre to look at it this way, since you would be writing most of your application logic in JavaScript, but try to look at it as an implementation detail and consider the advantages of the Node platform and the ecosystem that surrounds it. When you take this perspective, Node becomes a lot more attractive than the JavaScript language is on its own.
At this point you can probably say choosing node/js is similar to why you would choose Ruby or Python or PHP for your backend, it's another scripting language that offers decent performance, a large ecosystem and good developer productivity. It really boils down to preference in syntax, tooling and ethos ("micro frameworks", "batteries included" or somewhere in between). At this point I'm so comfortable in JS that I can be very productive in Node compared to the ramp up time I would require for Rails, django etc.
I cant answer for keithwhor I think websocket support is a huge + for picking nodejs.
Lately rails got their socket support, and python3 has been getting better support through async, but in both those languages, I've long felt its been pretty experimental, and there simply hasnt been a performant option available that has a good opinionated framework.
Nodejs has performance going for it at least if you look at the language benchmarks, and now with ES6, it feels like the language is finally starting to shape up.
Nodal doesn't have built-in socket support right now but the benefits of non-blocking IO in node are obviously huge.
(It will. I just want to make sure I do integrated socket support right. I don't want to chase realtime frameworks because that's not Nodal's value prop, but I do want it to be easy to create socket connections when they're needed.)
Elixir + Phoenix seems like a better choice if websockets is going to be a core feature, since the BEAM's concurrency model is better and Phoenix's "Channels" abstraction is so solid. I wouldn't think of using Rails for that use case, even with ActionCable in tow, unless it was a minor feature.
YES!!! I've been looking very carefully at this, but Elixir still feels intimidating to me. A friend of me gave me an ebook which I'm working through at the moment.
For me, the jury is still out on whether I will be able to model my domain well in a language like Elixir.. I love Haskell, but I sometimes wonder if its a healthy attitude to be so stubbornly against OO. That said, I understand the arguments against essentially `this` and mutability. Any pointers on how to model your domain model in FP would be really welcome!
One major advantage I can see is if you're a full stack dev. You don't have a switch languages when you're building the backend and the front end. Some people may not see this as an advantage, but personally it takes some time for my brain to switch to javascript for the front end when I've been using either java, python, or ruby for the backend.
i could imagine that a decent full stack dev would rather use the right tool for the right job. thinking your scenario further, you would use something like couchdb instead of a relational db, because it utilizes javascript.
> i could imagine that a decent full stack dev would rather use the right tool for the right job.
The right tool depends on the requirements. If there's no special requirements then I don't see why javascript can't be a substitute for ruby, python, php, or perl on the backend.
> you would use something like couchdb instead of a relational db
I'm not sure this is a good analogy since javascript (as well as the backend languages that it seeks to substitute for) is more of a general purpose tool, and not a super specialized datastore.
> ease/speed of prototyping, pure performance, a good concurrency model
out of curiosity, which language + library/framework pairs do you think is a better tool than javascript + nodejs when evaluated along each of your 3 metrics?
I moved from python + flask to nodejs a while ago, I still thing nodejs is better than python + flask, but I'm trying to move away from javascript on the backend.
>> ease/speed of prototyping, pure performance, a good concurrency model
> out of curiosity, which language + library/framework pairs do you think is a better tool than javascript + nodejs when evaluated along each of your 3 metrics?
ease/speed of prototyping: Ruby (or Python, even), Go, [Crystal]
pure performance: Go, Rust, C++, C, Scala, [Crystal]
a good concurrency model: Erlang, Go, [Crystal (similar to Go)]
A small note about why Crystal is in brackets: The language is very young compared to the rest, and it's currently very volatile in terms of syntax/API stability, or even compiler semantics, but it looks very promising and it's quite easy to get started with it or to become a contributor because the compiler is written in itself. http://crystal-lang.org/ (Sadly, /docs is a bit outdated and misses some crucial parts, but /api is very comprehensive).
Clojure - if you're looking for a dynamically typed language with REPL driven development process - it can leverage the huge JVM ecosystem and the concurrency tools are best in class compared to mainstream languages. Performance often comes down to idiomatic vs optimized - but you can optimize stuff and there's always "drop to Java transparently" card if you hit a wall in some area.
I choose Rails for fast prototyping, recently Go if I want pure performance that I can't get from caching, and Elixir + Phoenix if I need a good concurrency model and/or high throughput, but don't necessarily care about the microseconds that can be shaved off with Go.
I believe the main selling point is sharing business code in both client and server, recently known as Isomorphic Javascript Applications.
I think that this is specially appealing for people that are building offline enabled clients, which end up having to handle more business logic than usual for client-side code.
A big chunk of UI work is typically input validation which should happen client side and server side. And you'll usually need regex for this at somepoint. Having the same validation logic and regex engine on either side is a huge win.
In practice that depends on the app quite a bit, something like http://marshmallow.readthedocs.org/en/latest/ makes validation a breeze on the backend for an API and you will need the database for more complex ones anyway. Again that probably depends on the app, but the only duplication in mine right now would be the password length which is a 1 character change.
Another reason : you can send ops over the wire rather than data. For example, you can send "add 7 to x" when the user makes a change rather than "set x to 21". Then you use the same code on server and client side to execute the ops.
If you structure your ops to be reorderable and composable you can get nice stuff like multi user editing, arbitrary undo, multi data centre synchronization, etc.
Google for "Operational Transformation". That turns up lots of good stuff. The wikipedia article includes links to Google Wave papers, which I think is the papers I'm referring to. It's been several years since I read them, though.
Well at the very least your are missing isomorphic/universal apps. One case when it's best in class is edge servers backing mobile clients/SPAs that need to have millions of web sockets open. Tooling I can have single package manager for backend and frontend I can use same packages on backend and frontend. I can use single language to develop for Server,Web,Mobile.
For example I'm taking some front end javascript I've been working on and putting it on the server (using another new node framework based on Laravel that so far I really like: http://adonisjs.com ) and it would definitely perform better if I rewrote it in Go or Elixir - but even if I could figure out how to do that if the thing takes off I could never find anyone to help me with it.
With JS though it should perform reasonably well (node is supposedly pretty fast where it counts, nonblocking and all that) and I could hire a danged high school kid to give me a hand with it if it somehow succeeds. I imagine a company like Walmart was thinking along those same lines when it chose Node.
Client/server data sync and optimizations like server side rendering are easier with code-sharing between client and server. Though as far as I can tell, this framework doesn't leverage code sharing for either purpose.
Everyone knows how to javascript, that's why it's the best. It's really that simple, put yourself in a position where you have to hire, you'll see why.
(These comments are just from watching the first video.)
But how is this next-generation? It seems to be very inspired by established widely used web frameworks such as Ruby on Rails. With elements such as ORM, routing, controllers, HTML templates.
It also seems to require a lot of code generation. Is that really constructive? (What happens if I edit the various generated files, would I still be able to add field to a record using the command line tools). Couldn't you have moved some of the boilerplate into the framework?
Why not use ES6 imports? (Rather than require / Nodal.require)
Why create an ORM rather than use a JavaScript-orientated NoSQL database? (mongo, couch etc.)
>Why create an ORM rather than use a JavaScript-orientated NoSQL database? (mongo, couch etc.)
I could be way off here (and I probably am) but shouldn't frameworks abstain from being too opinionated about the particular technologies that you use? The database (or type of db) you choose seems like something that should be based on what your application's requirements dictate not what your framework prefers right?
My opinion differs: if you're going to package your tool as a "framework" rather than a "library", you should integrate a large vertical section of the technology being used. This doesn't mean you have to be coupled with a particular database server, but you should at least have special support for one that can be swapped out for something else.
If a framework can't offer me this kind of functionality, why would I want to use it over a library with all the control benefits that brings.
> Why create an ORM rather than use a JavaScript-orientated NoSQL database? (mongo, couch etc.)
NoSQL has its place, but it's usually not the best choice. Any "comprehensive" web framework should cater to the needs of RDBMS users at a minimum, with support for NoSQL as a plus.
The main benefit I see of import is for client-side code, so that you can statically determine a file's imports ahead of time without actually having to run the code.
Require is a regular function rather than a directive, and is probably needed for this framework to automatically find and load all controllers, models, etc.
The project is still 0.5 and it has a lot of cool ideas that most other NodeJS frameworks lack. That being said, here are the things I feel would be worth improving, based on the first video:
Writing tests for the Controllers would be a real pain, because you would have to do a lot of ad hoc mocking, it would be better if the controllers would return something instead of calling the this.render.
You might be able to make the the controllers into POJO's.
The file naming conventions are weird, mixing camel case coding with underscore filenames is just unnatural.
Having a custom 'require' function in the framework, means that any code I write, is dependent on the framework itself.
The automatic migration generation is pretty sweet.
Coupling the data models with DB configuration is a bad habit.
The use of static methods to define aspects doesn't feel natural.
Having one big routing file doesn't scale, the routings should be expressed in the controllers.
Overall I would recommend adding in TypeScript, it would allow a lot more cleaner code.
Thanks for the suggestions, but a lot of the things you dislike were choices made very purposefully.
1. POJOs are ugly and you must revert back to using Object.create() for inheritance, breaking the design pattern of using ES6's class syntax.
2. PascalCase class <-> camelCase instance <-> underscore_filename <-> underscore_tablename is a standard borrowed from Rails and easily managed through the npm inflect module (i).
3. It's just a shortcut. You can use normal CommonJS require(), you'll just have to resolve the relative path yourself.
4. Thanks! :)
5. Models can exist without database connections and with manually defined schemas. If you check through the commit history, I used to keep database and model completely separate but there was way too much code reuse / smell (passing in a db as a parameter on every function call).
6. The alternative is setting properties with ClassName.prototype.value = 'xyz'; or ClassName.value = 'abc'; Static methods provide an easy to read + concise way to do this for you (and take care of additional functionality). Also borrowed from Rails.
7. Chose that pattern because it is very explicit / ordered. How do I determine what order the routes are hit when I specify them per Controller? And if I define them on the Controller, that means I need to load all Controllers globally on Application start.
This looks interesting, and although I'm already committed to an ad-hoc framework on my current projects, I'll check it out for future ideas (or to import some of your ideas into my current projects).
Having the framework be batteries-included is nice, but also nice would be decomposing it into modules. For a good example of this, check out the Hapi.js server ecosystem. Lots of different plugins, and if you want object validation outside of the hapi.js world, you can just use Joi alone. It lets me mix-and-match stuff. A concrete thing here is the ORM layer (which hapi.js doesn't have). If I could pull your ORM out from the server stuff, I'd be a lot more likely to take that part at least for a spin.
promises are rad, and I know I can just use Bluebird's promisifyAll to wrap your code. But still, it would be nice if I didn't have to muck around with that and async methods called without a callback returned a promise by default.
middleware is rad, it lets me abstract out pre-processing that happens on (say) every POST route to validate parameters. It doesn't look really feasible to do that with this system. I'd basically just have to bake all that into the post() method, which isn't super-modular and is probably harder to write unit tests for.
can't say that I'm wild about regex routes by default. I dig stuff like 'items/:itemId' with named parameters in a microsyntax. Makes life a lot easier.
Nodal supports Middleware for post-processing controller output (gzip, etc.) and I could do something similar for pre-processing but right now it's just encouraged that you write your own intermediate controller, get all controllers to inherit from it and do something like a super call. Will think about what pre-processing middleware would look like / be called.
Yah, I had thought about inheritance and super, but without multiple inheritance, it'd be tricky.
Basically a lot of my routes do stuff like parameter validation (I store specific criteria on the model class, but apply them in the route), creating a new object from validated post params, loading from the database, storing to the database, authorizing and authenticating, etc. Then my route definition declares the per route middleware and the specific controller only has to encapsulate route specific business logic.
I could do that just by putting it all in a utils package and calling loadItem(), validate params() etc at the top of each handler, but that feels less elegant.
It may be that I've just been using hapi.js for too long, the modularity and composition in that framewrok.is quite elegant, IMO.
I came here to mention Hapi, so I'll piggyback on your post.
For those looking for an "enterprise" alternative to Express, give Hapi a try! It's very mature, has tons of extension modules (as pfooti mentions), and basically can do mostly everything you need without your needing to write much glue code.
Also, if you use typescript, it has a .d.ts file at Definitely Typed. (I wrote it)
I'm sure as Nodal matures the core components will become more (and not less) modular. I'll make sure of it. Helps with testing, extensibility, etc. I've refactored several pieces numerous times as complexity (due to tight-coupling) became too high. The Composer (ORM) used to be twice the size, three modules, and not nearly as capable as it is now.
You'd save yourself one line of indentation if you encouraged module.exports = Controller; at the end of the file instead. Node already puts a closure around the module, no need for another one.
I like the IIFE because of the way it reads. A developer new to Node.js It's impossible to miss. Putting your export line at the bottom is begging for silly bugs. Even if they're quick fixes, still annoying.
would be the clearest and least bug-prone and satisfies the "no extra closures" complaint. Considering you're buying into other ES6isms, why not use that one too?
Haha! Wow! A friend I've known since 5th grade made a bunch of different logo variations and I chose that one. Swear neither of us have ever seen / heard of this company. Hilarious (?). I liked it because it reminded me loosely of the N64 logo.
Perhaps it is just me, but I much prefer functionality broken down in small packages, rather than offered as a complete framework. The advantage is that module boundaries are more clearly defined, and that parts can be more easily understood, and, most importantly, they can be more easily replaced.
Yeah, I know not everyone puts much stock in accessibility but this is actually really hard to read thanks to the contrast. Hopefully if the devs do see this they can check their colours here:
Thanks for this. I'm not a (visual) designer by nature so I often miss things like this. I've made a small adjustment, but I'll make a bigger one as soon as I can!
Understand completely. I share the same feelings, which is why I built Nodal. I was building my Node applications from the ground and building the same things each time ;), felt I wanted a standard set of tools.
I'm really flattered you found things you thought were interesting! Would you care to share?
I'm slowly starting to genuinely understand DHH Omakase rant. The whole "modularity" part of Node doesn't seem to work out so well. Constantly have to look for third party support for simple but necessary things. Eg Strong Params, json builders or a Mailer. I wish there was JS framework that offered everything out of the box as a first party support or at least a decent API libraries could use. Like ActiveModel is used by various NoSQL gems.
I think it depends on what you do. I spent first half of my career ordering a la carte.. In hindsight, I ended up building a lot of crap that the framework should have provided for me.
This is the major reason why I have learned to be cautious with getting wowed by the apparent simplicity of micro frameworks.
At the very minimum, I want a framework to have an opinionated model layer with migration support, and chances are you will get trickle down benefits from frameworks that have opinionated M layer..
Look at djangos form abstraction for instance. Or the way validation is handled in Django models, which in turn opens up for the possibility of creating a neat REST abstraction. These are the types of abstractions that you end up writing yourself or not writing at all when you go the 'light framework' route, but they are almost always handy and will save you time.
Sometimes you want something like Rails or Django. Then express and similar "a la carte" solutions won't help you and you'll end up re-inventing frameworks and re-implementing the same old bugs and mistakes.
Sometimes you just want a small single-purpose server. Then Node and NPM shine and big frameworks seem like unwieldy behemoths in comparison.
Personally I'd say Node isn't a good choice for the former and you'd be better off with something powered by Ruby, Python or PHP (i.e. Rails, Django etc). And I say that as someone who's been almost exclusively using JavaScript for the past couple of years.
The docs do seem to be a little lacking - it's mostly technical stuff about methods and might not be what the developer is looking for. Looking at documentations from Laravel, SailsJS, even Django, it's easier to get the point of what you're expected to do to get X done.
Other notes on the documentation:
* Very little info on how the templates (views) work. Can I use a different engine for them? No info about that.
* (just as an example of many) I've noticed that a scheduler is implemented and that it's mentioned in the site. It is also noted on github that there's no info on the scheduler yet. So, why would you include the features that no one will be able to use unless they're willing to get into the source code of Nodal itself?
I see that the project has been going for almost a year now and it looks like it's going a great direction. Just needs a more user friendly documentation to be fully usable, I'd say.
I still have so much work to do to ensure there's great community support. I've been too cautious to release software in the past and over-optimized for the wrong things. My goal is to get this out in the wild so I can learn what people are most interested in, and optimize from there. Everything will be covered soon!
I won't speak for anyone else, but looking at the code samples, pretty much everything I was worried about in terms of readability for ES6/silly uses of 'this' is present here. It just looks a bit arcane.
I appreciate the DSL-for-problem approach, but this is kinda exactly what some of us were worried about.
The source is amazing for anyone wanting to learn how to write decent MVC framework. Though I got some reservation about letting users write regex for routes and middleware execution being so far late in the chain (at render).
While looking through the documentation for reasons to use this, I stumbled upon some points regarding modularity in the "Why Nodal?" section of the readme. I think that this should be emphasised.
But not is inherently modular, in-and-of-itself. Wouldn't Nodal make it _less_ so? Because now I have this ORM built-in, the router built-in, the scheduler built-in, etc. With a standard Node project, I can just pick my own ORM, router, and scheduler, as I see fit.
It may be a great framework, but that strikes me as an odd point to make about the project.
Systems modularity. Nodal is about building independent micro services which each have their own internal consistency (the Nodal environment) but are not tied to each other. Nodal just encourages you to optimize for systems first to build a product / business and spend less time worrying about granular technical decisions.
IMO that is also one of the strong parts of the mature package management that comes with Node.js: it's super easy to have a really small project in a couple of minutes with exactly the dependencies you need.
FWIW, I checked out at the "go install PostGres" pre-requisite. I'd prefer either being less opinionated about pgsql or making the dependency transparent via something like Docker.
I've not read all the documentation yet, but I'm assuming you can tell Nodal to use any arbitrary IP:PORT for the database, which would allow for Docker.
The framework might be good, but you need to ditch that video and replace it with some example code. I need to know why it is better than Express or other Node frameworks and what it is like to work with - also you claimed it was next generation. How do you justify that claim?
It could the best framework ever, but without an example all that stuff is useless. The video could help, but it is a) way too long and b) appears to be pretty slow in showing the meat.
Problem is that node is buggy as hell. Try and do something more trivial than basic I/O and you are going to face lots of them. Its almost a decade since node hype has begun and still you will hardly find any large, well-known website being powered by node is the testament to this fact.
Also, if you read the docs of any major API implementation, you will find examples in python, php, java, etc. but I'm yet to come across a node example. Node ain't ready for the real world yet.
It sounds like you haven't used Node or read API docs in several years. Developing for Node full-time for the past few years, I've yet to find any bugs in the standard library or runtime. And, just glancing around at a few "major API docs" that come to mind, all that included code examples (PayPal, Stripe, IBM Bluemix, MaxMind) included Node.js examples.
You're right. PayPal, Uber, Walmart are all tiny little nobodies. And I'm not entirely certain what api implementation docs you're looking at, but I've yet to say, "I need service X" and not find a node.js API wrapper already built.
I dont have experience to corroborate, but I can say I have been seeing a lot of interest in Node even from people in the enterprise crowd. Places that would ordinarily be writing stuff in Java and .NET are turning to Node instead..
It's a tool, and like every other tool comes with its pros and cons. I am not saying Node is the perfect fit for any project, because it isn't. However stating it isn't used and almost a decade is just wrong.
This looks like a node framework that I'd really enjoy using - first time I see a framework that feels like it fits around ES6. For me personally, having a good ORM and models layer, coupled with migrations have been a deal breaker in choosing a framework, and I'm very happy to see that here.
Is everything written from scratch or are there dependencies? If so, it sounds like its actually quite an opinionated microservice architecture.. Lately I've felt like microservice and microframeworks have gone hand in hand :)
Great job!