Setup & Installation
Everything you need to install, configure, and deploy PropertyPro — from your first pnpm install to a custom domain on production.
Overview
PropertyPro is a complete property management application built with Next.js 16, React 19, and MongoDB. This documentation covers everything from your first install to deploying in production.
Read sectionQuickstart
If you're already comfortable with Node, pnpm, and MongoDB, this is the express path. Each step is expanded later in the docs.
Read sectionRequirements
PropertyPro runs anywhere Node.js does. These versions are tested in CI — older versions may work but aren't supported.
Read sectionDownload & Setup
Download from CodeCanyon, unzip, and install. PropertyPro ships as a ready-to-run Next.js project — no build steps required to start dev.
Read sectionPropertyPro is a complete property management application built with Next.js 16, React 19, and MongoDB. This documentation covers everything from your first install to deploying in production.
What's in the package
Full source code, database schema, seed data, and a self-contained PWA-ready Next.js app.
License
One regular license per end product. Lifetime updates within the same major version.
Stack
Next.js 16, React 19 + Compiler, TypeScript, Tailwind CSS v4, MongoDB, Stripe.
Support
6 months of buyer support included. Renewable from your CodeCanyon account.
Looking for end-user docs?
If you're configuring tenants, leases, and day-to-day workflows, head to the User Manual instead.
If you're already comfortable with Node, pnpm, and MongoDB, this is the express path. Each step is expanded later in the docs.
- 1
Install dependencies
From the unzipped folder, install all packages with pnpm.
bashcd propertypro pnpm install - 2
Copy env file
Duplicate the example env and fill in your database, Stripe, and SMTP credentials.
bashcp .env.example .env.local - 3
Connect MongoDB & seed
Set MONGODB_URI, then load demo data so you can log in immediately.
bashpnpm db:seed - 4
Start the dev server
Open http://localhost:3000 — the demo admin is admin@propertypro.app / admin1234.
bashpnpm dev
PropertyPro runs anywhere Node.js does. These versions are tested in CI — older versions may work but aren't supported.
Node.js 20.11+
Use 20 LTS or 22. We do not support Node 18 due to React Compiler dependencies.
pnpm 9+
Required. Install with corepack enable && corepack prepare pnpm@latest --activate.
MongoDB 6+
MongoDB Atlas is recommended. Self-hosted MongoDB works when MONGODB_URI points to your server.
Object storage
Cloudflare R2 stores property photos, tenant documents, and uploaded files.
Hosting suggestion
For most buyers, Vercel + MongoDB Atlas is the fastest path. The full deploy guide covers VPS and Docker too.
Download from CodeCanyon, unzip, and install. PropertyPro ships as a ready-to-run Next.js project — no build steps required to start dev.
- 1
Download from CodeCanyon
Sign in to CodeCanyon → Downloads → PropertyPro. Choose 'All files & documentation'.
- 2
Unzip the package
Extract the archive to a permanent location. The main folder is /propertypro.
bashunzip propertypro-v2.0.0.zip -d ~/projects/ cd ~/projects/propertypro - 3
Install dependencies
We use pnpm for fast, deterministic installs. Run this once after every download or update.
bashpnpm install - 4
Verify the install
A quick smoke test confirms everything resolved correctly.
bashpnpm typecheck pnpm lint
Don't use npm or yarn
The lockfile is pnpm-only. Mixing package managers will corrupt resolutions — stick to pnpm.
All secrets live in .env.local. The included .env.example documents every key. Below is a complete MongoDB-ready example.
# Database Configuration (MongoDB Atlas)
MONGODB_URI=mongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro
# Self-Hosted MongoDB
# MONGODB_URI=mongodb://mongo:password@your_ip_address:27017/propertypro
# MONGODB_DB=propertypro
# NextAuth Configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-nextauth-secret
AUTH_TRUST_HOST=true
AUTH_URL=http://localhost:3000
# Cloudflare R2 (Replace with your actual keys from https://dash.cloudflare.com)
R2_ACCOUNT_ID=your-r2-account-id
R2_ACCESS_KEY_ID=your-r2-access-key-id
R2_SECRET_ACCESS_KEY=your-r2-secret-access-key
R2_BUCKET_NAME=your-r2-bucket-name
R2_PUBLIC_URL=https://your-custom-domain.com
NEXT_PUBLIC_R2_PUBLIC_URL=https://your-custom-domain.com
# Stripe
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Email (SMTP)
EMAIL_SERVER_HOST=smtp.gmail.com
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=your-email@gmail.com
EMAIL_SERVER_PASSWORD=your-email-password
EMAIL_FROM=your-email@gmail.com
# File Upload Configuration
UPLOAD_MAX_SIZE=10485760
UPLOAD_ALLOWED_TYPES=image/jpeg,image/png,image/webp,application/pdf
# Application Configuration (optional)
APP_NAME=propertypro
APP_URL=http://localhost:3000
SUPPORT_EMAIL=support@propertypro.com
# Web Push (VAPID)
NEXT_PUBLIC_VAPID_PUBLIC_KEY=your-vapid-public-key
VAPID_PRIVATE_KEY=...
VAPID_SUBJECT=mailto:admin@propertypro.app| Key | Required | Description |
|---|---|---|
MONGODB_URI | Required | MongoDB Atlas or self-hosted MongoDB connection string for the PropertyPro database. |
MONGODB_DB | Optional | Database name override. Useful when your connection string does not include /propertypro. |
NEXTAUTH_SECRET | Required | Random secret used to sign auth sessions. Never commit this. |
NEXTAUTH_URL / AUTH_URL | Required | Public URL of your deployment, used in emails, callbacks, and auth redirects. |
R2_ACCOUNT_ID | Required | Cloudflare account ID used to build the R2 S3 endpoint. |
R2_ACCESS_KEY_ID | Required | Access Key ID from a Cloudflare R2 API token with object read/write access. |
R2_SECRET_ACCESS_KEY | Required | Secret Access Key for the same R2 API token. Store it once; Cloudflare does not show it again. |
R2_BUCKET_NAME | Required | Name of the bucket that stores uploaded property photos and documents. |
R2_PUBLIC_URL / NEXT_PUBLIC_R2_PUBLIC_URL | Required | Public origin for reading uploaded files, either a production custom domain or a development r2.dev URL. |
STRIPE_SECRET_KEY | Required | Server-side Stripe key. Use test keys in development. |
STRIPE_WEBHOOK_SECRET | Required | Signing secret for the /api/webhooks/stripe endpoint. |
EMAIL_SERVER_* | Required | Outbound email credentials for invites, receipts, and reminders. |
VAPID_* | Optional | Required only if you want web push notifications. Generate with npx web-push generate-vapid-keys. |
UPLOAD_* | Optional | Upload size and MIME type limits for images, WebP files, and PDFs. |
Generate NEXTAUTH_SECRET fast
Run openssl rand -base64 32 in your terminal and paste the output as the value.
PropertyPro stores application data in MongoDB. Create a MongoDB Atlas cluster or self-hosted database, then point MONGODB_URI at it before starting the app.
- 1
Create a MongoDB database
Create a MongoDB Atlas cluster and database named propertypro, or prepare a self-hosted MongoDB instance.
bash# MongoDB Atlas example MONGODB_URI=mongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro - 2
Allow network access
In MongoDB Atlas, add your local IP address for development and your hosting provider's outbound IPs for production.
txtAtlas → Network Access → Add IP Address - 3
Seed demo data (optional)
Loads two demo properties, ten units, three tenants, and an admin account so you can explore immediately.
bashpnpm db:seed - 4
Inspect with MongoDB Compass
Use MongoDB Compass or the Atlas Data Explorer to browse collections and verify seeded records.
txtmongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro
Production: skip the seed
Never run pnpm db:seed against a live database — it inserts demo records and accounts intended for evaluation.
Two scripts cover 99% of dev work: dev and build. The PWA service worker is disabled in dev to keep iteration fast.
- 1
Start in development
Hot-reload, fast refresh, and source maps. Defaults to port 3000.
bashpnpm dev - 2
Run a production build
Compiles, treeshakes, and runs Next.js production server. Use this to validate before deploying.
bashpnpm build pnpm start - 3
Sign in with the demo admin
If you ran the seed, an admin account exists out of the box.
txtEmail: admin@propertypro.app Password: admin1234
Change the demo password
First action in production: log in, open Settings → Profile, and rotate the seeded password.
PropertyPro uses Cloudflare R2 for property images, tenant documents, and other uploaded files. Configure one private write path through R2 API credentials and one public read URL for displaying saved files.
- 1
Create an R2 bucket
In Cloudflare, open Storage & databases -> R2 and create a bucket for PropertyPro uploads. Use a lowercase bucket name with numbers and hyphens only, then place that exact bucket name in R2_BUCKET_NAME.
bashR2_BUCKET_NAME=your-r2-bucket-name - 2
Create a scoped R2 API token
From the R2 overview, open Manage API Tokens, create an API token with Object Read & Write permission, and scope it to the PropertyPro bucket. Copy the Access Key ID, Secret Access Key, and account ID before leaving the confirmation screen.
bashR2_ACCOUNT_ID=your-r2-account-id R2_ACCESS_KEY_ID=your-r2-access-key-id R2_SECRET_ACCESS_KEY=your-r2-secret-access-key R2_BUCKET_NAME=your-r2-bucket-name - 3
Enable public file delivery
For production, connect a custom domain such as assets.yourdomain.com to the bucket. For local testing only, you may enable the Cloudflare-managed r2.dev public development URL. Set both public URL variables to the exact origin with no trailing slash.
bash# Production custom domain R2_PUBLIC_URL=https://your-custom-domain.com NEXT_PUBLIC_R2_PUBLIC_URL=https://your-custom-domain.com # Local or staging with R2 public development URL # R2_PUBLIC_URL=https://pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.dev # NEXT_PUBLIC_R2_PUBLIC_URL=https://pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.dev - 4
Allow the image host in Next.js
The bundled next.config.ts already allows r2.dev and r2.cloudflarestorage.com image hosts. If you use a custom R2 domain and render uploaded images through next/image, add that hostname to images.remotePatterns, then rebuild.
next.config.tstsimages: { remotePatterns: [ { protocol: "https", hostname: "assets.yourdomain.com", port: "", pathname: "/**", search: "", }, ], } - 5
Verify uploads
Restart the app after changing environment variables, upload a property image or tenant document, then open the saved file URL. If the upload succeeds but previews fail, check the public bucket URL and image remote pattern first.
https://<ACCOUNT_ID>.r2.cloudflarestorage.comKeep write credentials server-only
Never expose R2_ACCESS_KEY_ID or R2_SECRET_ACCESS_KEY in NEXT_PUBLIC_* variables. Only NEXT_PUBLIC_R2_PUBLIC_URL should be readable by the browser.
Use custom domains in production
Cloudflare's r2.dev public development URLs are intended for non-production traffic. A custom domain gives you normal Cloudflare cache, access control, WAF, and bot-management options.
PropertyPro uses Stripe Checkout for one-time invoices and Stripe Customer Portal for tenant self-service. Both work with test keys out of the box.
- 1
Get your API keys
Stripe Dashboard → Developers → API keys. Copy the secret and publishable keys into .env.local.
- 2
Create a webhook endpoint
Point Stripe at /api/webhooks/stripe on your deployed URL. Subscribe to checkout.session.completed and invoice.payment_succeeded.
bash# Webhook URL https://yourdomain.com/api/webhooks/stripe - 3
Test webhooks locally
Use the Stripe CLI to forward events to your dev server while developing.
bashstripe listen --forward-to localhost:3000/api/webhooks/stripe - 4
Switch to live mode
When ready, swap test keys (sk_test_*, pk_test_*) for live keys (sk_live_*, pk_live_*) and re-create the webhook in live mode.
Lease reminders, payment receipts, password resets, and tenant invites all go through one SMTP transport. We've tested Resend, SendGrid, Postmark, and standard SMTP servers.
Resend (recommended)
Easiest for new buyers. Free tier covers most small portfolios. EMAIL_SERVER_HOST=smtp.resend.com, EMAIL_SERVER_USER=resend.
SendGrid
Higher limits and better deliverability for large portfolios. EMAIL_SERVER_HOST=smtp.sendgrid.net.
Postmark
Best for transactional-only email. EMAIL_SERVER_HOST=smtp.postmarkapp.com.
Gmail / generic SMTP
Works for testing but rate-limited. Not recommended for production.
Verify your sender domain
Always set up SPF, DKIM, and DMARC for EMAIL_FROM's domain — without it, emails land in spam.
Push notifications use the Web Push API with VAPID keys. Tenants and admins get instant alerts for payments, requests, and chats.
- 1
Generate VAPID keys
Run the bundled generator. Copy both keys into .env.local.
bashpnpm gen:vapid - 2
Set NEXT_PUBLIC_VAPID_PUBLIC_KEY
The client uses this public key to subscribe browsers to the push service.
- 3
Set VAPID_PRIVATE_KEY
The server uses this to sign push payloads. Never expose it to the browser.
- 4
Test from the dashboard
Sign in, allow notifications when prompted, then go to Settings → Notifications → Send test.
All brand assets live under /public and the color palette is defined as Tailwind CSS variables. No code changes required for a basic rebrand.
- 1
Replace the logo
Drop your SVG logo at /public/logo.svg. The dashboard reads from this path automatically.
- 2
Update the favicon & PWA icons
Replace /public/favicon.ico and the icons under /public/icons/ (sizes 192, 256, 384, 512).
- 3
Tweak brand colors
Edit the --brand-* tokens in app/globals.css. Tailwind picks them up across the app.
app/globals.csscss:root { --brand-50: oklch(0.97 0.02 230); --brand-500: oklch(0.62 0.18 230); --brand-700: oklch(0.45 0.18 230); } - 4
Update site metadata
Edit app/layout.tsx to change the default title, description, and OG image.
PropertyPro ships with English, Arabic, French, Spanish, and Bengali. Locales live as JSON files under /messages and are loaded with next-intl.
- 1
Edit existing strings
Open /messages/<locale>.json and edit values directly. Changes hot-reload in dev.
- 2
Add a new language
Copy /messages/en.json to /messages/<your-locale>.json and translate values. Then register it in lib/i18n.ts.
lib/i18n.tstsexport const locales = ["en", "ar", "fr", "es", "bn", "de"] as const; export const defaultLocale = "en"; - 3
RTL support
Arabic is enabled by default and switches the layout direction automatically. Add other RTL locales in lib/i18n.ts → rtlLocales.
Vercel is the fastest path to production. The whole flow takes under 10 minutes once your environment variables are ready.
- 1
Push to a GitHub repo
Create a private GitHub repo and push the source. Vercel will pull from it.
bashgit init git add . git commit -m "Initial PropertyPro setup" git remote add origin git@github.com:you/propertypro.git git push -u origin main - 2
Import the repo into Vercel
vercel.com → New Project → Import. Vercel auto-detects Next.js — no build config needed.
- 3
Add environment variables
Project Settings → Environment Variables. Paste every key from your .env.local. Set APP_URL, NEXTAUTH_URL, and AUTH_URL to your Vercel URL.
- 4
Connect MongoDB Atlas
Add Vercel's outbound access to MongoDB Atlas Network Access, then set MONGODB_URI in Vercel before deploying.
bashMONGODB_URI=mongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro - 5
Add your custom domain
Project Settings → Domains. SSL is provisioned automatically.
If you'd rather run on a VPS, PropertyPro ships with a production-ready Dockerfile and a sample docker-compose.yml that can run MongoDB alongside the app.
- 1
Build & start the stack
From the project root, build the images and run them in the background.
bashdocker compose up -d --build - 2
Seed demo data inside the container
Load demo records only when you are setting up a test or evaluation instance.
bashdocker compose exec app pnpm db:seed - 3
Front with nginx + SSL
Use nginx (or Caddy) to terminate TLS and proxy to localhost:3000. Caddy will provision Let's Encrypt automatically.
Caddyfilenginxpropertypro.yourdomain.com { reverse_proxy localhost:3000 }
services:
app:
build: .
ports: ["3000:3000"]
env_file: .env.local
environment:
MONGODB_URI: mongodb://propertypro:change-me@mongo:27017/propertypro?authSource=admin
depends_on: [mongo]
mongo:
image: mongo:7
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: propertypro
MONGO_INITDB_ROOT_PASSWORD: change-me
volumes:
- mongodata:/data/db
ports: ["27017:27017"]
volumes:
mongodata:Use a managed database
Self-hosting MongoDB works but you'll own backups, replication, and upgrades. MongoDB Atlas offloads that work.
Once your app is live, route a custom domain to it. Both Vercel and Caddy provision SSL certificates for free.
- 1
Add an A or CNAME record
For Vercel, add a CNAME pointing to cname.vercel-dns.com. For your VPS, point an A record at the server IP.
- 2
Verify in Vercel / Caddy
Vercel auto-verifies once DNS propagates. Caddy reissues the certificate on the next request.
- 3
Update application URLs
Switch APP_URL, NEXTAUTH_URL, and AUTH_URL to https://yourdomain.com and redeploy. These are used in emails and auth callbacks.
After your first deploy, lock down the demo admin and create real users with scoped permissions.
- 1
Sign in & rotate the demo password
Log in as admin@propertypro.app, open Settings → Profile, and set a strong password.
- 2
Invite your team
Settings → Team → Invite. Each invitee gets an email with a one-time setup link.
- 3
Assign roles
Built-in roles: Admin, Manager, Accountant, Inspector, Tenant. Create custom roles under Settings → Roles.
- 4
Audit log
Every sensitive action is recorded. Review under Settings → Activity.
Don't share admin accounts
Shared logins break audit trails. Always invite a new user — even for short-term contractors.
PropertyPro ships minor updates monthly. Every release is non-destructive — your data and customizations stay intact.
- 1
Download the latest build
From your CodeCanyon downloads. Compare the version against the Changelog to plan the update.
- 2
Diff and merge
Use git or your favorite diff tool to merge the new files. Your /messages and /public assets are safe to keep as-is.
- 3
Install and rebuild
Install dependencies and run a production build after merging each release.
bashpnpm install pnpm build - 4
Schedule database backups
Use MongoDB Atlas automated backups or set up nightly mongodump on a VPS.
bash# Cron: nightly backup at 02:00 0 2 * * * mongodump --uri="$MONGODB_URI" --archive=/backups/propertypro-$(date +\%F).archive --gzip
Most install problems fall into the same handful of buckets. Walk through these before opening a support ticket.
MONGODB_URI connection refused
Check the username, password, database name, and Atlas Network Access allowlist. For self-hosted MongoDB, confirm the authSource value.
Stripe webhook signature invalid
Make sure STRIPE_WEBHOOK_SECRET matches the secret of the specific endpoint, not your account secret.
Emails landing in spam
Set up SPF, DKIM, and DMARC for your sender domain. Resend & SendGrid have step-by-step UIs for this.
Push notifications not arriving
iOS Safari requires the PWA to be installed via Add to Home Screen first. Web push is unavailable in Incognito mode.
pnpm install fails
Delete node_modules and pnpm-lock.yaml, run corepack enable, then pnpm install fresh.
File uploads silently fail
Check R2_* variables, NEXT_PUBLIC_R2_PUBLIC_URL, upload limits, and whether your Cloudflare R2 bucket allows public reads from the configured URL.
