Stock Market Portfolio App using MERN Stack (original) (raw)
Last Updated : 30 Mar, 2026
The Stock Market Portfolio project is a web application that helps users manage and track their investments efficiently. Built using the MERN stack, it offers a scalable and responsive solution for modern financial management.
Prerequisites
Ensure you have the required technologies and tools installed to build and run the MERN-based application.
Create Stock Market Portfolio App
Follow this approach to build a dynamic stock portfolio management application.
- The database stores a list of stock data fetched by the server.
- Users can also manually add stock data via API requests.
- The frontend includes two routes: one for all stocks and another for watchlisted stocks.
- Users can add favorite stocks to a watchlist.
- Stock prices are displayed in green if increasing and red if decreasing.
Steps to Create the Project
Follow these steps to build a full-stack stock market portfolio application using the MERN stack.
**Step 1: Create a folder for the project backend and initialized the Express Application.
mkdir stock-market-portfolio cd stock-market-portfolio npm init -y
**Step 2: Install Express and other required packages:
npm install express mongoose body-parser cors
**Folder Structure:

**Dependencies (Backend):
"dependencies": { "body-parser": "^1.20.2", "cors": "^2.8.5", "express": "^4.18.2", "mongoose": "^8.0.4" }
**Example: Create a file named server.js and add the following code.
server.js ``
const express = require("express"); const mongoose = require("mongoose"); const cors = require("cors"); const bodyParser = require("body-parser");
const app = express(); const PORT = process.env.PORT || 5000;
app.use(cors()); app.use(bodyParser.json());
const uri = "Your Mongo URI";
mongoose .connect(uri) .then(() => console.log("MongoDB connected")) .catch((err) => { console.error("MongoDB connection error:", err); process.exit(1); });
const stockSchema = new mongoose.Schema({ company: String, description: String, initial_price: Number, price_2002: Number, price_2007: Number, symbol: String, });
const Stock = mongoose.model("Stock", stockSchema, "stocks");
const watchlistSchema = new mongoose.Schema({ stockId: { type: mongoose.Schema.Types.ObjectId, ref: "Stock" }, addedAt: { type: Date, default: Date.now }, });
const Watchlist = mongoose.model("Watchlist", watchlistSchema);
app.get("/api/stocks", async (req, res) => { try { const stocks = await Stock.find(); res.json(stocks); } catch (error) { res.status(500).json({ error: "Internal Server Error" }); } });
app.get("/api/watchlist", async (req, res) => { try { const list = await Watchlist.find().populate("stockId"); res.json(list); } catch (error) { res.status(500).json({ error: "Internal Server Error" }); } });
app.post("/api/watchlist", async (req, res) => { try { const { stockId } = req.body; const exists = await Watchlist.findOne({ stockId }); if (exists) return res.json({ message: "Already in watchlist" }); const item = new Watchlist({ stockId }); await item.save(); res.json({ message: "Added to watchlist" }); } catch (error) { res.status(500).json({ error: "Internal Server Error" }); } });
app.listen(PORT, () => {
console.log(Server running on port ${PORT});
});
``
**Step 3: Open the MongoDB atlas or compass and insert the following JSON file in the "stocks" collection.
"https://gist.github.com/stevekinney/f96d5800852e91282f46#file-stocks-json".
**Step 4: Create the Frontend (React.js) by running the below command.
npx create-react-app stock-market-frontend cd stock-market-frontend
**Step 5: Install the required dependencies.
npm install axios
**Dependencies (Frontend):
"dependencies": { "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@mui/material": "^5.15.4", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.6.5", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.21.2", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }
**Example: Write the given code in the respective files.
App.css `
/* src/App.css / body { font-family: 'Arial', sans-serif; background-color: #d9d7ca; margin: 0; padding: 0; } .App { text-align: center; padding: 20px; } h1 { color: #1f454d; } h2 { color: #3c8d93; margin-top: 30px; } ul { list-style-type: none; padding: 0; } li { background-color: #3c8d93; color: #d9d7ca; padding: 10px; margin: 10px 0; border-radius: 5px; display: flex; justify-content: space-between; align-items: center; } button { background-color: #1f454d; color: #d9d7ca; border: none; padding: 8px; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } button:hover { background-color: #3c8d93; } / Navigation bar styles */ nav { background-color: #1f454d; padding: 15px 0; } nav a { color: #d9d7ca; text-decoration: none; margin: 0 20px; font-size: 18px; transition: color 0.3s ease; } nav a:hover { color: #3c8d93; }
App.js
// src/App.js import React, { useState, useEffect } from "react"; import { BrowserRouter as Router, Routes, Route, NavLink, Navigate, } from "react-router-dom"; import "./App.css";
function computeColor(stock) { if (!stock) return "black"; const current = stock.initial_price; const compare = stock.price_2007; if (typeof current === "number" && typeof compare === "number") { return current >= compare ? "green" : "red"; } return "black"; }
const Stocks = ({ addToWatchlist }) => { const [stocks, setStocks] = useState([]);
useEffect(() => { fetch("http://localhost:5000/api/stocks") .then((res) => res.json()) .then((data) => setStocks(data)) .catch((error) => console.error("Error fetching stocks:", error)); }, []);
return ( <div className="App" style={{ padding: 16 }}>
Stock Market MERN App
Stocks
-
{stocks.map((stock) => (
<li key={stock._id || stock.symbol} style={{ marginBottom: 8 }}>
{stock.company} ({stock.symbol}) -
<span style={{ color: computeColor(stock), marginLeft: 8 }}>
${stock.initial_price ?? "N/A"}
<button
style={{ marginLeft: 12 }}
onClick={() => addToWatchlist(stock)}
>
Add to My Watchlist
))}
const Watchlist = ({ watchlist }) => { return ( <div className="App" style={{ padding: 16 }}>
Stock Market MERN App
My Watchlist
{watchlist.length === 0 ? (No items in watchlist.
) : (-
{watchlist.map((item) => {
const stock = item.stockId || item;
return (
<li key={item._id} style={{ marginBottom: 8 }}>
{stock.company} ({stock.symbol}) -
<span style={{ marginLeft: 8 }}>
${stock.initial_price ?? "N/A"}
);
})}
function App() { const [watchlist, setWatchlist] = useState([]);
const loadWatchlist = () => { fetch("http://localhost:5000/api/watchlist") .then((res) => res.json()) .then((data) => setWatchlist(data)) .catch((err) => console.error("Error loading watchlist:", err)); };
useEffect(() => { loadWatchlist(); }, []);
const addToWatchlist = (stock) => { fetch("http://localhost:5000/api/watchlist", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ stockId: stock._id }), }) .then((res) => res.json()) .then((data) => { alert(data.message || "Action completed"); loadWatchlist(); }) .catch((error) => { console.error("Error adding to watchlist:", error); alert("Failed to add to watchlist"); }); };
return ( <nav style={{ padding: 12 }}> <NavLink to="/stocks" style={{ marginRight: 12 }}> Stocks Watchlist
<Routes>
<Route path="/" element={<Navigate to="/stocks" replace />} />
<Route path="/stocks" element={<Stocks addToWatchlist={addToWatchlist} />} />
<Route path="/watchlist" element={<Watchlist watchlist={watchlist} />} />
</Routes>
</Router>); }
export default App;
`
**Step 6: Start backend server
cd stock-market-portfolio npm start
**Step 7: Start frontend
cd stock-market-frontend npm start
**Output: