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:
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.
Create a .env file in the root directory by copying the example file:
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;
Create PostgreSQL Database
Create a new PostgreSQL database for the application:Or using psql:CREATE DATABASE eventpalour;
Generate Database Schema
Generate the database migrations from the schema:This reads the schema from ./lib/db/schema/ and creates migration files in the ./drizzle directory. Run Migrations
Apply the migrations to your database: Verify Setup (Optional)
Open Drizzle Studio to view your database: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:
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"
}
}
Development Mode
Starts the Next.js development server with Turbopack and hot reloading Build for Production
Creates an optimized production build Start Production Server
Runs the production server (after building)
EventPalour uses Biome for linting and formatting:
Linting
# Check for linting errors
pnpm lint
# Auto-fix linting errors
pnpm fix
# 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
Database connection errors
- 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
Environment variable issues
- 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:
Set Production Environment Variables
Configure all environment variables with production values
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