Hey everyone out there! Hope you all have a good time!

Maybe some of you know that some two to three weeks ago @georginagrey asked Hashnode:

What do you think are the most important skills/tools that every full-stack software developer should master?

At first, I was a bit hesitant. This kind of question is difficult to answer in a few short readable lines. So I read the answers at the time and I had to disagree with them. As sleepy as I was, I sat down and threw an answer at her (please take no offence for assuming your gender...). It was just an enumeration of things I consider really important. But my answer received so much love, that I decided to rewrite it as a "story". Here is to everyone who requested it: @devmal @mariacarey @paulfwatts

Quick Jump List

Preface

First things first. After reading my post a few times and comparing it to other popular answers, I noticed that I did not mention any JS library at all. So, before I go for the meat, here is why I did not include any libraries.

Libraries are not important. Forget about the libraries.

There will always be libraries you can use, but it highly depends on the problem you try to solve which of the libraries available are important. There are no universal libraries out there and very often you have many good libraries which try to solve the same problem. Choosing one tool over another highly depends on personal taste. Also, when choosing libraries, do not follow hypes. There are a lot of libraries out there which are hyped, but also, because of the hype, miss-used. I see a lot of people who try to build small homepages with some big boilerplate, like MERN with React, Redux, NoSQL DB,... which was originally intended for big, highly dynamic web applications, like Hashnode (thanks @ Hashnode for open-sourcing your base stuff!). That is why I want to refrain from recommending any library at all! Only use what you really need and only if it is a real advantage. Libraries come and go and will have bugs and introduce new problems. I am a minimalist and I try to do things myself without pulling in too many extra dependencies, when things can be done easily by myself.

Well then, but what skills should I have as a Full Stack Developer? (tl;dr)

First of all you have to understand, what a "Full Stack Developer" (FSD) is. A FSD is a person, who is familiar with all layers necessary in order to request a homepage, respond to the request and last but not least generate the website/web application for an end-user. These layers consist of

Database

Server

Network

Client

However, it's not just those specific things a FSD should know. There are a lot of general programming patterns and universal knowledge which should be a must-know for every FSD. Most of these patterns will improve your code architecture by decoupling things, advice you on security and optimize performance and resource usage by implementing little tricks. Also there are principles which make your code a lot more maintainable. This is very helpful when you want to work on a project for longer than a week or even just one more person. Keep your eyes open for patterns, even when the article is about some other language, like C++, Python, ...

Database / Data Origin

Though sometimes a bit underrated, I think a web developer should be able to store and load data in an ordered fashion. One of the best ways to store data in a ordered fashion is to use databases. Imho knowing how to use the two prevailing types: SQL and NoSQL is a must-know kind of thing. The first decision you need to make is which architecture is the right one. So you need to know the differences, advantages and disadvantages of each type. Also you should know at least one or two implementations of each (not only the name). Personally, on the SQL side, I consider MSSQL and Oracle the most important when working in an enterprise context, else MySQL/MariaDB (but, as I said before, that is no recommendation, just my preference and what I think is important). Consequently what that means is that you need to know ANSI SQL which is understood by all SQL databases plus the differences between the dialects (and data types). Consider the following example of two queries which do the exact same thing:

SELECT TOP 2 [foo] FROM [ sample ]..[bar];

vs

SELECT `foo` FROM `sample` . `bar` LIMIT 2 ;

You can learn about ANSI SQL on Wikipedia or at w3schools. The different dialects are documented on the official homepages of the database servers.

On the NoSQL side, I think you should have heard about MongoDB and ArangoDB. While, language-wise, the SQL side is pretty simple since everything stems from ANSI SQL, developers run wild with NoSQL. There are databases which go for a JSON-like syntax while others take a SQL-like route. Compare the following two queries, given a similar schema and the same intention as for the SQL queries above:

sample.bar.find({}, { foo: 1 }).limit( 2 )

vs

FOR row IN bar LIMIT 2 RETURN { foo: row.foo }

Please read about the exact specs and license limits of the different servers before selecting one!

In addition to the different SQL database types, you should know about general things, like DB normalization. Always try to normalize your databases for a better overview and good scalability! In many cases, normalization will also lead to a smaller data size and better performance. Aside from normalization, every DB has some specific optimizations, for example differences between FLOAT and DECIMAL, which might affect performance. You will either need to read and benchmark a lot or hire a professional to get the biggest bang out of your DB. Personally, I do not think that those specific optimizations are the job of a developer.

Server / Data Processing

The one instance all requests and initial data processing revolve around is the server. As it is the only part you can actively control and which is independent from the others, you will probably spend quite a while setting up the server in a way which is most optimal for your project. So you will have to take a lot of time considering what you set up and how you set it up. This might change a lot in your project later on!

The first question you should ask yourself is:

How will my application work? Does it use a lot of static content or do I have to generate a lot of stuff? Do I need real-time communication?

The answer to those questions will determine if all you need is an Apache web server or some fancy Node.JS, Java, Go, Erlang, Python,.... server application. Try to have as much static content as possible. If your site has a lot of static content and does not need real-time communication (for example a simple eCommerce shop), you should go with a simple setup which utilizes proven tools. For these kind of situations, a simple HTML Preprocessor, like PHP or embedded JS or Mustache JS or something else, is enough! You might want to talk to your admins about caching resources (e.g. with Varnish).

Guess what? Writing your own application is a lot more difficult. It requires you to choose from many languages, create a network listener, write a protocol parser, and when you are done finally your application's logic. Very often you will find that all those extra hurdles are necessary. Also, very often, you will find that there are already nice libraries which do the annoying part for you. Things you have to consider when writing an entire application like this might be a little out of scope. However, let me tell you that it is vital that you know how your technology works under the hood. Just as an example, have you ever read the Node.JS source code which loads all the modules? I certainly have! It's not a whole lot of code, but it might allow you to do some new tricks because you suddenly know black magic :)

In addition to knowing how stuff works, you really should know about how to write a good interface. You want to create a server client should connect to. In order to have a good communication between client and server, clear, standard-compliant interfaces are vital. Just as an example: If you decide to only format data as JSON, stick to it and never allow XML. By the way, the two mentioned formats are quite important in order to structure data and I highly recommend knowing them. There are others, which might be more fitting, but most stuff you might be working with will probably use one of those two.

Once you decided on the data container format, you need to think about state. Now, state is a unique configuration of stored information. An example might be: Is the user logged in or not?

How do you want to handle state?

Depending on your decision, you should know about RESTful, RPCs and Sessions. RESTful makes a lot of things very convenient, but also introduces some trouble, like problems with clustered servers + caching or which verb to use. A RESTless (non-RESTful) API on the other hand allows the server to aggregate information and expose a custom API. You can just do some RPC in order to call your custom logic with custom parameters. A RESTless architecture also allows you to have sessions. This approach is more natural, but the downside is that more custom logic is required, too.

STOP RIGHT THERE! Before starting to plan and implement everything, a good FSD should take a look at security. The easiest thing to do is use the OWASP ASVS checklist, decide on one of the three levels and add all items to your plans. There are other great sources and ideas on how to improve security for your users, how to react to malware and hacking attempts (even 0-day bug users). OWASP contains many articles and projects, but for big companies you should hire a professional.

After setting up your interface and the communication, you should think about optimizing the performance of your application. Most of the time, you only need to think about what things you can cache (keep in memory after generation) and how to invalidate the cache (update whatever is in memory at the right moment).

There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton

The second popular way to highly improve performance is to compress your data in order to boost the transfer speed. In the web context, the most used algorithm for compression is gzip. Be careful, however, because small data blobs (people say <256Bytes) will result in a bigger size when compressed.

Network / Data Transfer

Not matter if you make a request or send back data to your client via HTTP, if you use websockets or raw TCP or UDP. You will always have some kind of network and protocol to deal with. Especially in a browser, all the low-level stuff is hidden pretty well. I think, it's amazing, that all you need is one line of code to open a socket connection and one line to send data over it. But there-in lies a problem! People tend to forget about the low-level stuff. Tricks in order to improve performance, security and traffic. That's why, in my opinion, it is very important to know at least the basics about TCP (RFC 793), the most-used protocol for network traffic at the moment. That way you can understand, why it is slow and what you can do in order to speed up our apps.

The next big thing in the chain of networking protocols is HTTP (RFC 7230 / RFC 7231 / RFC 7232 / RFC 7540). It has a lot of potential in headers and implementations which are often left unused (especially on the server-side).

On top of protocols, like HTTP, you should be able to use common data structures, like XML (W3C) and JSON (RFC 7159).

Client / Data Presentation

Well, after knowing all the stuff I told you about above, you still need to know the place where a new request is born and ends. Some client! And while I wrote about browsers in the mentioned answer, I want to correct myself! You do not always have a browser. What you create is a web application which can be displayed with any compatible piece of software. That means, you will have to write standards compliant request results. For the W3, that means HTML for the structure, CSS for the style and JavaScript for the logic. You might as well use some other fancy language which compiles to JS, but when it comes to debugging, you will need JS no matter what. That's why I do not consider other languages, like TypeScript, as important. Those languages are more about personal taste and what feels good for you and your team. Either way, personally, I think that it is very important to know the latest features available, even if you cannot use them in your current project (because you have to support IE8). A good source for learning is w3schools, which once had a few inaccuracies in its tutorials, but nowadays it is quite good, easy to follow and even later, long after you mastered everything, a great source when you need to look something up. Other than that I recommend the Mozilla Dev Network for looking up things, as it has the latest and the greatest features with simple examples.

HTML

For HTML, one of the most important and probably underrated things to do is writing semantic HTML (what is that?). Your users will not only be healthy people browing your site with the latest Chrome. Your users might be blind and completely dependent on screen-readers. The more information your HTML contains about the content in between your tags, the more accurate can it be interpreted. Here is an example:

This is < b > important </ b > ! This is < strong > important </ strong > !

But not only semantic HTML is very important for screen-readers. You probably want to make an interactive web experience, which is accessible at the same time. Todays screen-readers can do so much more than just read. They also tell the user where the curser currently is and what will happen when they click. You really should learn about ways to make interactive elements accessible.

Speaking about interaction, did you know that there are so-called Microformats? Microformats offer an additional standardized way to deliver information to a user, but in a way which will integrate with UX they are already used to. For example the browser will be able to ask the user if they want to save your vCard. Browser native controls or plugins should always be preferred to some custom solution.

CSS

While HTML is your basic structure and important for how a user can interact with your website, CSS is important for styling your site. What color should the font have, how wide should a certain image be, in what way will your website scale for different viewport sizes, etc. Since there are countless browsers and other clients in many different versions you want to support, you will have to find a way to make your website look the same similar good, no matter the client software. The first step to do so is normalization: overwriting all default CSS values with your very own default values. For this kind of task, I really like the HTML5Boilerplate CSS files. Apart from that, you should watch out for some dangerous CSS attributes, which might be interpreted and displayed differently in different products. One of these dangerous attributes might be the padding attribute. Last but not least you have to make sure that whatever you want to display looks good on all kind of devices. That's why it is important to know about responsive design and how to take a device-agnostic approach on that. In that context, especially client hints can be very useful in order to prevent content shifting on those small smartphone screens where overview is lost very easily.

Because of all those measurements, you will have to write a lot of CSS. For a beginner, this is one of those tasks which you just do, and later, when you have to change somethingm, rewrite the entire stylesheet. That's why some very intelligent people came up with some very neat ideas on how to organize CSS for professional development. There are different ideas, but most of the time they revolve around using naming conventions, like namespacing and BEM for class names and some kind of specificity layering. In my humble opinion, the most noteworthy approaches are BEMIT and ITCSS, which might cover anything you ever needed to know about CSS architecture.

Seeing all this trouble you might consider using some big frameworks, like Bootstrap, so all you need to do is link them into your HTML and add a few small rules. Boy, never have you been more wrong. Not only will you still have to write a lot of CSS, you will also have to learn an additional library and you will devliver a huge overhead to your user which is never used. Try to refrain from using big frameworks. If you really have to use one, minify it removing all unused rules before rolling it out.

JS

Javascript. Or, as I joked with a friend of mine: "JeSus". Let me describe the language in one word: Rainbow Unicorn Flavoured Chewing Gum . Ok, that was five words, but basically that's just how flexible the language is. I love it. But at the same time, having all that freedom and flexibility is a curse. It makes optimization for low-level execution very hard, resulting in a very poor performance. Hence, try to avoid JS whenever possible. Many animations and effects can be achieved using modern CSS3, you just have to take a moment to figure out how they work. Lately, I have seen some extraordinary CSS stuff! I saw an animated dog. Animated with the power of CSS3. AWESOME!

Of course, not everything can be done with CSS. Asynchronous calls to your API are a good excuse to use JS. But then again, try to limit the amount of JS code. You do not need jQuery just for an AJAX call and selecting some class. VanillaJS already is very short and easy to use. All modern browsers support the stuff jQuery was good for. Oh, I do not think, jQuery is a bad library. It's just about how you use it. It's the same for some other libraries, like Angular and React. Make sure you really need those libraries before adding them to your project.

General Programming

In general, when programming an application, no matter if you use JS (server/browser) or PHP or Ruby or w/e, it is important to know a little bit about how to create a solid architecture. It is important that an application

is easy to develop

is easy to maintain (even after many years, when the original developers have long left the company)

has a performant hot-path

does not leak and

is resource-economical in general.

In order to meet all those demands, a good programmer should know at least a few programming patterns by heart. If you don't know where to find good ones, try your luck with "Game Programming Patterns". In game development, all the mentioned items are especially important, as games are very big, often monolithic pieces of software which have to perform very well on limited hardware.

If patterns are not enough, try to get a deeper understanding of how your standard-libraries work. You can often find shortcuts and little hacks. Just as an example, you should read the source code of Node.JS's require() function. You might learn a lot of new things from it.

Miscellaneous Stuff

Wow, that was one big story! I really hope you liked it. After writing so much, there's only little left to say. Keep informed, learn new stuff (for example about UX and typography) and talk about what you are doing, about your ideas, findings, problems. Help build a good community so everyone can profit from each other. You can do so right here, on Hashnode :)

If I should have forgotten something, please leave a comment. I might add things later on. Web Development is an ever-evolving field with very many topics, so I cannot even begin to get everything into one simple text.

PS.: The cover is a photo I just took from my apartment window. HDR is nice, but my photo-skills are still very bad :D