As a software developer and tutor, creating a full-stack portfolio is an excellent way to showcase your skills, projects, and expertise. In this article, I’ll walk you through how to build a modern, responsive portfolio using the MERN stack (MongoDB, Express.js, React.js, and Node.js). By the end of this guide, you’ll have a fully functional portfolio that you can deploy and share with the world.


Why the MERN Stack?

The MERN stack is a popular choice for full-stack development because:

  1. JavaScript Everywhere: You use JavaScript for both frontend and backend development, making it easier to maintain.
  2. Scalability: MongoDB and Node.js are highly scalable, making them suitable for projects of any size.
  3. Community Support: With a large and active community, you’ll find plenty of resources and tutorials to help you along the way.

Portfolio Features

Our portfolio will include the following features:

  1. Homepage: A brief introduction and overview of your skills.
  2. Projects Section: A showcase of your work with descriptions and links.
  3. Blog/Tutorials Section: A space to share your knowledge as a tutor.
  4. Contact Form: A way for visitors to reach out to you.

Step 1: Setting Up the Project

1.1 Create the Project Structure

Start by creating a project folder and setting up the backend and frontend:

mkdir dhanian-portfolio
cd dhanian-portfolio

# Backend setup
mkdir backend
cd backend
npm init -y
npm install express mongoose cors dotenv

# Frontend setup
cd ..
npx create-react-app frontend
cd frontend
npm install axios react-router-dom
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

1.2 Backend Setup

The backend will handle the contact form submissions and serve as the API for your portfolio.

1.2.1 Create the Backend Structure

backend/
├── models/
├── routes/
├── controllers/
├── .env
├── server.js

1.2.2 Set Up the Server

In backend/server.js, add the following code:

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

dotenv.config();
const app = express();
const PORT = process.env.PORT || 5000;

// Middleware
app.use(cors());
app.use(express.json());

// MongoDB Connection
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('MongoDB Connected'))
  .catch(err => console.log(err));

// Routes
app.get('/', (req, res) => {
  res.send('Backend is running');
});

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

1.2.3 Add a Contact Model

Create a Contact model in backend/models/Contact.js:

const mongoose = require('mongoose');

const ContactSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
  message: { type: String, required: true },
});

module.exports = mongoose.model('Contact', ContactSchema);

1.2.4 Add a Contact Route

Create a route for the contact form in backend/routes/contact.js:

const express = require('express');
const router = express.Router();
const Contact = require('../models/Contact');

router.post('/', async (req, res) => {
  const { name, email, message } = req.body;
  try {
    const newContact = new Contact({ name, email, message });
    await newContact.save();
    res.status(201).json({ message: 'Message sent successfully' });
  } catch (err) {
    res.status(500).json({ error: 'Server error' });
  }
});

module.exports = router;

1.2.5 Update the Server to Use the Contact Route

In backend/server.js, add:

const contactRoutes = require('./routes/contact');
app.use('/api/contact', contactRoutes);

1.3 Frontend Setup

The frontend will be built using React.js and styled with Tailwind CSS.

1.3.1 Configure Tailwind CSS

Update frontend/tailwind.config.js:

module.exports = {
  content: ['./src/**/*.{js,jsx,ts,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
};

Add Tailwind to frontend/src/index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

1.3.2 Create the Homepage

In frontend/src/components/Home.js, add:

import React from 'react';

const Home = () => {
  return (
    <div className="min-h-screen bg-gray-100 flex items-center justify-center">
      <h1 className="text-4xl font-bold text-blue-600">Welcome to Dhanian's Portfolio
); }; export default Home;
Enter fullscreen mode Exit fullscreen mode