Skip to main content
The Node + PostgreSQL template scaffolds a complete backend application with Express server, PostgreSQL database integration using Prisma ORM, and example CRUD operations.

What Gets Generated

This template creates a production-ready Node.js application with:
  • Express server with middleware setup
  • PostgreSQL integration using Prisma ORM
  • Type-safe database queries with Prisma Client
  • MVC architecture with routes and controllers
  • Example User model with full CRUD operations
  • Database migration system
  • Development tooling (nodemon, morgan logger)
  • Environment configuration
  • TypeScript or JavaScript variants

Create a New Project

1

Run the template command

devark template node-postgresql my-app
Or use the shorthand:
devark t node-postgresql my-app
2

Choose your language

The CLI will prompt you to select JavaScript or TypeScript:
? Which language do you want to use?
> JavaScript
  TypeScript
3

Wait for installation

Devark will:
  • Create the project structure
  • Generate all template files
  • Install dependencies automatically
  • Set up Prisma configuration
4

Initialize Prisma

After installation, run these commands:
cd my-app
npx prisma generate
npx prisma migrate dev --name "init"

Project Structure

my-app/
├── controllers/
│   └── userController.js    # User CRUD operations
├── routes/
│   └── userRoutes.js        # User API endpoints
├── utils/
│   └── prismaClient.js      # Prisma client singleton
├── prisma/
│   └── schema.prisma        # Database schema
├── app.js                   # Express server entry point
├── .env.example             # Environment variables template
├── .gitignore              # Git ignore rules
├── package.json            # Project dependencies
└── Instructions.md         # Setup instructions

Generated Files

Express Server (app.js/app.ts)

The main application file configures Express with middleware:
import express from "express";
import morgan from "morgan";
import dotenv from "dotenv";
import userRoutes from "./routes/userRoutes.js";

dotenv.config();

const app = express();

// Middleware
app.use(express.json());
app.use(morgan("dev"));

// Routes
app.use("/api/users", userRoutes);

// Health check
app.get("/", (req, res) => {
  res.send("Node.js + PostgreSQL + Prisma API is running...");
});

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Prisma Schema (prisma/schema.prisma)

Database schema definition with PostgreSQL provider:
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        Int      @id @default(autoincrement())
  name      String
  email     String   @unique
  createdAt DateTime @default(now())
}
Prisma provides type-safe database access and automatic migrations. The schema defines your database structure in a declarative way.

Prisma Client (utils/prismaClient.js)

Singleton instance of Prisma Client with connection testing:
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

async function testConnection() {
  try {
    await prisma.$connect();
    console.log("Successfully connected to PostgreSQL via Prisma!");
  } catch (err) {
    console.error("Failed to connect to PostgreSQL:", err);
  }
}

testConnection();

export default prisma;

User Routes (routes/userRoutes.js)

RESTful API endpoints:
import express from "express";
import { 
  getUsers, 
  createUser, 
  getUserById, 
  deleteUser, 
  updateUser 
} from "../controllers/userController.js";

const router = express.Router();

router.get("/", getUsers);
router.post("/", createUser);
router.get("/:id", getUserById);
router.patch("/:id", updateUser);
router.delete("/:id", deleteUser);

export default router;

User Controller (controllers/userController.js)

Type-safe CRUD operations using Prisma:
import prisma from "../utils/prismaClient.js";

// Create User
export const createUser = async (req, res) => {
  try {
    const { name, email } = req.body;
    const user = await prisma.user.create({
      data: { name, email },
    });
    res.status(201).json(user);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

// Read All Users
export const getUsers = async (req, res) => {
  try {
    const users = await prisma.user.findMany();
    res.json(users);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
};

// Read One User by ID
export const getUserById = async (req, res) => {
  try {
    const { id } = req.params;
    const user = await prisma.user.findUnique({
      where: { id: parseInt(id) },
    });
    if (!user) return res.status(404).json({ error: "User not found" });
    res.json(user);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
};

// Update User
export const updateUser = async (req, res) => {
  try {
    const { id } = req.params;
    const { name, email } = req.body;
    const user = await prisma.user.update({
      where: { id: parseInt(id) },
      data: { name, email },
    });
    res.json(user);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

// Delete User
export const deleteUser = async (req, res) => {
  try {
    const { id } = req.params;
    await prisma.user.delete({
      where: { id: parseInt(id) },
    });
    res.json({ message: "User deleted successfully" });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
};

Dependencies

Production Dependencies

express

Fast, minimalist web framework for Node.js

@prisma/client

Auto-generated type-safe database client

dotenv

Load environment variables from .env file

morgan

HTTP request logger middleware

Development Dependencies

  • prisma - Prisma CLI for migrations and schema management
  • nodemon - Auto-restart server on file changes

NPM Scripts

{
  "scripts": {
    "dev": "nodemon app.js",
    "start": "node app.js",
    "prisma:migrate": "prisma migrate dev --name init",
    "prisma:generate": "prisma generate",
    "prisma:studio": "prisma studio"
  }
}

Script Descriptions

  • dev - Start development server with auto-reload
  • start - Start production server
  • prisma:migrate - Create and apply database migrations
  • prisma:generate - Generate Prisma Client from schema
  • prisma:studio - Open Prisma Studio (database GUI)

Environment Variables

Create a .env file in your project root:
DATABASE_URL="postgresql://username:password@localhost:5432/mydb?schema=public"
PORT=5000
Update the DATABASE_URL with your actual PostgreSQL credentials. Never commit .env files to version control.

TypeScript Configuration

The TypeScript variant includes tsconfig.json:
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "nodenext",
    "rootDir": "src",
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src"]
}

Running the Project

1

Install PostgreSQL

Make sure PostgreSQL is installed and running:
# macOS
brew services start postgresql

# Linux
sudo systemctl start postgresql

# Or use Docker
docker run -d \
  --name postgres \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_DB=mydb \
  -p 5432:5432 \
  postgres:latest
2

Configure environment

Copy .env.example to .env and update the database URL:
cp .env.example .env
Update DATABASE_URL with your PostgreSQL credentials.
3

Generate Prisma Client

Generate the Prisma Client from your schema:
npx prisma generate
4

Run database migrations

Create the database tables:
npx prisma migrate dev --name "init"
This creates the User table in your PostgreSQL database.
5

Start development server

npm run dev
The server will start on http://localhost:5000.
6

Test the API

Create a user:
curl -X POST http://localhost:5000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane Doe", "email": "jane@example.com"}'
Get all users:
curl http://localhost:5000/api/users

Prisma Commands

prisma generate

Generate Prisma Client after schema changes

prisma migrate dev

Create and apply database migrations

prisma studio

Open visual database editor in browser

prisma db push

Push schema changes without migrations

API Endpoints

The generated User API includes:
MethodEndpointDescription
POST/api/usersCreate a new user
GET/api/usersGet all users
GET/api/users/:idGet user by ID
PATCH/api/users/:idUpdate user by ID
DELETE/api/users/:idDelete user by ID

Next Steps

Add Relations

Extend your Prisma schema with relational models (Posts, Comments, etc.)

Add Authentication

Implement JWT or session-based authentication

Use Prisma Studio

Explore your data with npx prisma studio

Add Validation

Install Zod or express-validator for request validation

Working with Prisma Schema

Add more models to prisma/schema.prisma:
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  authorId  Int
  author    User     @relation(fields: [authorId], references: [id])
  createdAt DateTime @default(now())
}

model User {
  id        Int      @id @default(autoincrement())
  name      String
  email     String   @unique
  posts     Post[]   // Relation to Post
  createdAt DateTime @default(now())
}
After modifying the schema:
npx prisma generate
npx prisma migrate dev --name "add-posts"

Adding More Devark Modules

Enhance your project with additional Devark modules:
# Add authentication
devark module auth

# Add email functionality
devark module email

# Add file uploads
devark module upload

Customization Tips

  • Prisma Relations: Add relationships between models for complex data structures
  • Prisma Middleware: Add logging, soft deletes, or data transformation
  • Error Handling: Create custom error handler middleware
  • Validation: Use Prisma’s built-in validation or add Zod/Joi
  • Pagination: Implement cursor or offset-based pagination with Prisma
  • Seeding: Create prisma/seed.js to populate your database

Prisma Studio

Prisma Studio provides a visual interface to view and edit your data:
npx prisma studio
This opens a browser interface at http://localhost:5555 where you can:
  • Browse all tables and records
  • Create, update, and delete records
  • Filter and sort data
  • View relationships between models
Prisma automatically generates TypeScript types from your schema, providing full type safety and IntelliSense in your code editor.

Build docs developers (and LLMs) love