Kiran Chauhan

Cogito, ergo sum // I think, therefore I am.

Search This Blog

Thursday, February 19, 2026

Let's Build Peter Pt. 4

Since the backend is working, we can now start using the middleware packages we installed earlier.

Let's begin with morgan.

import express from "express";
import morgan from "morgan";

const app = express();

app.use(morgan("tiny"));

app.get("/ping", (req, res) => {
    return res.json({ data: "pong" });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});

Now that logging is in place, the next middleware we will configure is cors. We will whitelist the React application's URL: http://localhost:5173.

import express from "express";
import morgan from "morgan";
import cors from "cors";

const app = express();

app.use(morgan("tiny"));
app.use(
    cors({
        origin: "http://localhost:5173",
    }),
);

app.get("/ping", (req, res) => {
    return res.json({ data: "pong" });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});

Finally, let's add helmet and compression.

import express from "express";
import morgan from "morgan";
import cors from "cors";
import helmet from "helmet";
import compression from "compression";

const app = express();

app.use(morgan("tiny"));
app.use(
    cors({
        origin: "http://localhost:5173",
    }),
);
app.use(helmet());
app.use(compression());

app.get("/ping", (req, res) => {
    return res.json({ data: "pong" });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});

Perfect! Now visit http://localhost:3000/ping. It should return the same output as before. However, this time you will also see the request being logged in the terminal.

Yes — it’s working for me 👍

Now is a good time to open Insomnia (or any other API client). Send a request to the same endpoint and confirm that you receive: { "data": "pong" }

Cleaning Up the Frontend

On the frontend side, let’s clean up the scaffolded application:

  • Remove the public folder
  • Remove the src/assets folder
  • Remove the App.css file

After cleaning up, your folder structure should look minimal and clean.

Now open the App.jsx file and replace its content with the following:

const App = () => {
    return <h1>hello, world</h1>;
};

export default App;

Run the React application using:

npm run dev

Within a few seconds, the application should be available at: http://localhost:5173. Visit the URL and confirm that you see: hello, world.

Both applications are now running — yay! 🎉

at

Monday, February 16, 2026

Let's Build Peter Pt. 3

Inside the backend folder, let’s create an app.js file and write some base code to test our setup.

touch app.js

We will use the modern import...from syntax. We’ll update the necessary configuration in the package.json file shortly.

import express from "express";

const app = express();

Now, let’s define a /ping route that returns "pong" as a JSON response.

import express from "express";

const app = express();

app.get("/ping", (req, res) => {
    return res.json({ data: "pong" });
});

💡 Tip: Always use return when you want to stop the execution of a function after sending a response.

We will use port 3000 because the React application created using Vite runs on port 5173 by default.

import express from "express";

const app = express();

app.get("/ping", (req, res) => {
    return res.json({ data: "pong" });
});

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

Finally, let’s start the server and print the URL for future reference and debugging.

import express from "express";

const app = express();

app.get("/ping", (req, res) => {
    return res.json({ data: "pong" });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});

We need to make the following changes in the package.json file:

  • Change "type" from "commonjs" to "module" to support the import...from syntax.
  • Change "main" from index.js to app.js.
{
    "name": "backend",
    "version": "1.0.0",
    "description": "",
    "main": "app.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "type": "module",
    "dependencies": {
        "compression": "1.8.1",
        "cors": "2.8.6",
        "express": "5.2.1",
        "helmet": "8.1.0",
        "morgan": "1.10.1",
        "postgres": "3.4.8"
    }
}

I almost forgot — we also need nodemon to automatically restart the server when files change during development.

💡 Tip: This is an example of a non-perfect setup. You will always miss something — and that’s completely fine.

Install nodemon as a development dependency:

npm i -E -D nodemon

Now, let’s add two scripts to package.json:

  • dev → runs nodemon app.js
  • start → runs node app.js
{
    "name": "backend",
    "version": "1.0.0",
    "description": "",
    "main": "app.js",
    "scripts": {
        "dev": "nodemon app.js",
        "start": "node app.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "type": "module",
    "dependencies": {
        "compression": "1.8.1",
        "cors": "2.8.6",
        "express": "5.2.1",
        "helmet": "8.1.0",
        "morgan": "1.10.1",
        "postgres": "3.4.8"
    },
    "devDependencies": {
        "nodemon": "3.1.11"
    }
}

With these changes, we are ready to run the application. Both scripts will start the server, but during development, we usually use:

npm run dev

Now open your browser and visit http://localhost:3000/ping. You should see { "data": "pong" } And yup — it’s working! 🎉 If everything works on your side, you’re ready to head over to the next article.

at

Sunday, February 15, 2026

Let's Build Peter Pt. 2

Let’s create a folder named peter and navigate into it.

mkdir peter
cd peter

Now, create two folders — frontend and backend. As the names suggest, the frontend folder will contain the React code, and the backend folder will contain the Node.js code.

mkdir frontend backend

Inside the frontend folder, let’s create a React application using Vite with the JavaScript template.

cd frontend
npm create vite@latest . -- --template react

While the process is running, open a new terminal tab (or window), navigate to the backend folder, and perform some initial setup such as creating a package.json file and installing the required dependencies.

cd ../backend

Let’s create a package.json file:

npm init -y

Now, install the express and postgres packages:

npm i -E express postgres

Next, install a few middleware packages:

  • morgan for logging
  • helmet for security
  • cors to allow API calls from the React application
  • compression to compress responses
npm i -E morgan helmet cors compression

Great! The initial setup is complete, and we’re ready to get started.

at

Saturday, February 14, 2026

Let's Build Peter Pt. 1

Welcome!

In this article series, we are going to build a project management system (or an issue tracking system) called Peter. The tech stack we will use includes Express for the back end and React for the front end. Along the way, we will also use GraphQL. The database will be PostgreSQL.

Please install the following software before we proceed:

  1. Node v24+
  2. npm v11+
  3. PostgreSQL 17+
  4. Insomnia (or any API client)
  5. VS Code (or any text-editor)
  6.  Terminal (I guess you already have one!)

Take your time to install this software. Once you're ready, head over to the next article.

at