What is the MERN stack, and how to work with it?
- Transfer
Hello, Habr!
Once upon a time, we released a pilot project on the MEAN stack (Mongo, Express, Angular, Node), which generally did not disappoint us, however, we decided not to do additional prints and updates at the time - unlike Manning, which updated this book . Nevertheless, we continue to search in this direction and today we would like to talk with you about the related MERN stack, where React is located on the client, not Angular. The floor is given to Tim Smith .
![](https://habrastorage.org/webt/1d/hf/l7/1dhfl7yw9am620o13r-nz-i4il8.jpeg)
Warning: all code for this article is here .
In this MERN stack guide, we will write a simple blog using React.js, Node.js, Express.js and MongoDB to expand our full-stack arsenal.
Perhaps the first thing to discuss is the idea of a "stack" as such. There are many different stacks, and all of them are just different paths to achieve the same goal. When creating a full-stack application, we provide for the client part with which the user will interact, and the same client part will mediate the work with the server and the database - making this entire process as simple and manageable as possible.
We can say that the stack is a certain set of technologies used to solve this problem.
Although there are many stacks worth talking about, some of them are more popular than others today. One of these popular stacks is called MEAN, and it consists of:
Today we will talk about the MERN stack, which is very similar to MEAN except that Angular.js is replaced here with React.js. Thus, we can use MongoDB as a database, Node.js and Express, respectively, for the server and routing, and React.js - to create the client part with which the user will interact.
Before moving on to all the subtleties, let's take a general look at how all these elements work together. Personally, it took me a while to delve into this, since my background is related to PHP, where the client and server parts are somewhat mixed up.
1. Server part (Node and Express.js) and client part (React.js)
First of all, you need to understand that the server part and client part are separate entities. The client part may be in the same repository with the server, or maybe in a completely different one.
2. API terminals are used for communication
If you are already thinking about how to make friends of the client and server parts, I will answer: this is done through the API. An API (application program interface) is created on the server, where we will get “terminals” through which the application located in the client part can interact with the server.
Let’s explain on fingers: imagine that your left hand is the server side, and your right hand is the client side.
Now fold your hands and twist your fingers as if you were shaking your own hand. That is how template languages work. They allow you to simply display some markup along with the data dumped with the servers - and in them the client and server components overlap to a large extent.
Now open your hands. Spread your fingers as wide as possible and make sure that your left and right hands are touching only with your fingertips. This is how the MERN stack works. The server part provides terminals (fingertips from the left hand) to access the server, to which the client sends calls (through the tips of the fingers of the right hand) and through these points of contact exchanges information with the server (left hand).
I hope it has become a little clearer, and if not, forget all this metaphor, as if I had not mentioned it.
Although I’m not going to give step-by-step instructions on how to build this stack here (this is a topic for a separate article), I would like to consider various elements of the stack that are usually used or can be used in it. I myself read several manuals that told how to configure the server, but did not explain why these particular libraries are used for this.
After we create the app.js file, you will need to install a number of packages. The following are the most common packages that I have previously used in my projects with Express.js - maybe they will come in handy for you too.
Of course, there are many other packages, but in my experience, it is these libraries that are used most often.
So, after sorting out some of the most heavily used packages, let's look at the code. For starters, our server:
![](https://habrastorage.org/webt/xk/g7/f_/xkg7f_3zeltvgqsj-knjstppros.png)
This is a simple API server. As you can see, it is equipped with the basic CRUD (Create-Read-Update-Delete) functionality - nothing supernatural. A closer look at it will see what is used here
You might also notice that I just pointed mongoose to my own mongodb server installed on my computer. For such a mechanism to work correctly, MongoDB must be installed on your computer and work. If it does not work, just open the console window and enter the following command:
![](https://habrastorage.org/webt/yz/fr/o2/yzfro2ns9az9yqno2kc522rdnfa.png)
It will start the MongoDB server on your local machine. Since all this is done locally, you will not be able to see my posts if you run the code from the repository. We have to write new content ourselves. If you need a content stub, I recommend the excellent Fillerama.io generator, slicing text from some of my favorite movies and TV shows.
If you are interested in testing the server yourself, you can start it with the following command:
![](https://habrastorage.org/webt/83/fr/1z/83fr1z4cgcdnjrx9up44nk5enxe.png)
After the server starts up and tells us that it works on port 3333, as well as that it connected to MongoDB, you can open Postman and test our routes there. As for the GET options, you can simply insert the route and click “Send”. In the case of POST, you will have to select “Body” and fill in the fields for the header and main content.
Now that we have configured and launched our server, we can begin to work on the client with which our users will interact. The client will be written in React.js, and this can be done in several different ways.
The first is to simply add all the necessary libraries for the client side (react, react-dom, react-router, etc.) all to the same file
The second and (in my opinion) more optimal approach is to create a separate repository for the server side and a separate one for the client. We can still clone the client part repository into the directory with our project without any problems, we just need to make sure that the client part is listed in our file
![](https://habrastorage.org/webt/o8/sy/h4/o8syh4xj4rxbc5te5wwk_ax_7bc.png)
Adding a folder
How exactly your full-stack application will be designed is entirely up to you. It just seems to me that if you keep separate repositories for the client and server parts, the structure of the application will be a little more accurate.
Now, having understood the organization of the project, let's talk, actually, about the client code. Below is my file
And here is what the screenshot of the main page of our application will look like:
![](https://habrastorage.org/webt/rp/j-/yz/rpj-yzfnehkwotobufkxqxf3zzi.png)
As you can see,
We use Axios to make http calls to the API terminals, and then use React.js to display the data as we please. In this post I will give Index.js code to make it clear how it all works together.
![](https://habrastorage.org/webt/9j/dp/wo/9jdpwo-gh8ifomloyx0cibju1mi.png)
In the above code, a class component is involved that allows us to use state and life cycle methods. This is necessary because Axios calls must be made in the lifecycle method
Let's make sure that search bots read our React.js app normally.
Rounding off, I would like to talk briefly about rendering. If you launch our site and go directly to some blog post, then there may be some problems with the display of content. In this case, browsing the site will be inconvenient not only to users, but also to search robots indexing content. To work around this problem, I recommend using tools like Gatsby js or Next js. These two solutions are different from each other, but both may come in handy, depending on what exactly you need.
Gatsby js is a static site generator. You can write a site on React.js, and then Gatsby will turn it into static files during build, which will make the site super-fast. Gatsby comes with many useful plugins that make the tool almost universal. By the way, my site was made using Gatsby.js! Since static files are created during assembly, the site needs to be rebuilt whenever the original content changes.
Next.js, in turn, is a server component for displaying React.js sites. Many useful features are built into it, in particular, routing, code splitting, designed components, and much more. Server rendering means that the data will be updated automatically, as is done on the server, but before rendering in the browser window, the rendering stage will take place. That is why there should not be any problems with displaying data to the user, and search robots will also do their job without problems.
There are many other solutions of this kind, but I heard the most about these two, and when working on this project I used them. Both are excellently documented, so it’s easy to quickly deal with both and get down to business.
I hope this article has helped you get a little more accurate insight into how the MERN stack works. In it, we just take MongoDB, Express.js and Node.js and create from them a server that already provides API terminals through which our React.js application can access data. So now you understand a lot, it is time to do great things!
Once upon a time, we released a pilot project on the MEAN stack (Mongo, Express, Angular, Node), which generally did not disappoint us, however, we decided not to do additional prints and updates at the time - unlike Manning, which updated this book . Nevertheless, we continue to search in this direction and today we would like to talk with you about the related MERN stack, where React is located on the client, not Angular. The floor is given to Tim Smith .
![](https://habrastorage.org/webt/1d/hf/l7/1dhfl7yw9am620o13r-nz-i4il8.jpeg)
Warning: all code for this article is here .
In this MERN stack guide, we will write a simple blog using React.js, Node.js, Express.js and MongoDB to expand our full-stack arsenal.
What is a stack?
Perhaps the first thing to discuss is the idea of a "stack" as such. There are many different stacks, and all of them are just different paths to achieve the same goal. When creating a full-stack application, we provide for the client part with which the user will interact, and the same client part will mediate the work with the server and the database - making this entire process as simple and manageable as possible.
We can say that the stack is a certain set of technologies used to solve this problem.
Although there are many stacks worth talking about, some of them are more popular than others today. One of these popular stacks is called MEAN, and it consists of:
- M ongoDb
- E xpress.js
- A ngular.js
- N ode.js
Today we will talk about the MERN stack, which is very similar to MEAN except that Angular.js is replaced here with React.js. Thus, we can use MongoDB as a database, Node.js and Express, respectively, for the server and routing, and React.js - to create the client part with which the user will interact.
How is development done with this stack?
Before moving on to all the subtleties, let's take a general look at how all these elements work together. Personally, it took me a while to delve into this, since my background is related to PHP, where the client and server parts are somewhat mixed up.
1. Server part (Node and Express.js) and client part (React.js)
First of all, you need to understand that the server part and client part are separate entities. The client part may be in the same repository with the server, or maybe in a completely different one.
2. API terminals are used for communication
If you are already thinking about how to make friends of the client and server parts, I will answer: this is done through the API. An API (application program interface) is created on the server, where we will get “terminals” through which the application located in the client part can interact with the server.
Let’s explain on fingers: imagine that your left hand is the server side, and your right hand is the client side.
Now fold your hands and twist your fingers as if you were shaking your own hand. That is how template languages work. They allow you to simply display some markup along with the data dumped with the servers - and in them the client and server components overlap to a large extent.
Now open your hands. Spread your fingers as wide as possible and make sure that your left and right hands are touching only with your fingertips. This is how the MERN stack works. The server part provides terminals (fingertips from the left hand) to access the server, to which the client sends calls (through the tips of the fingers of the right hand) and through these points of contact exchanges information with the server (left hand).
I hope it has become a little clearer, and if not, forget all this metaphor, as if I had not mentioned it.
Our server side is from Node.js and Express.js
Although I’m not going to give step-by-step instructions on how to build this stack here (this is a topic for a separate article), I would like to consider various elements of the stack that are usually used or can be used in it. I myself read several manuals that told how to configure the server, but did not explain why these particular libraries are used for this.
After we create the app.js file, you will need to install a number of packages. The following are the most common packages that I have previously used in my projects with Express.js - maybe they will come in handy for you too.
- Express.js is a framework for creating web applications. It has built-in functionality to solve many problems, in particular, to establish routing.
- Mongoose is an object data manager (ODM) that provides interoperability between an express.js application and a MongoDB database.
- BodyParser is a library that allows the express.js application to read the body (i.e., content) of incoming requests.
- DotENV - allows you to use files with the extension .env to work with confidential data.
- Passport.js - provides authentication in our application, and provides several different authentication methods.
- Validator - simple validation of many data types
- bCrypt - encryption of sensitive data, such as passwords
- Nodemon - “hot reboot” for our node-server in case of a change in situation; Thanks to Nodemon, you can not stop or restart the server after making any changes.
Of course, there are many other packages, but in my experience, it is these libraries that are used most often.
So, after sorting out some of the most heavily used packages, let's look at the code. For starters, our server:
![](https://habrastorage.org/webt/xk/g7/f_/xkg7f_3zeltvgqsj-knjstppros.png)
This is a simple API server. As you can see, it is equipped with the basic CRUD (Create-Read-Update-Delete) functionality - nothing supernatural. A closer look at it will see what is used here
res.json()
to provide output data for a specific URL - that is, HTML or another template is not used for output. This is how we build our APIs by opening data access to React.js.You might also notice that I just pointed mongoose to my own mongodb server installed on my computer. For such a mechanism to work correctly, MongoDB must be installed on your computer and work. If it does not work, just open the console window and enter the following command:
![](https://habrastorage.org/webt/yz/fr/o2/yzfro2ns9az9yqno2kc522rdnfa.png)
It will start the MongoDB server on your local machine. Since all this is done locally, you will not be able to see my posts if you run the code from the repository. We have to write new content ourselves. If you need a content stub, I recommend the excellent Fillerama.io generator, slicing text from some of my favorite movies and TV shows.
If you are interested in testing the server yourself, you can start it with the following command:
![](https://habrastorage.org/webt/83/fr/1z/83fr1z4cgcdnjrx9up44nk5enxe.png)
After the server starts up and tells us that it works on port 3333, as well as that it connected to MongoDB, you can open Postman and test our routes there. As for the GET options, you can simply insert the route and click “Send”. In the case of POST, you will have to select “Body” and fill in the fields for the header and main content.
Client side note
Now that we have configured and launched our server, we can begin to work on the client with which our users will interact. The client will be written in React.js, and this can be done in several different ways.
The first is to simply add all the necessary libraries for the client side (react, react-dom, react-router, etc.) all to the same file
package.json
where we recorded the server libraries. In this project, I did just that, but I must say that I do not think this option is optimal. I think that as our project grows, the code base will become more and more complicated, and if you use just this method, then working with it will become more complicated in the future. I preferred this path in the described application precisely because I know for sure: it will not grow and will not change at all. This application is written solely for demonstration purposes.The second and (in my opinion) more optimal approach is to create a separate repository for the server side and a separate one for the client. We can still clone the client part repository into the directory with our project without any problems, we just need to make sure that the client part is listed in our file
.gitignore
. For example, in the file structure for this application there is a directory client
where all the client-side code is located. We could take it to a completely separate repository, and then simply add the following entry to .gitignore
our repository file with the server side: ![](https://habrastorage.org/webt/o8/sy/h4/o8syh4xj4rxbc5te5wwk_ax_7bc.png)
Adding a folder
client
to the file.gitignore
, we guarantee that the system will not perceive this folder as the second repository in the project. In addition, this approach facilitates the work of redesigning or replacing the client part, since the server part is not affected at all. How exactly your full-stack application will be designed is entirely up to you. It just seems to me that if you keep separate repositories for the client and server parts, the structure of the application will be a little more accurate.
We create a client part on React.js
Now, having understood the organization of the project, let's talk, actually, about the client code. Below is my file
app.js
for the application on React.js, and I will not insert code for each component in this post, but just leave a link to the repository and explain what each of the React components does. And here is what the screenshot of the main page of our application will look like:
![](https://habrastorage.org/webt/rp/j-/yz/rpj-yzfnehkwotobufkxqxf3zzi.png)
As you can see,
app.js
absolutely nothing complicated. There is a <Router> that allows you to set routes in React.js that display various components based on their URL. Here are the other components that will be used in our React.js application:- Header - The navigation bar located at the top of the screen
- Index - Lists available blog entries
- New - The form through which the user can create a new post
- Single - Displays a specific blog entry based on its
id
- Edit - The form through which the user can update the blog entry found by
id
We use Axios to make http calls to the API terminals, and then use React.js to display the data as we please. In this post I will give Index.js code to make it clear how it all works together.
![](https://habrastorage.org/webt/9j/dp/wo/9jdpwo-gh8ifomloyx0cibju1mi.png)
In the above code, a class component is involved that allows us to use state and life cycle methods. This is necessary because Axios calls must be made in the lifecycle method
componentDidMount()
. It should be noted that I was getting a CORS error when trying to make calls to my local API. To solve this problem, I added several headers to the server.js file in my Express server - and it worked. This code is noted in the comments on the server.js file. Let's make sure that search bots read our React.js app normally.
Rounding off, I would like to talk briefly about rendering. If you launch our site and go directly to some blog post, then there may be some problems with the display of content. In this case, browsing the site will be inconvenient not only to users, but also to search robots indexing content. To work around this problem, I recommend using tools like Gatsby js or Next js. These two solutions are different from each other, but both may come in handy, depending on what exactly you need.
Gatsby js is a static site generator. You can write a site on React.js, and then Gatsby will turn it into static files during build, which will make the site super-fast. Gatsby comes with many useful plugins that make the tool almost universal. By the way, my site was made using Gatsby.js! Since static files are created during assembly, the site needs to be rebuilt whenever the original content changes.
Next.js, in turn, is a server component for displaying React.js sites. Many useful features are built into it, in particular, routing, code splitting, designed components, and much more. Server rendering means that the data will be updated automatically, as is done on the server, but before rendering in the browser window, the rendering stage will take place. That is why there should not be any problems with displaying data to the user, and search robots will also do their job without problems.
There are many other solutions of this kind, but I heard the most about these two, and when working on this project I used them. Both are excellently documented, so it’s easy to quickly deal with both and get down to business.
Final thoughts on the MERN stack
I hope this article has helped you get a little more accurate insight into how the MERN stack works. In it, we just take MongoDB, Express.js and Node.js and create from them a server that already provides API terminals through which our React.js application can access data. So now you understand a lot, it is time to do great things!
Only registered users can participate in the survey. Please come in.