Meta Description: Learn what a database is in Node.js, explore MySQL, PostgreSQL, MongoDB, and SQLite options, and build your first database connection with real code examples. (158 chars)
You've built your first Node.js API. It works — but every time the server restarts, your data vanishes. That's the moment every developer realizes they need a database. Let's fix that, step by step.
What is a Database?
A database is an organized system for storing, retrieving, and managing data persistently. Think of it as a supercharged spreadsheet your application can read and write to — even after restarting.
There are two major families:
- SQL (Relational): Data lives in tables with rows and columns. Strict schema. Examples: MySQL, PostgreSQL, SQLite.
- NoSQL (Non-relational): Flexible structure — documents, key-value pairs, or graphs. Examples: MongoDB, Redis.
Quick rule of thumb:
- Structured, relational data (users, orders) → SQL
- Flexible, nested data (posts, logs, real-time feeds) → NoSQL
Why Node.js Needs Databases
Node.js is a runtime — it processes logic, but it has no built-in memory between requests. Without a database:
- User accounts disappear on restart
- You can't query or filter data
- Scaling to multiple servers becomes impossible
A Node.js backend database bridges your API with persistent storage. Every production app — from a todo list to Netflix — runs on one.
Popular Node.js Database Options
| Database | Type | Best For | Node.js Driver |
|---|---|---|---|
| PostgreSQL | SQL | Complex queries, production apps |
pg / Prisma |
| MySQL | SQL | Web apps, WordPress-style stacks |
mysql2 / Sequelize |
| MongoDB | NoSQL/Docs | Flexible schemas, rapid prototyping | mongoose |
| SQLite | SQL (file) | Local dev, small apps, testing | better-sqlite3 |
2026 Recommendation: PostgreSQL + Prisma for new full-stack projects. MongoDB + Mongoose for rapid prototyping.
Connect Database to Node.js (Code Examples)
Step 1: Install dotenv for all projects
npm install dotenv
Create a .env file:
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=yourpassword
DB_NAME=myapp
MONGO_URI=mongodb://localhost:27017/myapp
Node.js MySQL Connection (mysql2)
npm install mysql2
// db/mysql.js
import 'dotenv/config';
import mysql from 'mysql2/promise';
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10,
});
// CRUD Example
async function getUsers() {
try {
const [rows] = await pool.query('SELECT * FROM users');
return rows;
} catch (err) {
console.error('MySQL Error:', err.message);
throw err;
}
}
async function createUser(name, email) {
const [result] = await pool.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
return result.insertId;
}
export { getUsers, createUser };
Node.js PostgreSQL Connection (pg)
npm install pg
// db/postgres.js
import 'dotenv/config';
import pg from 'pg';
const { Pool } = pg;
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
// OR individual fields: host, user, password, database, port
});
async function findUserById(id) {
try {
const { rows } = await pool.query(
'SELECT * FROM users WHERE id = $1',
[id]
);
return rows[0] ?? null;
} catch (err) {
console.error('PG Error:', err.message);
throw err;
}
}
export { findUserById };
MongoDB Node.js with Mongoose
npm install mongoose
// db/mongo.js
import 'dotenv/config';
import mongoose from 'mongoose';
await mongoose.connect(process.env.MONGO_URI);
// Define Schema
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
createdAt: { type: Date, default: Date.now },
});
const User = mongoose.model('User', userSchema);
// CRUD
const createUser = async (name, email) => {
const user = new User({ name, email });
return await user.save();
};
const getUsers = async () => await User.find().lean();
const deleteUser = async (id) => await User.findByIdAndDelete(id);
export { User, createUser, getUsers, deleteUser };
Prisma ORM (PostgreSQL/MySQL — 2026 Standard)
npm install prisma @prisma/client
npx prisma init
// prisma/schema.prisma
model User {
id Int @id @default(autoincrement())
name String
email String @unique
}
npx prisma migrate dev --name init
// db/prisma.js
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const users = await prisma.user.findMany();
const newUser = await prisma.user.create({
data: { name: 'Arjun', email: 'arjun@dev.io' },
});
Best Practices for Production
1. Always use connection pools
Never open a new connection per request. Use pool (mysql2, pg) or Prisma's built-in pooling.
2. Store credentials in environment variables
Never hardcode passwords. Use .env + dotenv, or a secrets manager in production (AWS Secrets Manager, Railway variables).
3. Validate and sanitize inputs
Always use parameterized queries (?, $1) — never string-concatenate user input. This prevents SQL injection.
4. Handle errors explicitly
Wrap every DB call in try/catch. Log errors server-side; return generic messages to clients.
5. Use transactions for multi-step operations
// pg transaction example
const client = await pool.connect();
try {
await client.query('BEGIN');
await client.query('INSERT INTO orders ...', [...]);
await client.query('UPDATE inventory ...', [...]);
await client.query('COMMIT');
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
client.release();
}
6. Index your frequently queried columns
Add indexes on email, userId, and foreign keys to avoid full table scans.
Conclusion + Next Steps
You now know:
- ✅ What a database is and SQL vs NoSQL differences
- ✅ How to connect Node.js to MySQL, PostgreSQL, and MongoDB
- ✅ How to use Prisma ORM for production-grade code
- ✅ Best practices to keep your app secure and fast
Next Steps:
- Build a REST API with Express + PostgreSQL + Prisma
- Add authentication (JWT + hashed passwords with bcrypt)
- Deploy to Railway or Supabase (free tiers available)
- Explore database indexing and query optimization
Try this code → share your results in the comments! Drop a link to your repo — happy to review it.
FAQ
Q1. What is the best database for Node.js beginners?
SQLite for local learning (zero setup), then PostgreSQL with Prisma for real projects.
Q2. Should I use an ORM or raw SQL?
Use Prisma or Sequelize for productivity. Learn raw SQL too — it makes you a better developer and is essential for debugging.
Q3. What's the difference between mysql and mysql2?
mysql2 is the modern, actively maintained successor with Promise/async-await support and better performance. Always use mysql2.
Q4. How do I connect a database in a Node.js backend for production?
Use a connection pool, store credentials in environment variables, enable SSL if your provider supports it, and use a managed database (Supabase, PlanetScale, Railway) instead of self-hosting.
Q5. Can I use multiple databases in one Node.js app?
Yes. Many production apps use PostgreSQL for structured data and Redis for caching, or MongoDB for logs alongside a relational database. Initialize each client once and export it.
Top comments (0)