A modern monorepo containing a Next.js web application with Web3 wallet integration, Prisma database layer, and Haraka mail server.
blanc/
├── apps/
│ └── web/ # @blanc/web - Next.js application
│ ├── src/
│ ├── public/
│ └── package.json
├── packages/
│ ├── database/ # @blanc/database - Prisma ORM
│ │ ├── prisma/
│ │ │ └── schema.prisma
│ │ ├── src/
│ │ │ ├── client.ts # Singleton PrismaClient
│ │ │ └── index.ts # Exports
│ │ └── package.json
│ └── typescript-config/ # @blanc/typescript-config - Shared TS configs
│ ├── base.json
│ ├── nextjs.json
│ └── react.json
├── services/
│ └── haraka/ # @blanc/mail-server - Haraka SMTP
│ ├── config/
│ ├── plugins/
│ └── package.json
└── package.json # Root workspace
Required Software:
- Node.js 18+
- npm 10.9.2+
- PostgreSQL database (local or hosted via Prisma Postgres)
- Git
Required Services:
- Cloudflare account (for R2 storage and Workers deployment)
- WalletConnect project (for Web3 wallet integration)
Important: For detailed setup instructions including environment variables, Cloudflare R2 configuration, and troubleshooting, see apps/web/SETUP.md.
-
Clone and install
git clone <repository-url> cd blanc npm install
-
Configure environment
# Root database URL cp .env.example .env # Web app configuration cp apps/web/.env.example apps/web/.env.development
-
Set up database
# Generate Prisma Client npm run db:generate # Push schema to database (development) npm run db:push
-
Start development
npm run dev
Visit http://localhost:3000
npm run dev # Generate Prisma Client + start web app
npm run dev:web # Start web app only
npm run dev:mail # Start Haraka mail servernpm run build # Build web app for production
npm run deploy # Deploy web app to Cloudflare Workers
npm run preview # Preview Cloudflare deployment locallynpm run db:generate # Generate Prisma Client
npm run db:push # Push schema changes (development)
npm run db:migrate # Create and run migrations
npm run db:studio # Open Prisma Studio
npm run db:seed # Seed databasenpm run lint # Lint code
npm run lint:fix # Fix linting issues
npm run type-check # TypeScript type checking
npm run format # Format code with Prettier
npm run check # Run type-check + lintnpm run clean # Clean all workspaces
npm run clean:deep # Deep clean (all node_modules, build artifacts)Next.js 15 application with:
- Framework: App Router, React 19, Turbopack
- Deployment: Cloudflare Workers via OpenNext
- Web3: wagmi 2.x + viem for wallet integration
- UI: shadcn/ui components, Tailwind CSS v4
- State: TanStack Query
- Database: Integrated with
@blanc/database
Development:
cd apps/web
npm run dev # Start dev server
npm run build # Production build
npm run type-check # Type checking
npm run clean # Clean build artifactsPrisma ORM package with:
- Version: Prisma 6.x
- Database: PostgreSQL
- Extensions: Prisma Accelerate for connection pooling
- Output:
packages/database/generated/prisma(gitignored)
Exports:
import { prisma } from "@blanc/database"; // PrismaClient singleton
import type { User, Post } from "@blanc/database"; // Generated typesUsage in apps:
// Add to package.json dependencies
{
"dependencies": {
"@blanc/database": "*"
}
}
// Use in code
import { prisma } from "@blanc/database";
const users = await prisma.user.findMany();Scripts:
cd packages/database
npm run db:generate # Generate client
npm run db:push # Push schema
npm run db:migrate # Run migrations
npm run db:studio # Open StudioShared TypeScript configurations:
base.json- Base configurationnextjs.json- Next.js specific (extends base)react.json- React specific (extends base)
Usage:
{
"extends": "@blanc/typescript-config/nextjs.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}Haraka SMTP server with:
- Authentication: Wallet-based (custom plugin)
- Database: PostgreSQL via
@blanc/database - Encryption: PGP support
- Ports: 25 (SMTP), 587 (Submission), 465 (SMTPS)
Scripts:
cd services/haraka
npm run dev # Development mode
npm start # Production mode
npm run clean # Clean queue/logs- Install PostgreSQL
- Create database:
CREATE DATABASE blanc;
- Update
.env:DATABASE_URL="postgresql://user:password@localhost:5432/blanc"
- Sign up at https://console.prisma.io
- Create new database
- Copy connection string to
.env:DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=YOUR_API_KEY"
Edit packages/database/prisma/schema.prisma:
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
}After changes:
npm run db:generate # Regenerate client
npm run db:push # Apply to database# Database
DATABASE_URL="postgresql://user:password@localhost:5432/blanc"
# Cloudflare R2 Storage (shared with web app and Haraka)
R2_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID=your_r2_access_key_id
R2_SECRET_ACCESS_KEY=your_r2_secret_access_key
R2_BUCKET_NAME=mail-storage
R2_ACCOUNT_ID=your_cloudflare_account_id# Session Secret (minimum 32 characters)
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
SESSION_SECRET=your_64_character_session_secret
# WalletConnect (get from https://cloud.walletconnect.com)
NEXT_PUBLIC_WC_PROJECT_ID=your_project_id
# Cloudflare R2 Storage
R2_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID=your_r2_access_key_id
R2_SECRET_ACCESS_KEY=your_r2_secret_access_key
R2_BUCKET_NAME=mail-storage
R2_ACCOUNT_ID=your_cloudflare_account_idNote: For detailed setup instructions, see apps/web/SETUP.md.
To a specific workspace:
npm install <package> --workspace=@blanc/web
npm install -D <package> --workspace=@blanc/databaseTo root (shared dev tools):
npm install -D <package> -wPackages reference each other using workspace protocol:
{
"dependencies": {
"@blanc/database": "*",
"@blanc/typescript-config": "*"
}
}# From root
npm run dev --workspace=@blanc/web
# Or use shortcuts
npm run dev:web
npm run dev:mail-
Always generate Prisma Client first:
npm run db:generate
-
Use workspace dependencies:
- Reference other packages with
@blanc/* - Use
"*"version for workspace packages
- Reference other packages with
-
Run quality checks before committing:
npm run check # Type-check + lint npm run format # Format code
-
Clean when switching branches:
npm run clean
npm run deployRequirements:
- Cloudflare account with Workers
- Set environment variables:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_ID
Or use GitHub Actions:
- Workflow:
.github/workflows/deploy-app.yml - Triggers on push to main
- Create feature branch
- Make changes
- Run quality checks:
npm run check - Format code:
npm run format - Test locally
- Submit PR
All packages use the @blanc scope:
@blanc/web- Web application@blanc/database- Database/ORM layer@blanc/typescript-config- Shared TypeScript configs@blanc/mail-server- Mail server service
GNU General Public License v3.0