| name | nodejs-project-setup |
| description | Use when setting up a new Node.js project, configuring Prisma, writing docker-compose, or creating project structure for backend development. Trigger phrases: setup project, initialize project, project structure, prisma setup, docker compose, nodemon, package install. |
Node.js Project Setup Reference
This skill contains the complete, canonical setup steps for every Node.js backend project taught in this course. When writing notes or helping with setup, always follow these conventions exactly.
Complete Project Folder Structure
Every project must follow this layout. The entry point is src/server.js, not app.js.
project-name/
src/
server.js <- starts the Express server, imports routes, middleware
controllers/
userController.js <- logic for handling user routes
productController.js
middlewares/
logger.js <- custom logging middleware
errorHandler.js <- global error handling middleware
auth.js <- JWT verification middleware
routes/
userRoutes.js <- Express Router, maps URLs to controllers
productRoutes.js
db/
prisma.js <- creates and exports the Prisma client
generated/
prisma/ <- auto-generated by Prisma, never edit manually
prisma/
schema.prisma <- define your database models here
migrations/ <- auto-created when you run prisma migrate
prisma.config.js <- Prisma configuration (renamed from .ts)
.env <- all secret/environment config, never commit this
.gitignore <- tell Git what to ignore
docker-compose.yaml <- defines the PostgreSQL container
package.json
package-lock.json
Step 1: Initialize the Project
mkdir my-project
cd my-project
npm init -y
Step 2: Install Packages
Run these two commands every time you start a new Node.js backend project.
npm i express dotenv pg @prisma/client @prisma/adapter-pg
npm i prisma --save-dev
npm i -D nodemon
Package explanations:
| Package | Purpose |
|---|
| express | Web framework for building APIs |
| dotenv | Loads .env file into process.env |
| pg | PostgreSQL driver (lets Node.js talk to Postgres) |
| @prisma/client | The auto-generated Prisma query client |
| @prisma/adapter-pg | Connects Prisma to PostgreSQL using pg driver |
| prisma | CLI tool for migrations and schema management |
| nodemon | Auto-restarts the server when you save a file |
Step 3: Configure package.json
After npm init -y, open package.json and update it to look like this:
{
"name": "my-project",
"version": "1.0.0",
"type": "module",
"main": "src/server.js",
"scripts": {
"start": "node src/server.js",
"dev": "nodemon src/server.js"
},
"dependencies": {
"@prisma/adapter-pg": "...",
"@prisma/client": "...",
"dotenv": "...",
"express": "...",
"pg": "..."
},
"devDependencies": {
"nodemon": "...",
"prisma": "..."
}
}
Key points:
"type": "module" enables ES module syntax (import/export)
"start" runs the production server
"dev" runs nodemon which restarts automatically on file save
Step 4: Create the .env File
Create .env in the project root (same level as package.json):
PORT=8888
POSTGRES_USER=userdipak
POSTGRES_PASSWORD=user_password
POSTGRES_DB=student_record
POSTGRES_HOST=localhost
POSTGRES_PORT=5555
# DATABASE_URL format: postgresql://user:password@host:port/databaseName?schema=public
DATABASE_URL="postgresql://userdipak:user_password@localhost:5555/student_record?schema=public"
Change userdipak, user_password, and student_record to match your actual values.
Step 5: Create the .gitignore File
Create .gitignore in the project root:
# Dependencies
node_modules/
# Environment variables (NEVER commit this)
.env
# Build output
dist/
# Prisma generated files (optional, regenerated with prisma generate)
# src/generated/
Step 6: Create docker-compose.yaml
Create docker-compose.yaml in the project root. This defines the PostgreSQL database container.
services:
postgres:
image: postgres:16
restart: always
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "${POSTGRES_PORT}:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
The ${VARIABLE} syntax reads values from your .env file automatically.
Podman Commands
This course uses Podman instead of Docker (they use the same compose file format):
podman compose up
podman compose up -d
podman compose down
Start the database container before running your Node.js server.
Step 7: Initialize Prisma
npx prisma init
This creates:
prisma/schema.prisma - your database schema file
prisma/prisma.config.ts - rename this to prisma.config.js
mv prisma/prisma.config.ts prisma/prisma.config.js
Step 8: Configure schema.prisma
Open prisma/schema.prisma and update it to exactly this (for JavaScript projects):
generator client {
provider = "prisma-client-js"
output = "../src/generated/prisma"
moduleFormat = "esm"
}
datasource db {
provider = "postgresql"
}
Explanation of each line:
provider = "prisma-client-js" tells Prisma to generate a JavaScript client
output = "../src/generated/prisma" puts the generated client inside src/generated/prisma/
moduleFormat = "esm" generates ES module format (matching "type": "module" in package.json)
provider = "postgresql" tells Prisma the database is PostgreSQL
- No
url is needed in datasource because Prisma reads DATABASE_URL from .env automatically
Step 9: Create src/db/prisma.js
Create the folder first: mkdir -p src/db
Then create src/db/prisma.js:
import 'dotenv/config';
import { PrismaClient } from '../generated/prisma/client.js';
import { PrismaPg } from '@prisma/adapter-pg';
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({ adapter });
export default prisma;
Note: if you want to use import { PrismaClient } from '@prisma/client' instead, remove the output line from schema.prisma and run npx prisma generate again.
Step 10: Add Models to schema.prisma
Example model for a User table:
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
}
Step 11: Run Migrations
npx prisma migrate dev --name create_users_table
Other useful Prisma commands:
npx prisma studio
npx prisma migrate reset
npx prisma generate
Step 12: Create src/server.js
import 'dotenv/config';
import express from 'express';
const app = express();
app.use(express.json());
const PORT = process.env.PORT || 8888;
app.get('/', (req, res) => {
res.json({ message: 'Server is running' });
});
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
Quick Start Checklist
Use this checklist every time you start a new project: