Stop Writing Auth From Scratch — One Command Does It All in NestJS

Stop Writing Auth From Scratch — One Command Does It All in NestJS

1 1 6
calendar_todayschedule5 min read

The problem every NestJS developer faces on day one

You open a fresh NestJS project.

You know what comes next.

Before you write a single line of business logic, you need to build:

  • User registration and login
  • Password hashing with bcrypt
  • JWT access and refresh tokens
  • Guards and decorators
  • Password reset flow
  • Email verification
  • Maybe OAuth (Google, GitHub...)
  • Maybe 2FA
  • Maybe RBAC
  • A User entity for your ORM
  • Docker Compose for your database
  • Environment variables
  • Swagger documentation

You have done this before. Multiple times. On every project.
It takes days. Sometimes a week.
And it is the same code every single time.


There is a better way

cd your-nestjs-project
npx @mehdijony/nestjs-user-service init

Answer a few questions. Done.

You get a complete, production-ready authentication and user management
system — installed directly into your existing NestJS project in under
5 minutes.

No boilerplate copying. No Stack Overflow rabbit holes.
No "why is my JWT strategy not working at 2am" sessions.


What exactly gets generated?

Let me be specific, because "complete auth system" is a phrase that
gets thrown around a lot.

Here is what you actually get:

Auth Module

  • Email + password registration and login
  • Email OTP (passwordless)
  • Magic link (passwordless)
  • Mobile OTP via SMS
  • OAuth: Google, GitHub, Facebook, Apple, Twitter, LinkedIn, Discord
  • Enterprise: LDAP (Active Directory) and SAML SSO
  • API key authentication
  • JWT access tokens + refresh tokens
  • Automatic token refresh endpoint
  • Password reset (forgot password flow)

Security Layer

  • bcrypt password hashing (rounds: 12)
  • Two-factor authentication (TOTP) with QR code
  • Rate limiting per IP with @nestjs/throttler
  • Account lockout after failed attempts
  • Password strength validator (custom class-validator decorator)
  • Password history (prevent reuse)
  • RBAC with roles and fine-grained permissions
  • Device and session management

User Module

  • Full CRUD with pagination
  • GET /users/me (current user profile)
  • Safe responses (password never exposed)
  • @CurrentUser() decorator for controllers

Infrastructure

  • Redis caching
  • BullMQ / RabbitMQ / Kafka queues
  • Email: Nodemailer, SendGrid, AWS SES, Resend, Postmark
  • SMS: Twilio, Vonage, AWS SNS, MSG91
  • File upload: AWS S3, Google Cloud Storage, Cloudinary, local

DevOps

  • Docker Compose with all required services
  • Environment variables auto-generated
  • Health check endpoint
  • Swagger / OpenAPI docs at /api/docs
  • GitHub Actions / GitLab CI pipeline

Which ORMs and databases does it support?

Database ORM options
PostgreSQL Prisma, TypeORM, Drizzle, MikroORM
MySQL Prisma, TypeORM, Drizzle
SQLite Prisma, TypeORM
SQL Server TypeORM
MongoDB Mongoose, Prisma

You pick the combination. It generates the right schema,
entities, and connection config for your choice.


How does it work with an existing project?

This is the part that makes it different from other generators.

Most generators create a new project. This one installs into what you
already have.

When you run npx @mehdijony/nestjs-user-service init inside your
existing NestJS project, it:

1. Detects your project

 Detected Project Info:
────────────────────────────────────────
  NestJS Version:   10.3.2
  Package Manager:  pnpm
  Source Path:      /your-project/src
  Has Docker:       Yes
  Has Prisma:       Yes
  Has TypeORM:      No
  Has Mongoose:     No
  Has .env:         Yes
────────────────────────────────────────

It detects your package manager, NestJS version, which ORMs you
already have, whether Docker is configured, and whether you have
a .env file.

2. Asks your preferences

Interactive prompts let you choose exactly what you want.
Already have Prisma? It will default to that.
Already have Docker? It will append to your existing docker-compose.yml.
Already have .env? It will only add new keys, never overwrite.

3. Creates a restore point BEFORE touching anything

This is critical. Before the installer modifies a single file,
it backs up:

  • Your app.module.ts
  • Your .env
  • Your docker-compose.yml
  • Your prisma/schema.prisma

And records every file it will create and every package it will add.

4. Installs everything

Packages go into YOUR project (not a separate directory).
Files go into src/user-service/.
UserServiceModule gets injected into your AppModule automatically.

5. If anything fails — it auto-rolls back

The installer wraps everything in try/catch. If step 6 fails,
steps 1-5 are automatically undone.

And if you decide later you want to remove it:

npx @mehdijony/nestjs-user-service rollback

That command:

  • Deletes all generated files
  • Uninstalls all added packages
  • Restores your original app.module.ts, .env, docker-compose.yml
  • Removes the backup directory

Your project is exactly as it was before.


Let me show you the actual output

After running init with PostgreSQL + Prisma + email/password +
Google OAuth + Swagger selected, here is what your project gets:

src/user-service/
├── user-service.module.ts
├── auth/
│   ├── auth.module.ts
│   ├── auth.service.ts
│   ├── auth.controller.ts
│   ├── guards/
│   │   └── jwt-auth.guard.ts
│   ├── strategies/
│   │   ├── jwt.strategy.ts
│   │   └── google.strategy.ts
│   └── decorators/
│       └── current-user.decorator.ts
└── user/
    ├── user.module.ts
    ├── user.service.ts
    └── user.controller.ts

Your app.module.ts gets this injected automatically:

import { UserServiceModule } from './user-service/user-service.module';

@Module({
  imports: [
    UserServiceModule,  // ← added automatically
    // ... your existing modules
  ],
})
export class AppModule {}

Your .env gets these appended:

# ─── USER SERVICE ───
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb
JWT_SECRET=change-this-to-a-secure-secret-minimum-32-characters
JWT_ACCESS_EXPIRATION=15m
JWT_REFRESH_EXPIRATION=7d
APP_URL=http://localhost:3000
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CALLBACK_URL=http://localhost:3000/api/v1/auth/google/callback

Your prisma/schema.prisma gets the User model added:

model User {
  id         Int      @id @default(autoincrement())
  email      String?  @unique
  phone      String?  @unique
  password   String?
  firstName  String?
  lastName   String?
  avatar     String?
  isActive   Boolean  @default(true)
  isVerified Boolean  @default(false)
  provider   String?  @default("local")
  providerId String?
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  @@map("users")
}

Then you run:

npx prisma generate
npx prisma db push
npm run start:dev

And your API is live at http://localhost:3000/api/v1 with Swagger
at http://localhost:3000/api/docs.


The API endpoints you get

POST   /api/v1/auth/register
POST   /api/v1/auth/login
POST   /api/v1/auth/refresh
POST   /api/v1/auth/logout
POST   /api/v1/auth/forgot-password
POST   /api/v1/auth/reset-password
GET    /api/v1/auth/google
GET    /api/v1/auth/google/callback
POST   /api/v1/auth/email/otp/send
POST   /api/v1/auth/email/otp/verify
POST   /api/v1/auth/magic-link/send
GET    /api/v1/auth/magic-link/verify
GET    /api/v1/users
GET    /api/v1/users/me
GET    /api/v1/users/:id
PATCH  /api/v1/users/:id
DELETE /api/v1/users/:id

All behind JWT guards where appropriate.
All documented in Swagger.
All returning a consistent response format:

{
  "success": true,
  "data": { ... },
  "timestamp": "2024-01-15T10:30:00.000Z"
}

Who is this for?

Solo developers and small teams who need to ship fast without
cutting corners on security.

Agencies who build multiple NestJS apps and are tired of copy-pasting
auth boilerplate between projects.

Startups who need a working MVP yesterday and can not afford to spend
a week on authentication infrastructure.

Senior developers who know how auth should be built and want it
generated correctly rather than written from scratch again.


Who is this NOT for?

If you have very specific, non-standard auth requirements that do not
fit any of the options (custom token format, exotic identity providers,
proprietary session stores), this might not cover your edge case —
though you can still use it as a starting point and modify the
generated code.

Get started


# In your existing NestJS project:
npx @mehdijony/nestjs-user-service init
# Or create a brand new project:
npx @mehdijony/nestjs-user-service init my-app
cd my-app

GitHub: https://github.com/mehdijony/nestjs-user-service
npm: https://www.npmjs.com/package/@mehdijony/nestjs-user-service


If this saves you time, star the repo and share it with your team.
Every developer who has built auth from scratch three times
deserves to know this exists.


3 Comments

2 votes
2 votes
2 votes
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

What Is SARIF and How Does It Help Security Tools Work Together?

Ganesh Kumar - Jul 4

Building Secure JWT Auth in NestJS: Argon2, Redis Blacklisting, and Token Rotation

David Essien - Jan 18

Your AI Doesn't Just Write Tests. It Runs Them Too.

Kevin Martinez - May 12

Starting From Scratch

MasterCraft - Feb 18

Stop Implementing Authentication Inside Containers on Kubernetes

Alexandre Vazquez - Jul 25
chevron_left
179 Points8 Badges
Hefei, Anhui, Chinamehdihassanjony.vercel.com
2Posts
0Comments
2Connections
404 error

Related Jobs

Commenters (This Week)

1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!