Skip to content

pro-nav/express-quickstarter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Express + TypeScript + Drizzle + Better Auth

A production-ready Express.js API with TypeScript, Drizzle ORM, and Better Auth for email/password authentication.

Features

  • ✅ Express.js with TypeScript
  • ✅ Drizzle ORM with PostgreSQL
  • ✅ Better Auth (email/password)
  • ✅ Cookie-based authentication
  • ✅ CORS enabled
  • ✅ Modular architecture
  • ✅ Input validation with Zod
  • ✅ Error handling middleware
  • ✅ Environment variable validation

Project Structure

src/
├── modules/
│   ├── auth/           # Authentication module
│   ├── user/           # User profile module
│   └── index.ts        # Module routes aggregator
├── shared/
│   ├── config/         # App configuration
│   └── middleware/     # Shared middleware
├── db/
│   ├── schema.ts       # Aggregate schemas
│   ├── migrations/     # Database migrations
│   └── seed.ts         # Seed script
├── app.ts              # Express app setup
└── server.ts           # Entry point

Setup Instructions

1. Install Dependencies

npm install

2. Setup Environment Variables

cp .env.example .env

Edit .env and fill in your values:

PORT=3000
NODE_ENV=development
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
BETTER_AUTH_SECRET=your-super-secret-key-min-32-chars-long
BETTER_AUTH_URL=http://localhost:3000
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000

Generate a secure secret:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

3. Setup PostgreSQL Database

Make sure PostgreSQL is running and create a database:

createdb mydb

Or using psql:

CREATE DATABASE mydb;

4. Generate and Run Migrations

# Generate migration files from schema
npm run db:generate

# Run migrations
npm run db:migrate

# Alternative: Push schema directly (dev only)
npm run db:push

5. Start Development Server

npm run dev

The server will start at http://localhost:3000

Available Scripts

Command Description
npm run dev Start development server with hot reload
npm run build Build for production
npm start Start production server
npm run db:generate Generate migration files
npm run db:migrate Run database migrations
npm run db:push Push schema directly (dev only)
npm run db:studio Open Drizzle Studio (database GUI)
npm run db:seed Run seed script

API Endpoints

Auth Routes (/api/auth)

Better Auth automatically provides these endpoints:

Method Endpoint Description
POST /api/auth/sign-up/email Register with email/password
POST /api/auth/sign-in/email Login with email/password
POST /api/auth/sign-out Logout
GET /api/auth/session Get current session
GET /api/auth/me Get current user (custom)

User Routes (/api/users)

Method Endpoint Description Auth
GET /api/users/profile Get user profile
POST /api/users/profile Create profile
PATCH /api/users/profile Update profile
DELETE /api/users/profile Delete profile

Authentication Flow

1. Sign Up

curl -X POST http://localhost:3000/api/auth/sign-up/email \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "SecurePass123!",
    "name": "John Doe"
  }'

2. Sign In

curl -X POST http://localhost:3000/api/auth/sign-in/email \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{
    "email": "user@example.com",
    "password": "SecurePass123!"
  }'

3. Access Protected Route

curl -X GET http://localhost:3000/api/users/profile \
  -b cookies.txt

4. Sign Out

curl -X POST http://localhost:3000/api/auth/sign-out \
  -b cookies.txt

Frontend Integration

React Example with Better Auth Client

npm install better-auth @better-auth/react
// lib/auth.ts
import { createAuthClient } from 'better-auth/react';

export const authClient = createAuthClient({
  baseURL: 'http://localhost:3000',
});

export const { signIn, signUp, signOut, useSession } = authClient;
// components/Login.tsx
import { signIn } from '@/lib/auth';

function Login() {
  const handleLogin = async (e) => {
    e.preventDefault();
    await signIn.email({
      email: 'user@example.com',
      password: 'password123',
    });
  };

  return <form onSubmit={handleLogin}>...</form>;
}

Adding New Modules

  1. Create module folder: src/modules/post/
  2. Add files:
    • post.schema.ts - Drizzle schema
    • post.repository.ts - Database queries
    • post.service.ts - Business logic
    • post.controller.ts - Request handlers
    • post.routes.ts - Route definitions
    • post.validation.ts - Zod schemas
  3. Export schema in src/db/schema.ts
  4. Register routes in src/modules/index.ts

Database Schema

The project includes these tables:

  • user - Better Auth user table
  • session - User sessions
  • account - OAuth/password accounts
  • verification - Email verification tokens
  • user_profile - Extended user profiles

Environment Variables

Variable Description Required
PORT Server port No (default: 3000)
NODE_ENV Environment No (default: development)
DATABASE_URL PostgreSQL connection string Yes
BETTER_AUTH_SECRET Auth secret (min 32 chars) Yes
BETTER_AUTH_URL Base URL of your app Yes
ALLOWED_ORIGINS CORS allowed origins (comma-separated) No

Production Deployment

  1. Build the project:
npm run build
  1. Set environment variables in your hosting platform

  2. Run migrations:

npm run db:migrate
  1. Start the server:
npm start

License

MIT

About

Production-ready Express.js + TypeScript starter with Drizzle ORM, PostgreSQL, Better Auth (email/password), Zod validation, and modular architecture

Topics

Resources

Stars

Watchers

Forks

Contributors