
Explore insightful articles, practical tips, and fresh perspectives on topics that matter — curated to inform, inspire, and ignite conversation.

During my final year, I attended interviews at several companies but was unfortunately rejected in the aptitude rounds. Instead of giving up, I decided to start freelancing and build real-world projects to sharpen my skills and gain experience. 💪
I began by reaching out to local businesses and startups that didn’t have an online presence. I offered to create simple, functional websites for them — sometimes even free — just to learn real-world workflows. Each project helped me understand client requirements, deployment, and teamwork better than any classroom project ever could.
I consistently shared my freelance projects and coding progress on LinkedIn. That consistency paid off when Webinnova Ltd (UK) noticed my work and reached out to me! Today, I’m thrilled to share that I’ve officially joined Webinnova Ltd as a Web Developer! 🎉
I’ve learned that the universe always listens — what you truly believe, ask for, and work hard toward will happen one day. ✨ We may not know what’s coming next, but that’s the beauty of it. Just give your best today, stay consistent, and the results will come automatically when the time is right. 🌠
To anyone feeling disheartened by rejections — don’t lose hope. ❤ Keep building, keep learning, and keep sharing your work. Your consistency and passion will get noticed sooner or later. 🌱
Real-world projects are the fastest way to grow as a developer. They teach you communication, problem-solving, and deployment — the skills that truly matter in the industry. Believe in yourself, trust the universe, and keep moving forward — your moment will come. 🙌

During my job, my senior staff approached me and said: "We have this React web project, but we also need it as a mobile application." At first, I was a bit unsure how to approach it efficiently. So I decided to research ways to create native applications from a single codebase. 📱💻
Normally, writing separate code for Web, Android, and iOS can take a lot of time and effort. Today, I discovered a fantastic platform called Capacitor. Using Capacitor, you can take your React code and build it for Android, iOS, and Web — all from a single codebase. 🚀
Capacitor is a modern cross-platform framework created by the team behind Ionic. It allows web developers to use **one codebase** to deploy applications on multiple platforms. Essentially, your React app runs inside a native container, giving you access to native device APIs while still writing in React.
Capacitor is ideal in many scenarios:
Here’s a step-by-step guide to get your React app running as a native mobile application:
npm install @capacitor/core @capacitor/cli
npx cap init
npm run build
npm install @capacitor/android npx cap add android npm run build npx cap copy npx cap open android
✅ Note: npx cap copy copies your React build files into android/app/src/main/assets/public/
npx cap sync
✅ This will copy your new web assets and also update native dependencies if plugins or configurations change.
Before adding iOS platform, make sure you have the following:
sudo gem install cocoapodsxcode-select --installxcode-select -p xcodebuild -version
npx cap add ios npm run build npx cap copy ios npx cap open ios
✅ Now you can run your app on a simulator or a real iOS device.
Capacitor is a game-changer for developers who know React and want to create native apps efficiently. It saves time, simplifies deployment, and allows you to use a single codebase for multiple platforms. If your clients ever ask for both web and mobile versions, Capacitor is the perfect solution. ✨

This guide explains how to deploy a Node.js (Express) backend with MySQL and PM2 on a VPS, along with setting up a React frontend using Nginx as a reverse proxy.
ssh root@203.0.113.10
Connect securely to your VPS via SSH using your server's IP address.
apt update && apt upgrade -y
apt install nodejs npm -y
npm install pm2 -g
node -v
npm -v
pm2 -v
Update system packages, install Node.js and npm, then install PM2 globally to manage Node processes.
Before you begin editing configuration files on your VPS, it’s helpful to know some basic keyboard shortcuts for nano (the default text editor in most Linux servers).
These commands make it easy to save, cancel, or navigate when editing files like .env or Nginx configs.
# Save changes in Nano
Ctrl + O → Write (save) changes to file
Enter → Confirm file name
Ctrl + X → Exit the editor
# Cancel editing without saving
Ctrl + X → Exit
N → Discard changes
# Other helpful shortcuts
Ctrl + K → Cut the current line
Ctrl + U → Paste (after cutting)
Ctrl + W → Search for text in file
Ctrl + C → Show current cursor position
These shortcuts are essential when editing configuration files such as
/etc/nginx/sites-available/example.com or environment files like .env directly on your server terminal.
cd /root
git clone https://github.com/example/demo-express-app.git
cd demo-express-app
Clone your backend project from GitHub or manually upload your code into the VPS.
npm install
Install all required npm packages defined in package.json.
Create a .env file in your project root to store app and database configuration.
APP_NAME=DemoApp
APP_PORT=5000
APP_URL=http://localhost
DB_ENGINE=mysql
DB_NAME=demo_db
DB_HOST=localhost
DB_USER=demo_user
DB_PASS=supersecret
DB_PORT=3306
JWT_SECRET_KEY=change_this_secret
JWT_ALGORITHM=HS256
BASE_URL=http://localhost:5000
These variables define your app name, ports, and MySQL credentials.
apt install mysql-server -y
systemctl start mysql
systemctl enable mysql
mysql_secure_installation
Install and secure MySQL, then start and enable it to run automatically on reboot.
mysql -u root -p
CREATE DATABASE demo_db;
CREATE USER 'demo_user'@'localhost' IDENTIFIED BY 'supersecret';
GRANT ALL PRIVILEGES ON demo_db.* TO 'demo_user'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
Create a new database and user with full privileges for your application.
mysql -u demo_user -p
SHOW DATABASES;
Verify your new MySQL user can access the database successfully.
npm run start
# expect logs:
# Connected to mysql database
# Server running on http://localhost:5000
Run the app locally to confirm it connects properly before using PM2.
pm2 start dist/index.js --name demo-backend
pm2 save
pm2 startup
PM2 ensures your backend runs continuously even after terminal closure or system reboot.
pm2 list
pm2 logs demo-backend
pm2 restart demo-backend
pm2 stop demo-backend
pm2 delete demo-backend
Use these PM2 commands to view logs, restart, stop, or remove your app process.
apt install nginx -y
nano /etc/nginx/sites-available/example.com
Install Nginx and create a configuration file to route traffic to your Node.js app.
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
Link the config file, test syntax, and reload Nginx to apply changes.
apt install certbot python3-certbot-nginx -y
certbot --nginx -d example.com -d www.example.com
Install Certbot to automatically configure free SSL certificates via Let's Encrypt.
cd /root/demo-express-app
git pull
npm install
pm2 restart demo-backend
Pull the latest code, update dependencies, and restart your app using PM2.
.env credentials and MySQL grants.systemctl start mysql.pm2 logs demo-backend.ssh root@203.0.113.10
Connect again to your VPS to deploy the frontend application.
apt update && apt upgrade -y
apt install nodejs npm -y
npm install -g serve pm2
Install Node.js, npm, and serve for hosting static files.
cd /root
git clone https://github.com/example/demo-frontend.git
cd demo-frontend
Fetch your React project from GitHub or upload it manually.
npm install
Install frontend dependencies required for the React build.
npm run build
Generate production-ready static files in the dist/ folder.
serve -s dist -l 3000
Preview your app locally on port 3000 before deploying it permanently.
pm2 start "serve -s dist -l 3000" --name demo-frontend
pm2 save
pm2 startup
Use PM2 to keep the frontend running continuously in the background.
pm2 list
pm2 logs demo-frontend
pm2 restart demo-frontend
pm2 stop demo-frontend
Check logs and restart or stop the frontend when needed.
http://203.0.113.10:3000
Open the IP address in your browser to confirm the site is running.
/root
├── demo-express-app/
│ ├── dist/
│ ├── package.json
│ └── ...
└── demo-frontend/
├── dist/
├── package.json
└── ...
pm2 stop demo-frontend
npm run build
pm2 restart demo-frontend
Stop the old process, rebuild the latest code, and restart the frontend.
“Great things are built step by step — keep learning, keep building.”

This is an official security update from the Next.js team regarding a critical vulnerability affecting React Server Components (RSC) in Next.js App Router applications. The issue is rated CVSS 10.0 and can lead to remote code execution in unpatched environments.
A critical vulnerability has been identified in the React Server Components (RSC) protocol. This issue can allow remote code execution when processing attacker-controlled requests in unpatched environments. This advisory tracks the downstream impact on Next.js applications using the App Router.
The vulnerable RSC protocol allowed untrusted inputs to influence server-side execution behavior. Under specific conditions, an attacker could craft malicious requests that trigger unintended server execution paths, resulting in remote code execution.
Not affected: Next.js 13.x, stable 14.x, Pages Router applications, and the Edge Runtime.
There is no workaround. All users should upgrade to the latest patched version immediately.
npm install next@15.0.5
npm install next@15.1.9
npm install next@15.2.6
npm install next@15.3.6
npm install next@15.4.8
npm install next@15.5.7
npm install next@16.0.7
# Canary releases
npm install next@15.6.0-canary.58
npm install next@16.1.0-canary.12
# If using 14.x canary
npm install next@14
npx fix-react2shell-next
For full details, see the official Next.js advisory: https://nextjs.org/blog/CVE-2025-66478
“Always keep your frameworks updated to stay protected.”

Muthukumaran R
Full-Stack Developer & Freelancer
Jump to any section of my portfolio or explore more content.