Setting up a Full Stack React & Node.js Project: A Comprehensive Cheat Sheet

Ori Baram
8 min readMar 19, 2023

--

Embarking on a new full stack React & Node.js project can be both exciting and daunting. To ensure a smooth and efficient setup process, I have compiled a step-by-step cheat sheet that will guide you from creating your project folder to fine-tuning your frontend and back-end configurations.

In this article, you will learn how to create a project folder, set up your server for development with the help of essential dependencies such as concurrently, and initialize a Git repository. We will also cover setting up your frontend using Create React App or Vite, configuring a proxy for seamless communication between your frontend and back-end, and organizing your files using best practices. Furthermore, it is important to note that the appendices at the end of this article contain useful and crucial information. Please be sure to review them carefully.

By following the instructions in this cheat sheet, you will be able to dive into your full stack project with confidence, laying a strong foundation for your application development journey. So, let us get started and happy coding!

Setting Up the Server

  1. Create a folder for your project using lowercase letters and hyphen-separated words.

Naming conventions can vary depending on personal preference and team standards. However, there are some general best practices that you can follow to ensure your project’s folder names are clear and consistent. Here
are a few suggestions:

1. Use lowercase letters — it’s a common practice to use only lowercase letters when naming folders in web development. This is because Unix-based systems are case-sensitive, so using lowercase letters ensures that your files and directories will be accessible across different platforms. See also the appendix at the end of this document.

2. Use hyphens or underscores — when you need to separate words in your folder name, it’s a good idea to use either hyphens (-) or underscores (_). Both are commonly used, but hyphens are generally preferred since they are more readable and easier to type.

3. Use descriptive names — your folder name should be descriptive and concise, so anyone who reads it can quickly understand what it contains. Avoid using abbreviations or acronyms that may not be clear to everyone.

Based on these best practices, a good naming convention for a project folder could be something like ‘my-project’ or ‘my_app’. Again, the important thing is to choose a convention that is clear and consistent for you and your team.

2. Open the folder in VS Code.

3. Create a .gitignore file with the following content:

# Dependencies
node_modules

# Build/Production
/client/build

# Environment variables
*.env*
!.env.example

# Logs
/logs
*.log

# Editor specific
.vscode
.idea
*.suo
*.ntvs*
*.njsproj
*.sln

# Temporary files
*.sw?
*.cache
.DS_Store

# Generated / Auto-generated files
/dist
/dist-ssr
.eslintcache

# Configuration
.prettierrc

4. In the terminal, run npm init. Set the description, entry point to server.js, author to your name, and license to MIT.

Both licenses, ISC & MIT, allow users to use, copy, modify, and distribute the software, including for commercial purposes, without any requirement to share their changes.
The MIT license includes a disclaimer of liability, while the ISC license does not.

5. Install concurrently as a development dependency, by running npm i -D concurrently.

6. Install express and dotenv by running npm i express dotenv.

7. Create a config folder and a config.env file inside it.

8. Add the following content to config.env:

NODE_ENV=development
PORT=5000

9. To use ES modules instead of CommonJS, add "type": "module", to your package.json file after "main": "server.js",.

10. Create a server.js file with the following content (for ES modules):

import express from 'express';
import dotenv from 'dotenv';

dotenv.config({ path: './config/config.env' });

const app = express();

app.get('/', (req, res) => res.send('Server running'));

const PORT = process.env.PORT || 5000;

app.listen(PORT, console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`));

If you are using Common JS Modules, use this:

const express = require('express');
const dotenv = require('dotenv');

dotenv.config({ path: './config/config.env' });

const app = express();

app.get('/', (req, res) => res.send('Server running'));

const PORT = process.env.PORT || 5001;

app.listen(PORT, console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`));

11. Update the scripts section in package.json (remove the test script):

If you are intending to use CRA (create-react-app), use this:

"start": "node server.js",
"server": "node --watch server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""

If you are intending to use Vite, use this:

"start": "node server.js",
"server": "node --watch server.js",
"client": "npm run dev --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""

12. In the terminal, run npm run server and verify that you don't have any errors.

14. Open http://localhost:5000 in your browser to check if the server is running correctly and verify you see there “Server running”.

Verifying the server is running in the browser

Setting Up the Frontend

  1. Run npx create-react-app client or run yarn create vite and name your project “client”, to create a new Vite-based React app in the "client" folder.

If you didn’t install yarn on your machine before, in the terminal, run this command:

For macOS or Linux, you can use the following command:

npm install -g yarn

For Windows, you can use the following command:

npm install --global yarn

3. If you created a Vite-based React app, change to the client folder by using cd client in the terminal, and run yarn in order to install the node modules.

4. To install additional packages for your React app, don’t forget to first change to the client directory using cd client.

5. Delete the .gitignore and README.md files in the client folder.

6. Remove the git repository from the client folder. Change to the client folder using cd client and run -rf .git on macOS or Linux.
On Windows, Open File Explorer and go to the client folder. Click the “View” tab on the top menu. Check the “Hidden items” checkbox in the “Show” section.
Once you’ve enabled the visibility of hidden items, delete the .git folder in the client folder.
Back in the terminal, return to the root directory with cd ...

Enabling the visibility of hidden items on Windows 11

7. Add a proxy to the package.json file in the client folder for easier API requests, so if you type an address in this way: ('/api/users'), it will be directed to http://localhost:5000/api/users:

In a CRA (create-react-app) based project, add this line:

"proxy": "http://localhost:5000",

In a Vite based project, add to the vite.config.js file in the client folder:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
"/api/": "http://localhost:5000/",
},
},
});

8. Change back to root folder using cd .. and run npm run dev to start both the back-end and frontend servers simultaneously.

Now you’re all set to start working on your Full Stack application!

Summary

In this cheat sheet, we outline the steps to set up a full stack project, ensuring a smooth and efficient setup process. The article covers creating a project folder, setting up the server using essential dependencies, initializing a Git repository, configuring the frontend with Create React App or Vite, setting up a proxy for seamless frontend and back-end communication, and organizing files using best practices.

By following these instructions, you’ll be well-prepared to dive into your full stack project with confidence, laying a strong foundation for your application development journey.

Happy coding!

Appendix I: A GitHub repository

Here’s a link to a GitHub repository containing a boilerplate code for a full stack application based on this article using Vite. In this link, you will find a GitHub repository for a full stack application based on this article using CRA.

Appendix II: Testing Your Application

To ensure that your full Stack application is functioning correctly, we will add a sample data array to the server.js file and create a GET endpoint for retrieving this data. We will also update the client-side App.js file to fetch and display the data.

  1. Add the people array to the server.js file and create a GET endpoint for retrieving this array:
import express from 'express';
import dotenv from 'dotenv';

dotenv.config({ path: './config/config.env' });

const app = express();

app.get('/', (req, res) => res.send('Server running'));

const people = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Smith' },
{ id: 3, name: 'Michael Brown' },
{ id: 4, name: 'Emily Johnson' },
{ id: 5, name: 'David Jones' },
{ id: 6, name: 'Sarah Davis' },
{ id: 7, name: 'Kevin Wilson' },
{ id: 8, name: 'Laura Taylor' },
{ id: 9, name: 'Richard Williams' },
{ id: 10, name: 'Emma White' },
];

app.get('/api/people', (req, res) => {
res.json(people);
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`));

2. Update the App.js file in the client folder to fetch and display the data:

import { useState, useEffect } from 'react'
import './App.css'

function App() {
const [people, setPeople] = useState([]);

useEffect(() => {
const fetchPeople = async () => {
try {
const response = await fetch('/api/people');
const data = await response.json();
setPeople(data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchPeople();
}, []);

return (
<div className="App">
<h1>List of People</h1>
<ul>
{people.map((person) => (
<li key={person.id}>{person.name}</li>
))}
</ul>
</div>
);
}

export default App;

3. Verify everything is working.

  • Run npm run dev in the terminal to start both the back-end and frontend servers concurrently.
  • Open your web browser and navigate to http://localhost:3000 (or http://localhost:5173 if you are using Vite) to view the List of People.
  • Check that the list of people from the people array in the server.js file is displayed correctly.

By following these steps, you can verify that your full stack application is functioning properly and can proceed with further development.

Appendix III: __dirname and __filename are not defined In ES modules

In ES modules, the __dirname and __filename variables are not defined. These variables are commonly used in CommonJS modules to get the directory name and file name of the current module, and might be needed in your Node.js project later on.

While it may be inconvenient to not have access to __dirname and __filename in ES modules, it is not a major limitation. There are alternative ways to get the directory and file name of the current module in ES modules, such as using the URL constructor to parse the import.meta.url property.

The way to get around this in ES modules is by using the fileURLToPath method imported from the url module, and passing import.meta.url as an argument to get the __filename, and to get the __dirname to use the path.dirname method, like in this example:

import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

Appendix IV: File and Directory Naming Best Practices

Unix-based systems, such as Linux and macOS, are case-sensitive. This means that if you create two files with the names “file.txt” and “File.txt” in the same directory, the system will treat them as two distinct files.

The implication of this is that you need to be careful when naming your files and directories. If you use inconsistent capitalization, you may end up with multiple files or directories with similar names, which can cause confusion and errors when working with them. Therefore, it’s a best practice to use consistent capitalization and avoid naming conflicts to ensure that your files and directories are easily accessible and manageable across different platforms.

--

--

Ori Baram

A programmer & instructor in JavaScript, HTML, CSS, dedicated to learning, teaching, evolving, and sharing a passion for coding with the world.