If you'd told me a couple of years ago that I'd spend my evenings writing PHP, I would've laughed it off. I built my whole identity as a developer around MERN — MongoDB, Express, React, Node. It was fast, it was JavaScript top to bottom, and it felt like the "modern" stack compared to what a lot of local agencies were still running.
So it's a little funny to be sitting here now, a few months into learning Laravel and PostgreSQL, actually enjoying it. This isn't a "PHP was secretly amazing the whole time" post. It's more of an honest breakdown of why I started, what's been genuinely harder than I expected, and what's actually made me a better developer in the process.
Why bother, if MERN already works
Two things pushed me here.
First, the job and freelance market. I'm based in Dhaka, and if you look at what local agencies, small businesses, and even a lot of remote clients are actually running, PHP is everywhere. Laravel specifically shows up constantly in job posts and freelance briefs here — way more than I expected when I was deep in my MERN bubble. Sticking to one stack was quietly shrinking the pool of work I could take on.
Second, and this one surprised me more — I wanted to actually understand a relational database properly. I'd built a handful of projects on MongoDB, and I realized I'd never really had to think hard about schema design, foreign keys, or joins. MongoDB lets you get away with a lot of "figure it out later" thinking. I wanted to know what I was missing.
The parts that messed with my head
Coming from Mongoose, Eloquent felt oddly strict at first. In Mongoose, your schema is basically a suggestion:
// Mongoose — schema is more of a guideline
const productSchema = new mongoose.Schema({
name: String,
price: Number,
tags: [String], // add whatever, whenever
});
In Laravel, the database is the source of truth, and migrations force you to commit to a structure before you write a line of app logic:
// Laravel migration — schema is law
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->decimal('price', 8, 2);
$table->foreignId('category_id')->constrained();
$table->timestamps();
});
That foreignId()->constrained() line is such a small thing, but it represents a mindset shift I didn't expect. In MongoDB, "relationships" are usually just an ID you remember to populate correctly in your app code. In PostgreSQL, the database itself refuses to let you insert a product with a category that doesn't exist. The first time a constraint error caught a bug I would've silently shipped in MERN, I actually said "huh" out loud at my desk.
Artisan took some getting used to too. php artisan make:model Product -m scaffolds a model and migration in one command, and there's a generator for basically everything — controllers, requests, seeders, jobs. Coming from hand-rolling most of my Express boilerplate, it felt like cheating at first. Now I just think of it as Laravel handling the parts of backend dev that were never interesting anyway.
Blade was the smallest adjustment, honestly, mostly because I'd already done enough server-rendered work to not be precious about JSX. It's just PHP mixed into HTML with some sugar on top — @if, @foreach, component includes. Nothing revolutionary, but nothing to fight either.
What I'm not giving up
I want to be clear this isn't a "MERN was a phase" post. I'm still building with React and Node, and most of what I've shipped so far leans on that stack — a machine-learning-backed gold price predictor, a peer-to-peer file sharing tool built on WebRTC, an IoT drainage monitoring setup running on an ESP32 feeding into Firebase. None of that goes away.
What's changed is that I stopped treating "the stack" as a personality trait. Laravel and PostgreSQL are just more tools now, and honestly, having both a document-store mental model and a relational one makes me design better MERN apps too. I catch myself asking "should this actually be normalized?" in Mongoose schemas now, which never used to occur to me.
If you're a MERN dev thinking about doing the same
A few things that would've saved me time:
- Don't fight Eloquent relationships — learn
hasMany,belongsTo, andbelongsToManyproperly before building anything. Half of Laravel's "magic" is just these three. - Migrations are version control for your schema. Treat them like git commits — small, descriptive, one change at a time.
-
php artisan tinkeris basically a Node REPL for your Laravel app. Use it constantly to test queries before wiring them into controllers. - PostgreSQL's
EXPLAIN ANALYZEis worth learning early. Coming from Mongo, I never had to think about query performance this explicitly.
Where this is heading
I'm still early — a few real projects deep, not an expert by any stretch. But I'm at the point where I'd genuinely take on Laravel or PostgreSQL work alongside MERN projects, and I'm actively looking for freelance and full-time opportunities where I can keep building across both.
If you're working on something and think there's a fit, or you just want to see what I've built so far, my projects and contact info are here:
🔗 Portfolio: https://zahidhasantonmoy.vercel.app
🔗 GitHub: https://github.com/zahidhasantonmoy