Github Repo: https://github.com/Justinkarso/react-express-starter
Contents
- Introduction
- Installing dependencies
- Scripts
- Setting up react
- General configuration
- Express server
- Get up and running
- Conclusion
Introduction
Building web apps gives developers the opportunity to reach a wider audience. The combination of Express and React gives developers a powerful tool to create frontends and easily communicate with backends through their own APIs.
React
React is a free and open-source JavaScript library for building user interfaces based on components. It is maintained by Meta and has a large community of developers / companies that improve the overall experience with react. React can be used as a base in the development of single-page or mobile applications, but since the release of some awesome frameworks built on top of react like [NextJS, Remix, Gatsby, etc..] we can now utilize react to create all sorts of apps using SSR, SSG and so forth.
Express
Express is a minimalist, lightweight framework for making web apps in NodeJS. It is designed for building web applications and APIs. It has been called the de facto standard server framework for NodeJS. One of the major benefits of Express is that developers can use their prior knowledge of JavaScript, without needing to learn a new language.
Prerequisites
To follow along it would be helpful to have the following installed.
- Node.js installed.
- A text editor, like VS Code.
- A web browser, like Chrome or Brave.
You should also know the basics of
- Javascript / React
- NodeJS / Express
This guide will not go into detail about these subjects.
Folder structure
Let us create our project. you can name it anything you'd like. I'll name it react-express. Go to any folder where you would like the app to be located at and run the following.
mkdir react-express
cd react-express
Great! Now let's immediately create the basic folder structure. In this guide I'll use commands to create folders and files. Afterwards there will be a screenshot.
// dist folder
mkdir dist
cd dist
touch index.html
cd ..
// src folder
mkdir src
cd src
mkdir pages
mkdir styles
touch index.js
cd pages
touch Home.js
cd ..
cd styles
touch global.scss
cd ..
cd ..
// root files
touch .swcrc
touch app.js
touch webpack.config.js
Our folder structure should now look like this.
Alright, let's not lie about it. You probably don't have a favicon. This is not required but if you want the same one, here you go: https://favicon.io/emoji-favicons/rhinoceros
Installing dependencies
Let's first create our package.json using the init command
npm init -y
Now we are going to install some packages using the following commands:
dependencies
Short ✋
npm i react react-dom react-router-dom express cors concurrently
or
npm install react react-dom react-router-dom
concurrently lets us run multiple commands at the same time
npm install express cors concurrently
dev dependencies
Let's also include nodemon for a better development experience.
We'll also use webpack and include some loaders like sass to use scss in our project and SWC to compile our javascript with the SWC compiler created in rust.
Short ✋
npm i --save-dev @swc/cli @swc/core swc-loader nodemon webpack webpack-cli css-loader sass sass-loader style-loader
or
Nodemon reruns the express server on every file save.
npm install --save-dev nodemon sass
Webpack provides a solid bundeling process to build for production as well as making your development experience more fun.
npm install --save-dev webpack webpack-cli
SWC is a Rust based tool that we can use to compile our javascript. There are many more uses for SWC, but we'll only use it here for compiling.
npm install --save-dev @swc/cli @swc/core swc-loader
Add some loaders for webpack to understand our stylesheets
npm install --save-dev css-loader sass-loader style-loader
Scripts
Let's add our scripts inside our package.json.
"scripts": {
"build": "NODE_ENV=production webpack",
"build-dev": "webpack --watch",
"server": "nodemon app.js",
"dev": "concurrently \"npm run server\" \"npm run build-dev\""
},
Setting up React
Now we are ready to populate our files. let's get started by filling in the index.html inside the dist folder.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<title>React & Express</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
That seems pretty simple doesn't it! We are probably all familiar with this structure while working with react.
Alright so before we are jumping into the express server or configurations, let us populate the src folder first.
src > pages > Home.js
import React, { useEffect, useState } from "react";
export default function Home() {
const [users, setUsers] = useState([]);
useEffect(() => {
const getData = async () => {
try {
let response = await fetch("https://jsonplaceholder.typicode.com/users");
let data = await response.json();
setUsers(data);
} catch (err) {
console.log(err);
}
};
getData();
}, []);
return (
<div className="demo">
<div className="wrapper">
<h1>
A <span>demo</span> showing off <span>React</span> using{" "}
<em>
<span>Express</span> | <span>Webpack</span> | <span>SWC</span>
</em>
</h1>
<h2>
Some Async Data <small>No more extra babel plugins!</small>
</h2>
<ul>{users.length > 0 && users.map((user, index) => <li key={index}>{user.name}</li>)}</ul>
</div>
</div>
);
}
Wow thats a lot! We are simply creating a Home component that will return some text and fetch some data from jsonplaceholder and displaying it inside a unordered list. bear with me 🐻, we will apply some styling next (even though you can't see it yet..)
src > styles > global.scss
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-size: 14px;
color: #fff;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.demo {
background-color: #121212;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 2rem;
.wrapper {
max-width: 1000px;
h1,
span {
font-size: 4rem;
}
h2 {
margin: 2rem 0;
small {
font-size: 0.75rem;
opacity: 0.5;
}
}
em {
font-size: 2rem;
color: #858585;
span {
&:first-child {
color: #ffeb39;
}
&:nth-child(2) {
color: #39ffbd;
}
&:last-child {
color: #d83bd2;
}
}
}
span {
&:first-child {
color: #f44250;
}
&:nth-child(2) {
color: #3992ff;
}
}
ul {
list-style: none;
margin-left: 2rem;
li {
font-size: 1rem;
margin-bottom: 1rem;
}
}
}
}
Nice, scss is awesome!
To make your life easier and expand on this project later on, we are going to include react router. Let's do this inside our index.js
src > index.js
import React from "react";
import ReactDOM from "react-dom";
import Home from "./pages/Home";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import "./styles/global.scss";
ReactDOM.render(
<Router>
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</Router>,
document.getElementById("root")
);
As you can see, we're also importing our home component here. We're using the latest version of react router V6, which is a little different from its predecessor.
Phew, that's it for our src folder 😅
General configuration
We now want to add some code to our config files. Don't worry, after this we will create our express server and get things running!
First, navigate to our .swcrc file and add the following
{
"test": ".*.js$",
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": true
}
}
}
Awesome this lets SWC compile our code to proper javascript that is supported by all browsers!
SWC is 20x faster than Babel on a single thread and 70x faster on four cores.
webpack.config.js
now let us populate our webpack.config.js by adding some configuration (duh.. unnecessary sentence).
const path = require("path");
const mode = process.env.NODE_ENV === "production" ? "production" : "development";
module.exports = {
mode: mode,
entry: path.resolve(__dirname, "src"),
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "swc-loader",
},
},
{
test: /\.s[ac]ss$/i,
use: ["style-loader", "css-loader", "sass-loader"],
},
],
},
};
Great, so here we automatically check whether we're in production or development and build instances for those. We also include our SWC and style loaders in the webpack module rules.
Express Server
Cool so we can now finally create our express server! let's open our app.js file and add the following
const express = require("express");
const path = require("path");
const app = express();
const cors = require("cors");
app.use(cors());
app.use(express.json());
app.use(express.static("dist"));
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname + "/dist/index.html"));
});
app.listen(3000, () => {
console.log("App running on http://localhost:3000");
});
Hey that was pretty easy right? We are just telling express to serve our index.html which will render our react app!
Get up and running
Alright so now that we are done creating our code, hurry up and get your app started!
To spin up our development server we'll use:
npm run dev
Yes, it needs to be updated after each change. But there are solutions for that like webpack-dev-server. I didn't include it in this project for personal reasons. But of course you're welcome to add it to your project!
🎉 🎉 Hey check this out! 🎉 🎉
Look at our beautiful webpage.
To build for production we can simply do
npm run build
Webpack manages the environment for you! You can easily deploy your Node app to any platform like the Digital Ocean App Platform
When you run npm run server
our production web app will be deployed on the assigned port, in this case 3000
Conclusion
Alright, so we've built our application using React and Express. Where can we use that?
Well, React has its uses. You can easily create dashboards and advanced web apps that don't rely on good SEO or other marketing strategies. For that approach, you should probably move to NextJS or Gatsby. You can also dive into hydration and server components for react to help with these subjects.
But creating a React app is great. Especially now that our Express server is coming along, we can build full-stack solutions from scratch! There are so many use cases we can handle with this approach.
Please let me know if you've any pointers to improve this post or correct me if I have said something wrong. I'm always open to feedback.
Thank you for reading and Happy Coding 🥷💻
Top comments (1)
can some one update this article .render () functionis depricated