Skip to main content

Prerequisites

Before you begin, ensure you have the following installed on your machine:

Node.js

Version 20 or higher

pnpm

Version 9 or higher (recommended package manager)

PostgreSQL

Version 14 or higher

Git

For cloning the repository
You can use npm or yarn instead of pnpm, but pnpm is recommended for better performance and disk space efficiency.

Step 1: Clone the Repository

Clone the EventPalour repository to your local machine:
git clone https://github.com/your-org/eventpalour.git
cd eventpalour

Step 2: Install Dependencies

Install all required dependencies using pnpm:
pnpm install

Key Dependencies

EventPalour uses the following major packages:
// From package.json
{
  "dependencies": {
    "next": "16.1.6",
    "react": "19.2.4",
    "react-dom": "19.2.4",
    "drizzle-orm": "^0.44.5",
    "postgres": "^3.4.7",
    "@paystack/inline-js": "^2.22.7",
    "arctic": "^3.7.0",
    "@node-rs/argon2": "^2.0.2",
    "zod": "^4.1.8",
    "@tanstack/react-query": "^5.90.2",
    "tailwindcss": "^4"
  },
  "devDependencies": {
    "typescript": "^5",
    "drizzle-kit": "^0.31.4",
    "@biomejs/biome": "^2.3.6"
  }
}
EventPalour uses Next.js 16 with the App Router, React Server Components, and Turbopack for fast development builds.

Step 3: Configure Environment Variables

Create a .env file in the root directory by copying the example file:
cp .env.example .env

Required Environment Variables

Edit the .env file and configure the following variables:
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/eventpalour"
DIRECT_URL="postgresql://user:password@localhost:5432/eventpalour"
Security Best Practices
  • Never commit your .env file to version control
  • Use different keys for development and production
  • Rotate secrets regularly
  • Use strong, randomly generated values for sensitive keys

Environment Variables Reference

From the .env.example file:
# Database
DATABASE_URL=
DIRECT_URL=

# Supabase
SUPABASE_SERVICE_ROLE_KEY=

# Paystack
PAYSTACK_PUBLIC_KEY=
PAYSTACK_SECRET_KEY=

# Upstash & QStash
UPSTASH_URL=
UPSTASH_TOKEN=
QSTASH_URL=
QSTASH_TOKEN=
QSTASH_CURRENT_SIGNING_KEY=
QSTASH_NEXT_SIGNING_KEY=

# OAuth (Optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GOOGLE_CALLBACK_URL=

# Email Configuration
RESEND_API_KEY=
EMAIL_FROM=
EMAIL_SERVER_HOST=
EMAIL_SERVER_PORT=
EMAIL_SERVER_USER=
EMAIL_SERVER_PASSWORD=
EMAIL_FROM_SUPPORT=
EMAIL_FROM_TICKETS=
EMAIL_FROM_BILLING=
EMAIL_FROM_NOTIFICATIONS=
EMAIL_FROM_SUPPORT_NAME=
EMAIL_FROM_TICKETS_NAME=
EMAIL_FROM_BILLING_NAME=
EMAIL_FROM_NOTIFICATIONS_NAME=

Step 4: Set Up the Database

EventPalour uses PostgreSQL with Drizzle ORM for database management.

Database Configuration

The Drizzle configuration is defined in drizzle.config.ts:
import "dotenv/config";
import type { Config } from "drizzle-kit";
import { env } from "@/env/server";

export default {
  out: "./drizzle",
  schema: "./lib/db/schema/index.ts",
  breakpoints: true,
  verbose: true,
  strict: true,
  dialect: "postgresql",
  casing: "snake_case",
  dbCredentials: {
    url: env.DATABASE_URL,
  },
} satisfies Config;
1

Create PostgreSQL Database

Create a new PostgreSQL database for the application:
createdb eventpalour
Or using psql:
CREATE DATABASE eventpalour;
2

Generate Database Schema

Generate the database migrations from the schema:
pnpm db:generate
This reads the schema from ./lib/db/schema/ and creates migration files in the ./drizzle directory.
3

Run Migrations

Apply the migrations to your database:
pnpm db:migrate
4

Verify Setup (Optional)

Open Drizzle Studio to view your database:
pnpm db:studio
This will open a web interface at https://local.drizzle.studio

Database Schema Overview

EventPalour’s database schema includes the following main tables:
// lib/db/schema/user.ts
export const user = pgTable("user", {
  id: varchar("id", { length: 16 }).primaryKey(),
  email: varchar("email", { length: 255 }).notNull().unique(),
  username: varchar("username", { length: 255 }).notNull(),
  avatar: text("avatar").notNull(),
  password: text("password"),
  email_verified: boolean("email_verified").notNull().default(false),
  registered_2fa: boolean("registered_2fa").notNull().default(false),
  platform_role: platform_role_enum("platform_role"),
});

export const session = pgTable("session", {
  id: varchar("id", { length: 255 }).primaryKey(),
  user_id: varchar("user_id", { length: 16 }).notNull(),
  two_factor_verified: boolean("two_factor_verified").notNull().default(false),
  ip_address: varchar("ip_address", { length: 100 }),
  expires_at: timestamp("expires_at", { withTimezone: true }).notNull(),
});

Available Database Commands

// From package.json
{
  "scripts": {
    "db:generate": "drizzle-kit generate",
    "db:migrate": "drizzle-kit migrate",
    "db:studio": "drizzle-kit studio",
    "db:clear": "tsx ./lib/db/clear.ts",
    "db:view": "concurrently \"pnpm drizzle-kit studio\" \"pnpm dlx drizzle-lab visualizer\" \"sleep 1 && pnpm dlx drizzle-view\""
  }
}
Database Naming ConventionEventPalour uses snake_case for all database columns and tables as configured in drizzle.config.ts.

Step 5: Start the Development Server

Run the development server with Turbopack:
pnpm dev
The application will be available at http://localhost:3000.

Development Scripts

// From package.json
{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build --turbopack",
    "start": "next start",
    "lint": "biome check",
    "fix": "biome check --write",
    "format": "biome format --write"
  }
}
1

Development Mode

pnpm dev
Starts the Next.js development server with Turbopack and hot reloading
2

Build for Production

pnpm build
Creates an optimized production build
3

Start Production Server

pnpm start
Runs the production server (after building)

Step 6: Code Quality Tools

EventPalour uses Biome for linting and formatting:

Linting

# Check for linting errors
pnpm lint

# Auto-fix linting errors
pnpm fix

Formatting

# Format code
pnpm format

Git Hooks

EventPalour uses Husky for pre-commit hooks:
// From package.json
{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,json,jsonc,css,scss,md,mdx}": [
      "pnpm dlx ultracite fix"
    ]
  }
}
Code is automatically formatted on commit using lint-staged and Husky.

Next.js Configuration

EventPalour uses advanced Next.js 16 features:
// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  typedRoutes: true,
  cacheComponents: true, // Enables PPR with Cache Components
  reactCompiler: true,
  compiler: {
    removeConsole: process.env.NODE_ENV === "production",
  },
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "fgaiynraasujxieineag.supabase.co",
        port: "",
        pathname: "/storage/v1/object/public/**",
      },
      {
        protocol: "https",
        hostname: "lh3.googleusercontent.com",
      },
      {
        protocol: "https",
        hostname: "avatars.githubusercontent.com",
      },
    ],
  },
  serverExternalPackages: ["@node-rs/argon2"],
};

export default nextConfig;
The React Compiler is enabled for automatic optimization. Cache Components enables Partial Prerendering (PPR).

Project Structure

eventpalour/
├── app/                      # Next.js App Router
│   ├── (auth)/              # Authentication routes
│   │   └── auth/
│   │       ├── sign-in/
│   │       ├── sign-up/
│   │       ├── verify-email/
│   │       └── onboarding/
│   ├── api/                 # API routes
│   ├── dashboard/           # User dashboard
│   ├── workspace/           # Workspace pages
│   │   └── [workspaceId]/
│   │       ├── events/
│   │       └── create/
│   └── actions/             # Server actions
├── components/              # React components
│   ├── ui/                  # UI components
│   └── common/              # Shared components
├── lib/                     # Libraries and utilities
│   ├── db/                  # Database
│   │   └── schema/          # Drizzle schemas
│   ├── auth/                # Authentication utilities
│   ├── server/              # Server utilities
│   └── utils/               # Helper functions
├── drizzle/                 # Database migrations
├── public/                  # Static assets
└── package.json             # Dependencies

Troubleshooting

  • Verify PostgreSQL is running: pg_isready
  • Check your DATABASE_URL in .env
  • Ensure the database exists: psql -l
  • Try connecting manually: psql -d eventpalour
  • Delete node_modules and reinstall: rm -rf node_modules && pnpm install
  • Clear Next.js cache: rm -rf .next
  • Ensure all dependencies are installed
  • Restart the development server after changing .env
  • Verify all required variables are set
  • Check for typos in variable names
  • Ensure no trailing spaces in values
  • Check database credentials
  • Ensure PostgreSQL version compatibility (14+)
  • Clear the drizzle folder and regenerate: rm -rf drizzle && pnpm db:generate
  • Check for schema syntax errors
  • Verify callback URLs match your OAuth provider settings
  • Ensure client ID and secret are correct
  • Check redirect URIs in provider console
  • For local development, use http://localhost:3000 not https

Development Tips

Hot Reloading

Turbopack provides instant hot reloading. Changes appear immediately without full page refresh.

Type Safety

TypeScript and Drizzle ORM ensure type safety across the stack.

Server Actions

Use Next.js Server Actions for data mutations. See files in app/actions/.

Database Studio

Use pnpm db:studio to visually explore and edit your database.

Production Deployment

For production deployment:
1

Set Production Environment Variables

Configure all environment variables with production values
2

Run Database Migrations

pnpm db:migrate
3

Build the Application

pnpm build
4

Start Production Server

pnpm start
Always use strong, unique secrets in production. Never use development credentials in production environments.

Next Steps

Create Your First Event

Follow the quickstart guide to create your first event

Explore the API

Learn about available API endpoints and server actions

Authentication

Understand the authentication system

Core Concepts

Explore workspaces, events, and tickets

Build docs developers (and LLMs) love