One thing node is lacking is a clear set of principles and/or philosophy. Nothing too serious, something along the lines of Python's PEP 20 Zen of Python. Pulling from the history of the project and decisions already made and refined through comments from close friends and node contributors, this is what I'm calling "The Way of Node."
None of these are new or even recent revelations. The majority of these tenets have been articulated by Ryan and other community leaders for some time but much of that understanding has failed to spread throughout the community because it’s never been articulated very concisely. However, these points deserve a more in-depth explanation of where they come from and what they really mean.
Ryan described his earliest releases in terms of what he was binding to--V8 (which presumes JavaScript), libeio & libev (now replaced by libuv) and his HTTP parser (written in C). What he demonstrated is that by simply pulling these components together you have a compelling platform you can use to build servers. Ryan was also adamant about keeping this platform small and enabling a module community without shipping with a large standard library the way other contemporary platforms do.
Node will always be written in JavaScript (as well as C and C++ where necessary) and will never be built in a language that compiles to JavaScript. As JavaScript becomes more of a compile target and libuv bindings are written for more and more languages it is worth noting that Node is and will always be JavaScript. Node will not go out of its way to disable the use of languages that compile to JavaScript but they will never have a support equal to JavaScript.
Node is JavaScript but JavaScript is not Node. The Node community accepts JavaScript as defined by the VM it is bound to. The Node community is not defining or extending the JavaScript language.
Since the removal of Promises Ryan has been adamant that Node include only two API’s for dealing with IO: a standard callback API and Streams. Operations that can be completed in a single callback use the standard callback interface. Sockets and other file descriptors require an abstraction that can emit multiple chunks of data over a long period of time and handle “push back” from a remote end and Node continues to build and refine the Stream API to handle this case.
This is a design tenet Ryan iterated well to early node contributors. APIs that appear not to incur IO but do are the leakiest of abstractions. The most obvious differentiation this makes is between Node and platforms that use threads but this design principle extends to similar APIs using coroutines that more efficiently yield the VM and potentially use non-blocking IO. It is a tenet of Node that any API that abstracts from the programmer the fact that they are going to do an IO operation is not Node.
Node will not grow to include new modules, no matter how good they are or how distributed they’ve become. The kind of inclusion that you see across other platforms that grow large standard libraries has a negative effect on continued growth and maturity of the module community.
Node is not a science experiment or an academic research project. Node is built for builders. Node is for making things, here and now.
Node is not one person, or one company, it is a community. A community of users, module developers, and core developers. Without a community the project will not thrive. Regardless of sponsorship, gatekeepers, or our BDFL, node survives by its community and would quickly die if it were ever to abandon it.
Node will not be satisfied until it is at the top of every benchmark. Node is never fast enough, Node will always get faster, Node will not get slower. Node will not abuse Moore’s law and will respect your CPU.
Obviously :)
In the process of drafting this myself and many of the editors started including joking tenets.