How To Install MERN Stack on Manjaro
The MERN stack has become one of the most popular technology stacks for building modern web applications. Manjaro Linux, with its rolling release model and access to the Arch User Repository, provides an excellent development environment for JavaScript developers. This comprehensive guide walks through the complete installation process of MongoDB, Express.js, React.js, and Node.js on Manjaro Linux.
Whether you’re a seasoned developer or just starting your full-stack journey, setting up a proper MERN development environment is crucial for productivity. Manjaro’s bleeding-edge packages and robust package management system make it an ideal choice for web development workflows. By the end of this tutorial, you’ll have a fully functional MERN stack ready for building scalable, high-performance web applications.
Understanding the MERN Stack Components
MERN stack represents a powerful combination of four JavaScript-based technologies that work seamlessly together. Each component serves a specific purpose in the development ecosystem.
MongoDB is a NoSQL document-oriented database that stores data in flexible JSON-like documents. Unlike traditional relational databases, MongoDB offers schema flexibility, making it perfect for rapid application development where data structures may evolve over time.
Express.js acts as the backend web framework running on Node.js. It simplifies server creation, routing, and middleware implementation. Express handles HTTP requests, manages API endpoints, and integrates seamlessly with MongoDB through libraries like Mongoose.
React.js powers the frontend interface with its component-based architecture. Developed by Facebook, React enables developers to build dynamic, responsive user interfaces with reusable components and efficient DOM manipulation.
Node.js serves as the JavaScript runtime environment built on Chrome’s V8 engine. It allows JavaScript execution outside the browser, enabling server-side scripting and unifying the development language across the entire stack.
The unified JavaScript environment across frontend and backend development offers significant advantages. Developers can use the same programming language throughout the entire application, reducing context switching and improving code maintainability. The strong community support, extensive package ecosystem through npm, and cost-effectiveness of open-source technologies make MERN stack an attractive choice for startups and enterprises alike.
Prerequisites for MERN Stack Installation
Before diving into the installation process, ensure your Manjaro system meets specific requirements. A fresh or recently updated Manjaro installation works best, regardless of whether you’re running KDE Plasma, XFCE, or GNOME desktop environment.
Administrative privileges are essential for installing system packages and managing services. Your user account should have sudo access configured properly. Hardware requirements include at least 8GB of RAM, though 16GB is recommended for handling multiple development servers and database operations simultaneously.
Allocate at least 20GB of free disk space for package installations, dependencies, development tools, and project files. A stable internet connection is necessary for downloading packages from official Manjaro repositories and the Arch User Repository. Basic command-line familiarity helps navigate the terminal efficiently during installation.
Having a text editor or integrated development environment installed beforehand streamlines the development workflow. Popular choices include Visual Studio Code, Vim, Nano, or Sublime Text. Git version control should be available for cloning repositories and managing source code.
The base-devel
package group is particularly important for Manjaro users. This collection includes essential compilation tools needed for building packages from the AUR, which you’ll use for MongoDB installation.
System Update and Essential Dependencies
Begin by updating your Manjaro system to ensure all packages are current. Open the terminal and execute the synchronization command:
sudo pacman -Syu
This command synchronizes package databases and upgrades all installed packages to their latest versions. The process may take several minutes depending on when you last updated the system. Pacman will display a list of packages to be upgraded and request confirmation before proceeding.
Once the system update completes, install essential build tools and utilities required throughout the MERN stack installation:
sudo pacman -S --needed base-devel git curl wget
The --needed
flag prevents reinstallation of packages already present on your system. Each package serves specific purposes in the development workflow.
The base-devel
package group includes compilers, make utilities, and build tools necessary for compiling native Node.js modules and building packages from the AUR. Git provides version control functionality, essential for managing code repositories and cloning AUR packages. Curl and wget are command-line utilities for downloading files, scripts, and packages from the internet.
Verify successful installation by checking package versions:
git --version
curl --version
wget --version
Each command should return version information, confirming proper installation. These tools form the foundation for the subsequent MERN stack component installations.
Installing Node.js and npm Package Manager
Node.js installation on Manjaro offers multiple approaches, each with distinct advantages. The simplest method uses Manjaro’s official repositories through pacman.
Install Node.js and npm directly from the official repositories:
sudo pacman -S nodejs npm
This method provides automatic updates through the system package manager and tight integration with Manjaro’s ecosystem. The official repositories typically contain recent Node.js versions suitable for most development needs.
However, web development often requires managing multiple Node.js versions across different projects. NVM (Node Version Manager) addresses this requirement by allowing seamless switching between Node.js versions.
To install NVM, download and execute the installation script:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/latest/install.sh | bash
Reload your shell configuration to activate NVM:
source ~/.bashrc
Install the latest Long Term Support (LTS) version of Node.js:
nvm install --lts
nvm use --lts
The LTS version provides stability and extended support, making it ideal for production applications. NVM allows installing multiple versions simultaneously and switching between them using nvm use
commands.
Verify the installation by checking Node.js and npm versions:
node -v
npm -v
Expected output shows version numbers like v20.x.x
for Node.js and 10.x.x
for npm. NPM (Node Package Manager) handles JavaScript package installations, dependency management, and script execution throughout your MERN development workflow.
Configure npm to avoid permission issues by setting up a local directory for global packages:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
This configuration prevents the need for sudo when installing global npm packages, following security best practices.
Installing MongoDB Database System
MongoDB installation on Manjaro requires the Arch User Repository since it’s not available in official repositories. Begin by installing an AUR helper to simplify package management.
Yay is a popular AUR helper written in Go that provides a pacman-like interface. If not already installed, build it from source:
git clone https://aur.archlinux.org/yay-git.git
cd yay-git
makepkg -sri
The makepkg
command compiles the package, while flags -sri
handle dependency installation and cleanup. Verify Yay installation:
yay --version
Installing MongoDB from the AUR offers two primary options: mongodb
and mongodb-bin
. The binary package (mongodb-bin
) is strongly recommended as it downloads pre-compiled binaries, avoiding lengthy compilation that can take hours on some systems.
Install MongoDB using the binary package:
yay -S mongodb-bin
During installation, you may encounter GPG key verification errors. MongoDB packages are signed with developer keys that need importing. Resolve GPG key issues by manually importing the MongoDB release signing key:
gpg --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 27EDEAF22F3ABCEB50DB9A125CC908FDB71E12C2
After importing the key, retry the MongoDB installation:
yay -S mongodb-bin
Once installation completes, configure MongoDB to start automatically and begin the service:
sudo systemctl start mongodb
sudo systemctl enable mongodb
The start
command immediately activates the MongoDB service, while enable
configures it to launch automatically during system boot. Check service status to confirm MongoDB is running properly:
sudo systemctl status mongodb
A green “active (running)” status indicates successful operation. Verify MongoDB installation by checking the version:
mongod --version
By default, MongoDB creates a data directory at /var/lib/mongodb
and stores configuration files in /etc/mongodb.conf
. Understanding these locations helps with troubleshooting and configuration adjustments.
For developers preferring containerized environments, Docker provides an alternative MongoDB installation method. This approach isolates MongoDB from the host system and simplifies version management.
Installing MongoDB Tools and Shell
MongoDB database tools provide essential utilities for database administration, backup, and data manipulation. Install the tools package from AUR:
yay -S mongodb-tools-bin
This package includes valuable utilities like mongodump
for database backups, mongorestore
for restoring backups, mongoexport
for exporting data to JSON or CSV formats, and mongoimport
for importing data from external sources.
Test your MongoDB connection using the MongoDB shell client:
mongosh
The MongoDB shell provides an interactive JavaScript interface for database operations. Execute basic commands to verify functionality:
show dbs
use testdb
db.testCollection.insertOne({name: "test", description: "MERN stack test"})
db.testCollection.find()
exit
These commands display available databases, create a new database, insert a test document, query the collection, and exit the shell. Successful execution confirms MongoDB is fully operational and ready for MERN stack integration.
Setting Up Express.js Framework
Express.js simplifies backend development by providing a minimalist, unopinionated web framework for Node.js. The Express application generator scaffolds new projects quickly with standard directory structures.
Install the Express generator globally using npm:
sudo npm install -g express-generator
The -g
flag installs the package globally, making Express commands available system-wide. Create a dedicated directory structure for your MERN project:
mkdir ~/mern-project
cd ~/mern-project
mkdir backend
cd backend
Initialize a new Node.js project with default configuration:
npm init -y
The -y
flag accepts all default values, creating a package.json
file that tracks project dependencies and metadata. Install Express and essential middleware packages for backend development:
npm install express mongoose cors dotenv body-parser
Each package serves critical functions in your backend architecture. Express provides core web framework capabilities including routing, middleware support, and HTTP utilities. Mongoose acts as an Object Data Modeling (ODM) library for MongoDB, offering schema validation and query building.
CORS (Cross-Origin Resource Sharing) middleware enables communication between frontend and backend running on different ports during development. Dotenv loads environment variables from .env
files, keeping sensitive configuration separate from code. Body-parser middleware parses incoming request bodies in JSON format, though recent Express versions include this functionality natively.
Install Nodemon as a development dependency for automatic server restarts:
npm install --save-dev nodemon
Nodemon watches file changes and automatically restarts the Node.js application, significantly improving development workflow efficiency.
Creating and Testing Express Server
Create a basic Express server to verify proper installation and configuration. In the backend directory, create a new file named server.js
:
nano server.js
Add the following server code:
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 5000;
// Middleware configuration
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Basic route for testing
app.get('/', (req, res) => {
res.json({
message: 'MERN Stack Backend Running on Manjaro',
status: 'success',
timestamp: new Date()
});
});
// Health check endpoint
app.get('/health', (req, res) => {
res.status(200).json({ status: 'healthy' });
});
// Start Express server
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
This server configuration includes middleware setup, test routes, and proper error handling structure. The CORS middleware allows cross-origin requests from your React frontend. Express.json() and express.urlencoded() parse incoming request bodies.
Update the package.json
scripts section to include development and production commands:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "echo \"Error: no test specified\" && exit 1"
}
Start the development server using Nodemon:
npm run dev
The server starts on port 5000 by default. Open your web browser and navigate to http://localhost:5000
to see the JSON response confirming Express functionality. Nodemon automatically restarts the server whenever you modify and save files.
Installing React.js Frontend Framework
React.js powers the user-facing portion of your MERN application with its efficient component-based architecture. Create React App provides the official tooling for initializing React projects with zero build configuration.
Navigate to your MERN project root directory and create the frontend application:
cd ~/mern-project
npx create-react-app frontend
The npx
command executes the latest version of create-react-app without requiring permanent global installation. This approach ensures you always use the most recent version with latest features and security updates.
Create React App automatically generates a complete project structure including source directories, configuration files, and development dependencies. The process takes several minutes as it downloads and installs React, ReactDOM, React Scripts, and numerous build tools.
Navigate to the frontend directory and examine the generated structure:
cd frontend
ls -la
Key directories include src
containing application source code, public
holding static assets like images and the index.html template, and node_modules
storing all dependency packages.
Review the package.json
file to understand installed dependencies:
cat package.json
Core dependencies include react
(the React library itself), react-dom
(DOM-specific React methods), and react-scripts
(build scripts and configuration).
Start the React development server to verify installation:
npm start
The development server launches on port 3000, automatically opens your default browser, and displays the default React application. Hot Module Replacement (HMR) enables real-time updates without full page refreshes when you modify components.
The React application includes a built-in build process for production deployment:
npm run build
This command creates an optimized production build in the build
directory, minifying code, optimizing assets, and generating static files ready for deployment.
Connecting MongoDB to Express Backend
Establishing a database connection between MongoDB and Express creates the data persistence layer for your MERN application. Create an environment configuration file in the backend directory:
cd ~/mern-project/backend
nano .env
Add MongoDB connection configuration and server port settings:
PORT=5000
MONGODB_URI=mongodb://localhost:27017/mern_database
NODE_ENV=development
Environment variables keep sensitive configuration separate from source code and allow different settings across development, staging, and production environments.
Update your server.js
file to establish MongoDB connection using Mongoose:
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
require('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.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log('MongoDB Connected Successfully');
console.log('Database:', mongoose.connection.name);
})
.catch(err => {
console.error('MongoDB Connection Error:', err.message);
process.exit(1);
});
// Routes
app.get('/', (req, res) => {
res.json({
message: 'MERN Stack Backend Running',
database: mongoose.connection.readyState === 1 ? 'Connected' : 'Disconnected'
});
});
// Server initialization
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
The connection options useNewUrlParser
and useUnifiedTopology
handle MongoDB driver deprecation warnings. The promise-based connection provides clear success and error handling.
Start the server and verify MongoDB connection:
npm run dev
Console output should display both the server running message and MongoDB connection success confirmation. The database connection state appears in the root endpoint response.
Building a Complete MERN Application
Creating a functional full-stack application demonstrates all MERN components working together seamlessly. Begin by defining a Mongoose schema for data modeling.
Create a models directory and define an Item schema:
mkdir ~/mern-project/backend/models
nano ~/mern-project/backend/models/Item.js
Add the schema definition:
const mongoose = require('mongoose');
const ItemSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Name is required'],
trim: true,
maxlength: [100, 'Name cannot exceed 100 characters']
},
description: {
type: String,
trim: true,
maxlength: [500, 'Description cannot exceed 500 characters']
},
quantity: {
type: Number,
default: 0,
min: [0, 'Quantity cannot be negative']
},
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
});
// Update timestamp on save
ItemSchema.pre('save', function(next) {
this.updatedAt = Date.now();
next();
});
module.exports = mongoose.model('Item', ItemSchema);
This schema includes validation rules, default values, and middleware for automatic timestamp updates. Create API routes for CRUD (Create, Read, Update, Delete) operations:
mkdir ~/mern-project/backend/routes
nano ~/mern-project/backend/routes/items.js
Implement the route handlers:
const express = require('express');
const router = express.Router();
const Item = require('../models/Item');
// GET all items
router.get('/', async (req, res) => {
try {
const items = await Item.find().sort({ createdAt: -1 });
res.json({ success: true, count: items.length, data: items });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// GET single item
router.get('/:id', async (req, res) => {
try {
const item = await Item.findById(req.params.id);
if (!item) {
return res.status(404).json({ success: false, error: 'Item not found' });
}
res.json({ success: true, data: item });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
// POST create new item
router.post('/', async (req, res) => {
try {
const item = await Item.create(req.body);
res.status(201).json({ success: true, data: item });
} catch (error) {
res.status(400).json({ success: false, error: error.message });
}
});
// PUT update item
router.put('/:id', async (req, res) => {
try {
const item = await Item.findByIdAndUpdate(req.params.id, req.body, {
new: true,
runValidators: true
});
if (!item) {
return res.status(404).json({ success: false, error: 'Item not found' });
}
res.json({ success: true, data: item });
} catch (error) {
res.status(400).json({ success: false, error: error.message });
}
});
// DELETE item
router.delete('/:id', async (req, res) => {
try {
const item = await Item.findByIdAndDelete(req.params.id);
if (!item) {
return res.status(404).json({ success: false, error: 'Item not found' });
}
res.json({ success: true, data: {} });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
module.exports = router;
Update server.js
to use the item routes:
const itemRoutes = require('./routes/items');
app.use('/api/items', itemRoutes);
Create React components to interact with the backend API. Install Axios for HTTP requests in the frontend:
cd ~/mern-project/frontend
npm install axios
Create a services directory for API communication:
mkdir src/services
nano src/services/api.js
Configure Axios with base URL:
import axios from 'axios';
const API = axios.create({
baseURL: 'http://localhost:5000/api'
});
export const getItems = () => API.get('/items');
export const getItem = (id) => API.get(`/items/${id}`);
export const createItem = (data) => API.post('/items', data);
export const updateItem = (id, data) => API.put(`/items/${id}`, data);
export const deleteItem = (id) => API.delete(`/items/${id}`);
export default API;
This service layer centralizes API calls and simplifies component code.
Comprehensive Testing Procedures
Thorough testing ensures all MERN stack components function correctly and communicate properly. Begin with individual component verification.
Test Node.js and npm installations:
node -v
npm -v
Both commands should return version numbers without errors. Verify MongoDB service status and connectivity:
sudo systemctl status mongodb
mongod --version
mongosh --eval "db.runCommand({ connectionStatus: 1 })"
The connection status command confirms MongoDB accepts connections and returns authentication details.
Test Express backend endpoints using curl or browser:
curl http://localhost:5000/api/items
curl -X POST http://localhost:5000/api/items \
-H "Content-Type: application/json" \
-d '{"name":"Test Item","description":"Testing MERN stack","quantity":5}'
Successful responses indicate proper backend functionality. Test React frontend by accessing http://localhost:3000
and verifying component rendering and API communication.
Verify MongoDB data persistence by inserting documents through the API and querying them directly through the MongoDB shell. Check application logs for errors or warnings that might indicate configuration issues.
Security Best Practices
Implementing security measures protects your MERN applications from common vulnerabilities. Environment variables should never be committed to version control repositories.
Create a .gitignore
file in project root:
echo "node_modules/" >> .gitignore
echo ".env" >> .gitignore
echo "build/" >> .gitignore
echo "*.log" >> .gitignore
Install and configure security middleware packages:
cd ~/mern-project/backend
npm install helmet express-rate-limit express-validator
Helmet sets security-related HTTP headers, express-rate-limit prevents brute force attacks, and express-validator sanitizes user inputs. Update server.js
with security middleware:
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
app.use(helmet());
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use('/api/', limiter);
Configure MongoDB authentication for production environments by creating administrative and application-specific users with limited privileges. Regularly audit npm packages for security vulnerabilities:
npm audit
npm audit fix
Implement JSON Web Tokens (JWT) for authentication and authorization. Configure CORS to allow only trusted origins in production environments.
Performance Optimization Strategies
Optimizing MERN applications improves user experience and reduces server resource consumption. MongoDB performance benefits significantly from proper indexing.
Create indexes on frequently queried fields:
ItemSchema.index({ name: 'text' });
ItemSchema.index({ createdAt: -1 });
Implement pagination for large datasets to reduce memory usage and improve response times:
router.get('/', async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const skip = (page - 1) * limit;
const items = await Item.find().limit(limit).skip(skip);
const total = await Item.countDocuments();
res.json({
data: items,
pagination: { page, limit, total, pages: Math.ceil(total / limit) }
});
});
React performance improves through memoization and code splitting. Use React.memo for component memoization and useMemo for expensive calculations. Implement lazy loading for route-based code splitting:
import React, { lazy, Suspense } from 'react';
const ItemList = lazy(() => import('./components/ItemList'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<ItemList />
</Suspense>
);
}
Configure nginx as a reverse proxy for production deployments, enabling caching, compression, and load balancing. Minimize React bundle sizes through tree shaking and production builds.
Troubleshooting Common Installation Issues
Installation challenges arise from various sources requiring targeted solutions. MongoDB GPG key import failures represent the most common issue.
Resolve GPG key errors by importing keys from multiple keyservers:
gpg --recv-keys --keyserver hkp://keys.openpgp.org 27EDEAF22F3ABCEB50DB9A125CC908FDB71E12C2
Port conflicts occur when default ports 3000 or 5000 are already in use. Identify processes using specific ports:
sudo lsof -i :5000
sudo lsof -i :3000
Terminate conflicting processes or change application ports in environment configuration files.
MongoDB service startup failures often relate to permission issues or corrupted data directories. Check service logs for detailed error information:
sudo journalctl -u mongodb -n 50 --no-pager
Verify MongoDB data directory permissions:
sudo chown -R mongodb:mongodb /var/lib/mongodb
sudo chmod 755 /var/lib/mongodb
NPM permission errors during global package installation indicate improper npm configuration. Avoid using sudo with npm; instead, configure npm prefix to user directory as described earlier.
CORS errors between React frontend and Express backend require proper middleware configuration. Ensure CORS middleware is loaded before route handlers and configured to accept requests from React development server:
app.use(cors({
origin: 'http://localhost:3000',
credentials: true
}));
React build failures often stem from dependency conflicts or corrupted node_modules. Clear dependencies and reinstall:
rm -rf node_modules package-lock.json
npm cache clean --force
npm install
Mongoose connection timeouts indicate MongoDB service issues or incorrect connection strings. Verify MongoDB service status and confirm connection URI matches MongoDB configuration.
The Manjaro community forums and Arch Wiki provide extensive documentation for troubleshooting Arch-based distribution issues. MongoDB community forums offer database-specific support, while Stack Overflow contains solutions for common MERN stack challenges.
Congratulation’s! You have successfully installed MERN. Thanks for using this tutorial for installing the MERN Stack on your Manjaro Linux system. For additional help or useful information, we recommend you check the official MERN website.