All Articles

How to choose a Tech Stack for your Web App

Tech stacks can be overwhelming
Choosing the right tech stack can be overwhelming...

Choosing the right tech stack might seem like a trivial task, but it is really a decision that should not be taken too lightly. In fact, once development has started, it can be very complicated to make large changes, as they might disrupt the flow more than you expected.

It is not a coincidence that IT consultancies earn a significant part of their revenue with projects that do not really add functionalities, but instead only update the tech stack.

A survey of 208 SAP users in Europe has found that businesses can expect to pay between $10m and $100m to migrate from their existing SAP system to S/4 Hana.

—Rimini Street

In this article, I will describe the technologies that the application shall run on, and tools that I have chosen to work with.

Tools

Okay, the tools might not seem like a big deal - after all, you could simply write code in Notepad, using vi or nano. However, using tools that agrees with you can drastically improve your performance, and also save you from a lot of frustration.

OS

The application should be able to run independently of the Operating System, as it will be containerized. However, for development purposes, I’d like to specify that everything will be developed on a computer that’s running on Ubuntu 20 (with potentially upgrading the OS version, if required).

This will also be the OS of the server the applications will be running on.

IDEs

Frontend

For the development of the frontend application, I will use WebStorm. I have thought for a while about using Visual Studio Code, mostly because it’s free (and supposedly awesome), but after doing some research, I found that WebStorm has some features that just slightly make it a favourite for many people. Also, if I’m honest, I just really like the products that JetBrains provides, and since I use IntelliJ professionally, the switch to WebStorm is just a little easier. I do have the ultimate version for both of these IDEs.

Backend

As already mentioned, for the Backend development, I will use IntelliJ. Now, this decision was a lot easier, since IntelliJ is just considered the absolute best for JVM based languages. Its out-of-the-box integration of technologies such as spring-boot, accompanied by a multitude of plugins (e.g. Cloud Code for Kubernetes) make this decision a no-brainer.

Additionally, all JetBrains products have a very cool Code with me feature, where multiple people can code together, with the changes happening only on one computer. This brings pair programming to a whole new level!

Databases

Finally, I will also use IntelliJ for any connections to the databases, as it has a plethora of languages it supports with smart completions. I could also use a specific program for this, but currently, this does not seem necessary.

Frontend Technologies

Code

The frontend will be developed with React. This decision was motivated in part because a good friend of mine, who is an absolute wizard in Javascript development, recommended this to me over Angular.

React is the library to use for new projects. Angular is used by large companies that migrate from Angular.js. Vue.js is used by hipsters. React is the currently the best skill to develop as a frontend developer looking to hone his skills.

—Anonymous frontend wizard

I have also noticed by talking to colleagues that more and more companies are developing their new frontends with React. Since many enterprise-based coders know Angular better, but the market share is increasing for React, I figured that having React on my resume would definitely be a large plus.

As for the coding language, I will use Typescript. I am a big fan of typed languages, and while Typescript is really just Javascript that can be typed, at least it’s already that. I am aware that I will still sometimes get very strange errors, but the IDE will more easily point me towards what seems fishy.

Layout

No surprises here - HTML5 and CSS. Though that’s not entirely true, as it will be TSX, meaning it’s Typescript based syntactic sugar on HTML. However, coding with React, I don’t really have a choice here.

Backend Technologies

Before starting a large discussion, I will just state that, for brevity, I consider everything that happens on servers to be backend.

Code

The backend applications will be REST-based microservices, developed in Kotlin. I have chosen Kotlin over Java, since it has some features that just make development more comfortable. I am a big fan of Java, too, but Kotlin takes it to the next level, by adding some ideas from other coding languages to it, yet still compiling to JVM-readable code.

Some cool features that I particularly enjoy are (non-exhaustive list):

  • Better handling of Optional: Since Java 8, Optionals are available, yet they can be cumbersome to use. Kotlin encourages the developer to be much more thorough, using simply a ?, and NullPointerExceptions are almost an idea of the past.
  • Usage of var and val: The developer is motivated to think more thoroughly about the design, really go over which items should be final and which values could change over the course of time (think data classes also). Libraries such as Lombok also enable this, but with Kotlin, it comes right with the language.
  • Coroutines: The easy spinning up of coroutines, as opposed to more expensive multithreading, is a big performance boost. For someone looking to not spend too much on CPU, this is obviously very enticing.
  • Sooooooo many utility methods: Java 11 finally offers List.of() to create a new list, but Kotlin has always had the idea of making developers’ lives as easy as possible in mind. As a counterpart of the aforementioned List.of(), it has mutableListOf(), listOf(), arrayListOf(), listOfNotNull(), etc.
  • Much more: less verbose code, smart casts, type inference, functional programming, …

Framework

As the framework to hold the entire code together, I am also not going to be particularly fancy. I’ll just use the newest versions of spring-boot.

This is really not that particular, but I will write some nice features anyway:

  • Great initializer, which already provides a skeleton with a bunch of chosen dependencies
  • Dependencies such as spring-boot-actuator, which will give monitoring endpoints out-of-the-box
  • Great support from the community
  • Many more reasons…

Testing

My choice for Unit testing is also quite straightforward, as that is done with JUnit. Of course, I will use the latest version, which, of time of writing, is Junit5. This is really the only choice for JVM-based languages.

As for mocking, I will not use Mockito. Mockito is awesome, and, in my humble opinion, extremely important for Unit Tests. However, whilst Mockito works just fine with Kotlin, it is optimised for Java, and therefore, I will instead use MockK, which is optimized for Kotlin. It has support for Kotlin-specific ideas, such as coroutine mocking, but most importantly, it was really written with Kotlin usage in mind.

Other testing approaches, such as Integration Testing or CI/CD frameworks will be covered in the infrastructure chapter.

Database

Yes, this is technically not backend, but meh, I’ll cover it here anyway.

For my choice of DB, I have pondered a bit, but I will go with my gut and use PostgreSQL. I have played with the idea of using MariaDB instead, because I’ve never worked with it. However, I am definitely not a Postgres expert by any means, and therefore I am going with what I already know, but with the idea of improving my knowledge there.

From what I’ve seen, both choices would have been just fine, and would have given me a great performance. Since Postgres seems to be less forgiving on mistakes however, that was the kicker for me, as I want to be made aware of any errors immediately, and not realize it in Production after a large chunk of time.

Using something such as OracleSQL never even really crossed my mind. I mean, why would I pay for a database, when there are such great, free options out there…

Infrastructure

Containerization

Since I am not living in the past century, I will obviously have my applications run in containers. The obvious choice here is Docker. My plan is definitely to treat my software like cattle, as I will need to kill and restart the applications quite a bit.

I actually really wanted to use Kubernetes. The reason I am not going to start with it is not because that’d be overkill (it definitely would be though…), but the required RAM to simply run a cluster is already advised to be 8GB, and that’d run up the costs for my servers just a bit too much. Not to even mention a manager Kubernetes cluster on AWS, Azure or GCP, as those would be multiple thousand bucks a year… Still a shame though, as Kubernetes just offers so much.

Hosting

As I already mentioned, I will be running the application on the Cloud. The typical PAAS options would be ideal, but they are too expensive for my needs.

Therefore, I will simply use IAAS and have a linux machine running Ubuntu. My provider will be Hetzner, as I have had a great experience with them, and they are also fairly cheap.

Streaming

I will be using asynchronous operations as well. Technically, I could run everything in a simple monolith - the application won’t be that huge. I do want to do things right though, and therefore have multiple backends running. Message queues would be a fine option, but event streaming with Kafka seems like a much more modern approach. It will take up some space, and the load I’m expecting is nowhere near what would warrant Kafka, but I am ok with that.

Repository

Naturally, I will be using Git to have versioning. There are multiple free options out there, but I will simply use GitHub. I am not that big a fan of BitBucket, and even though GitLab has always had a lot of cool features for DevOps pipelines, GitHub has definitely caught up with their GitHub Actions. I have played around a bit with them, and I was pleasantly surprised. I felt they were sometimes almost as powerful as Jenkins, for example.

Closing words

Well, there you have it - my planned tech stack for this application. Of course, this may change over time, but I feel like a lot can be accomplished with all the technologies that I have mentioned. I expect to add more, especially if my curiosity motivates me to add some additional feature using a technology that is way too powerful for what I’d do with it. I’ll state the main mission of this application again though - learning!

If you have any improvement ideas, feel free to post about them in the comment section!