A full-stack real estate platform where you can browse & list properties, book viewings, and run AI-powered searches that scrape live listings from 99acres, MagicBricks & NoBroker in real time. You bring a free Firecrawl key — the AI runs on the server.
🏠 What is BuildEstate?
BuildEstate is a complete real-estate website for India — think of a mini 99acres/MagicBricks with an AI twist. In plain words, here is what you can do on it:
- Browse properties listed on the platform, filter them, view photo galleries, and book a property viewing (works even without an account)
- List your own property for sale or rent from your user dashboard — an admin reviews it before it goes live
- Use the AI Property Hub — enter a city, budget, and home type, and the AI searches live listings on 99acres, MagicBricks & NoBroker, then ranks the best matches with value verdicts and red-flag warnings
- See market trends — price per sq.ft, rental yields, and appreciation outlook for localities in any major Indian city
This repo contains all three apps: the user website (frontend/), the admin panel (admin/), and the REST API (backend/).
📸 Platform Preview
📋 Table of Contents
| | Section | | :-: | :----------------------------------------------- | | 🧠 | Why BuildEstate? | | 🤖 | AI Property Hub | | 🌟 | Features | | 🏗️ | Architecture | | 💻 | Tech Stack | | 🚀 | Getting Started | | 🔌 | API Endpoints | | 🌐 | Deployment | | 📖 | Deployment Guide | | 📂 | Project Structure | | 🤝 | Contributing | | 👨💻 | Author |
🧠 Why BuildEstate?
Most real-estate aggregators show you generic listings. BuildEstate is different:
| Problem | BuildEstate Solution | |---|---| | Generic search results with mixed content | Multi-source search — 99acres, MagicBricks, Housing.com results deduplicated & ranked | | No AI intelligence in traditional portals | Multi-model AI analysis — best-value picks, investment insights, red-flag detection, with a user-selectable model (GLM, Nemotron & more) | | API costs borne by the developer | Bring-your-own Firecrawl key — scraping runs on the user's free key; AI analysis runs server-side | | Search-page bot protection ruins results | Individual listing scraping — firecrawl.search() → per-property URLs → clean data | | Search breaks on proxy/rate errors | Auto-retry with exponential backoff — proxy → rate-limit → server errors all handled |
TL;DR — This is not another property listing site. It's an AI-first platform that turns raw web data into actionable real estate insights.
🤖 AI Property Hub
The headline feature. Search any Indian city + property type + budget → get live scraped properties with AI analysis.
🎬 Watch It In Action
https://github.com/user-attachments/assets/43cefb8a-0e75-4680-85e9-2eb099db0fc8
📹 _Demo video coming soon — a full AI search from form to ranked results in ~30 seconds._
How It Works
The new search pipeline uses Google-indexed URLs as the filter, scraping individual property pages in parallel:
sequenceDiagram
participant User as User<br/>(Browser)
participant Backend as Express<br/>Backend
participant Firecrawl as Firecrawl API
participant Sources as 99acres<br/>MagicBricks<br/>Housing.com
participant AI as GitHub Models<br/>(GPT-4.1)
User->>Backend: POST /api/ai/search<br/>(city, locality, bhk, budget, possession)
Backend->>Backend: Build 3 search queries
par Multi-Source Search
Backend->>Firecrawl: Search: "2BHK flat for sale in Powai<br/>Mumbai under ₹2Cr site:99acres.com"
Backend->>Firecrawl: Search: "...site:magicbricks.com"
Backend->>Firecrawl: Search: "...site:housing.com"
end
Firecrawl->>Sources: Google API returns listing URLs
Sources->>Firecrawl: Returns 8-10 URLs per source
par Parallel Scraping
Firecrawl->>Sources: Full browser render of each URL
Firecrawl->>Sources: LLM extracts structured JSON
end
Backend->>Backend: Deduplicate by address + building name<br/>Code-side filter: reject rentals/PG
Backend->>AI: Send clean properties for ranking
AI->>Backend: Return ranked with insights
Backend->>User: { properties, analysis, source_badges }
Search Query Construction
The backend builds rich search queries that leverage Google's index as the filter:
User fills form:
City: Mumbai
Locality: Powai
BHK: 2BHK
Budget: ₹1.5 - ₹2.5 Cr
Possession: Ready
↓
Search query:
"2BHK flat for sale in Powai Mumbai ready
under 2.5 crore site:99acres.com"
↓
firecrawl.search() → returns 10 individual property listing URLs
↓
Scrape each URL in parallel (each = exactly ONE property)
↓
Code-side filter: reject anything with "/month" or "rental"
Why this works:
- Individual listing pages have light bot protection (not heavily scraped)
- Google's index is the filtering engine — query says "ready" so only ready properties return
- One page = one property = zero mixed-content problem
- URL of the page you scraped IS the property listing URL — always correct
Supported Coverage
| Category | Coverage | |---|---| | 🏙️ Cities | 30+ — Mumbai, Delhi, Bangalore, Pune, Chennai, Hyderabad, Ahmedabad, Kolkata, Jaipur, Lucknow, and more | | 🏠 Property Types | Flat, House, Villa, Plot, Penthouse, Studio, Commercial | | 💰 Budget Range | ₹5 Lakhs → ₹25+ Crores (user-defined min/max) | | 📍 Multi-Source | 99acres.com, MagicBricks.com, Housing.com searched in parallel | | 🏷️ Deduplication | Same property across portals = shown once with source badges | | 🔄 Retry Logic | Auto-retry on proxy failures, rate limits (429), and server errors (502/503) | | 🔧 Advanced Filters | Locality, BHK (1/2/3/4/Any), Possession status (Ready/Under Const/Any) |
Advanced Search Form Fields
The redesigned form captures buyer intent more precisely:
| Field | Type | Values | Impact | |-------|------|--------|--------| | City | Dropdown | 30+ Indian cities | Primary market | | Locality ✨ | Text autocomplete | "Powai", "Andheri West", etc. | Highest relevance gain | | Property Type | Pill buttons | Flat / House / Villa / Plot | Property category | | BHK Config ✨ | Pill selector | 1BHK / 2BHK / 3BHK / 4BHK+ / Any | Unit size | | Budget | Dual slider | ₹X Lakhs → ₹Y Crores | Price range | | Possession ✨ | Radio group | Ready / Under Const / Any | Timeline preference |
Locality is the biggest improvement — Indians buy in neighborhoods, not cities. "Powai" → 10x better results than just "Mumbai".
🔑 Bring Your Own Firecrawl Key
Users provide their own free Firecrawl key in the browser — it lives in localStorage only, never on the server. AI analysis runs server-side through a multi-model fallback chain (NVIDIA NIM → GitHub Models), and users pick the model (GLM-5.2, Nemotron Nano/Ultra, Mistral…) right in the search form.
User's browser (localStorage)
buildestate_firecrawl_key = "fc-xxx"
│
│ X-Firecrawl-Key header on every AI request
▼
Backend creates a per-request Firecrawl instance
(scraping ALWAYS uses the user's key — server AI keys
are used only for the analysis step)
Get your free key in ~2 minutes:
| Service | Link | Free Tier | |---|---|---| | Firecrawl (web scraping) | firecrawl.dev | 500 free credits/month |
🌟 Features
✨ AI Property Hub (Redesigned)
Search across 3+ property portals in parallel, get deduplicated results ranked by AI insights.
| Feature | Description | | :-----: | :--- | | 🔍 | Multi-source search — 99acres, MagicBricks, Housing.com simultaneously | | 🏷️ | Source badges — know which portal each listing comes from | | 📍 | Locality-first searching — "Powai" not just "Mumbai" | | 🎯 | Advanced filters — BHK, possession status, min/max budget | | 🤖 | Per-property AI insights — specific not generic ("8% below area avg, metro in 800m") | | ⚠️ | Red flags detection — no RERA, delayed builder, overpriced alerts | | 🎨 | Two-column layout — results + AI analysis side-by-side | | 💾 | Compare tool — select up to 3 properties, compare specs |
🏡 Property Browsing & Booking
Rich filters, detailed galleries (up to 4 images per property via ImageKit CDN), and instant appointment scheduling.
| Feature | Description | | :-----: | :--- | | 🔎 | Advanced filter sidebar — price, type, location, area, amenities | | 🖼️ | Multi-image gallery delivered via ImageKit CDN | | 📅 | Appointment booking — works for both guest and authenticated users | | 🔐 | JWT authentication with bcrypt hashing + email-based password reset | | 🎨 | Fluid page transitions powered by Framer Motion | | 🔍 | SEO-optimized — structured data, sitemap, robots.txt, per-page meta tags |
👤 User Dashboard
Every registered user gets a personal dashboard — list a property for sale/rent, track its review status, and manage viewing appointments.
📊 Admin Dashboard
Full control — review user-submitted listings, manage properties & users, track appointments, and monitor analytics.
| Capability | Description | | :--------: | :--- | | 📥 | Review Queue — approve or reject user-submitted listings with a full image gallery | | ➕ | Add / Edit / Delete property listings with multi-image upload | | 📅 | Appointment management with status updates & meeting link generation | | 📈 | Real-time analytics dashboard with Recharts visualizations | | 👥 | User management — suspend, ban, reactivate with audit trail | | 🤖 | AI model management — enable/disable models and set the default from the panel | | 📜 | Activity logs — every admin action recorded and searchable |
🏗️ Architecture
Multi-source AI Property Search Pipeline:
graph TD
A["React Frontend<br/>(TypeScript + Vite)"] -->|POST /api/ai/search| B["Express Backend<br/>(Node.js + Helmet + CORS)"]
B -->|Build 3 parallel queries| C["Firecrawl API"]
C -->|Query 1:<br/>site:99acres.com| D1["99acres"]
C -->|Query 2:<br/>site:magicbricks.com| D2["MagicBricks"]
C -->|Query 3:<br/>site:housing.com| D3["Housing.com"]
D1 -->|8-10 URLs| E["Parallel<br/>Scraping"]
D2 -->|8-10 URLs| E
D3 -->|8-10 URLs| E
E -->|Full browser render<br/>per property| F["Firecrawl<br/>scrapeUrl"]
F -->|Structured JSON| G["Backend<br/>Processing"]
G -->|Deduplicate<br/>by address| H["Code-side Filter<br/>Reject rentals/PG"]
H -->|Clean properties| I["GitHub Models<br/>GPT-4.1"]
I -->|Ranked + Insights| J["Response<br/>to Frontend"]
J -->|Display with<br/>source badges| K["Rich Property<br/>Cards"]
B --> L[("MongoDB<br/>Atlas")]
C --> M["User API Keys<br/>(localStorage)"]
F --> N["ImageKit CDN<br/>(Images)"]
style B fill:#4A90E2
style E fill:#FF6B6B
style I fill:#7C3AED
style K fill:#10B981
Complete System Architecture:
flowchart LR
subgraph Client["CLIENT LAYER"]
FE["Frontend<br/>React 18 + TS<br/>Vercel"]
AD["Admin Panel<br/>React + JS<br/>Vercel"]
end
subgraph API["API LAYER (Render)"]
BE["Express.js<br/>Helmet + CORS<br/>Rate Limiter"]
end
subgraph Data["DATA & SERVICES"]
DB[("MongoDB Atlas<br/>Database")]
IK["ImageKit CDN<br/>Images"]
FC["Firecrawl API<br/>Web Scraping<br/>Multi-source"]
AI["AI Models<br/>NVIDIA NIM + GPT-4.1<br/>Ranking & Insights"]
EMAIL["Brevo SMTP<br/>Email Service"]
end
FE -->|Axios| BE
AD -->|Axios| BE
BE -->|JWT Auth| DB
BE -->|Upload| IK
BE -->|Scrape| FC
BE -->|Rank Props| AI
BE -->|Send Mail| EMAIL
style Client fill:#E8F4F8
style API fill:#F0E8FF
style Data fill:#FFF4E8
💻 Tech Stack
🚀 Getting Started
Prerequisites
- Node.js 18+ and npm 8+
- MongoDB Atlas free account (or local MongoDB)
- ImageKit free account (10GB free tier)
- Brevo free SMTP account (for email notifications)
1. Clone the Repository
git clone https://github.com/AAYUSH412/Real-Estate-Website.git
cd Real-Estate-Website
Install dependencies per app:
cd backend && npm install
cd ../frontend && npm install
cd ../admin && npm install
⚙️ 2. Backend Setup
cd backend
npm install
cp .env.example .env.local
Edit backend/.env.local with your actual values:
# Essential Configuration (Required)
MONGO_URI=mongodb+srv://username:[email protected]/buildestate?retryWrites=true&w=majority
JWT_SECRET=your_super_secure_jwt_secret_here # Generate with: openssl rand -base64 32
[email protected]
ADMIN_PASSWORD=your_secure_admin_password
Email Service (Brevo SMTP - Free tier available)
SMTP_USER=your_brevo_smtp_login
SMTP_PASS=your_brevo_smtp_password
[email protected]
BREVO_API_KEY=your_brevo_api_key
Frontend URL (for CORS + password reset emails)
WEBSITE_URL=http://localhost:5173
FRONTEND_URL=http://localhost:5173
ADMIN_URL=http://localhost:5174
LOCAL_URLS=http://localhost:5173,http://localhost:5174,http://localhost:4000
Optional: Image Storage (ImageKit - Free 10GB tier)
IMAGEKIT_PUBLIC_KEY=public_your_imagekit_public_key
IMAGEKIT_PRIVATE_KEY=private_your_imagekit_private_key
IMAGEKIT_URL_ENDPOINT=https://ik.imagekit.io/your_imagekit_id
Optional: AI Services (for AI Property Hub)
Users can provide their own keys via frontend, these are server fallbacks
FIRECRAWL_API_KEY=fc-your_firecrawl_api_key
GITHUB_MODELS_API_KEY=github_pat_your_github_token
npm run dev # Starts backend on http://localhost:4000
🔑 Get Free API Keys (Optional - for AI features):
- MongoDB Atlas: cloud.mongodb.com - Free 512MB tier
- ImageKit: imagekit.io - Free 10GB + CDN
- Brevo SMTP: brevo.com - Free 300 emails/day
- Firecrawl: firecrawl.dev - Free 500 pages/month
- GitHub Models: github.com/marketplace/models - Free with GitHub account
🖥️ 3. Frontend Setup
cd ../frontend
npm install
cp .env.example .env.local
Edit frontend/.env.local:
# Backend API URL
VITE_API_BASE_URL=http://localhost:4000
Feature flags
VITE_ENABLE_AI_HUB=true
npm run dev # Starts frontend on http://localhost:5173
🛠️ 4. Admin Panel Setup
cd ../admin
npm install
cp .env.example .env.local
Edit admin/.env.local:
# Backend API URL (must match your backend)
VITE_BACKEND_URL=http://localhost:4000
npm run dev # Starts admin panel on http://localhost:5174
🔐 Access Admin Panel:
- URL: http://localhost:5174
- Login with credentials from
backend/.env:ADMIN_EMAIL&ADMIN_PASSWORD
🔌 API Endpoints
🔐 Authentication & Users
| Method | Endpoint | Description | |---|---|---| | POST | /api/users/register | Register new user | | POST | /api/users/login | Login (returns JWT) | | POST | /api/users/admin | Admin login | | GET | /api/users/me | Get current user (JWT required) | | POST | /api/users/forgot | Send password reset email | | POST | /api/users/reset/:token | Reset password |
🏠 Properties
| Method | Endpoint | Description | |---|---|---| | GET | /api/products/list | List all properties | | GET | /api/products/single/:id | Get property by ID | | POST | /api/products/add | Add property with images (admin) | | POST | /api/products/update | Update property (admin) | | POST | /api/products/remove | Delete property (admin) |
📅 Appointments
| Method | Endpoint | Description | |---|---|---| | POST | /api/appointments/schedule | Book viewing (guest) | | POST | /api/appointments/schedule/auth | Book viewing (logged in) | | GET | /api/appointments/user | Get appointments by email | | PUT | /api/appointments/cancel/:id | Cancel appointment | | GET | /api/appointments/all | All appointments (admin) | | PUT | /api/appointments/status | Update status (admin) | | PUT | /api/appointments/update-meeting | Add meeting link (admin) |
🤖 AI & Other Services
| Method | Endpoint | Description | |---|---|---| | POST | /api/ai/search | AI property search (requires user API keys) | | GET | /api/locations/:city/trends | Location market trends (requires user API keys) | | POST | /api/forms/submit | Contact form submission | | GET | /api/admin/stats | Dashboard statistics (admin) |
🌐 Deployment
📖 For detailed deployment instructions, see DEPLOYMENT.md
🚀 Quick Deploy (5 minutes):
Live Deployments
- 🌐 Frontend: buildestate.vercel.app (Vercel)
- ⚙️ Backend: real-estate-website-backend-zfu7.onrender.com (Render)
▲ Frontend on Vercel (Recommended)
- Fork this repository to your GitHub account
- Import repo in Vercel
- Configure build settings:
frontend
- Build Command: npm run build
- Output Directory: dist
- Add environment variables:
VITE_API_BASE_URL=https://your-backend-domain.onrender.com
VITE_ENABLE_AI_HUB=false # Disable for production (users provide own keys)
VITE_SITE_URL=https://your-domain.vercel.app
[email protected]
- Deploy → Your site will be live at
https://your-project.vercel.app
🟢 Backend on Render
Backend Web Service:
- Create Web Service on Render
- Connect your GitHub repository
- Configure service:
Node
- Root Directory: backend
- Build Command: npm install
- Start Command: npm start
- Add environment variables (copy from
backend/.env.example):
NODE_ENV=production
MONGO_URI=your_mongodb_atlas_uri
JWT_SECRET=your_secure_jwt_secret
[email protected]
ADMIN_PASSWORD=your_secure_password
WEBSITE_URL=https://your-frontend.vercel.app
FRONTEND_URL=https://your-frontend.vercel.app
ADMIN_URL=https://your-admin.vercel.app
LOCAL_URLS=
# ... add other variables as needed
▲ Admin on Vercel
- Import repo in Vercel
- Configure build settings:
admin
- Build Command: npm run build
- Output Directory: dist
- Add environment variables:
VITE_BACKEND_URL=https://your-backend.onrender.com
- Deploy and test deep links (
/dashboard,/users,/activity-logs)
- Ensure backend CORS env includes your admin Vercel domain in
ADMIN_URL
✅ Pre-Deployment Checklist
Required Services (Free tier available):
- [ ] MongoDB Atlas cluster created → Connection string ready
- [ ] ImageKit account → API keys ready (for image uploads)
- [ ] Brevo SMTP account → SMTP credentials ready (for emails)
- [ ] All
.envfiles configured with production values - [ ]
JWT_SECRETset to secure random string (32+ characters) - [ ]
ADMIN_EMAILandADMIN_PASSWORDset to your admin credentials - [ ] Frontend
VITE_API_BASE_URLpoints to deployed backend - [ ] Backend
WEBSITE_URLpoints to deployed frontend
- [ ] Firecrawl API key (500 free pages/month)
- [ ] GitHub Models token (free with GitHub account)
🔧 Alternative Deployment Options:
- Backend: Heroku, Railway, DigitalOcean App Platform, AWS/Google Cloud
- Frontend: Netlify, GitHub Pages, Surge.sh
- Database: Local MongoDB, DigitalOcean MongoDB, AWS DocumentDB
📂 Project Structure
View Full Directory Tree
Real-Estate-Website/
├── frontend/ → User-facing website (React + TypeScript + Vite)
├── admin/ → Admin dashboard (React + Vite)
├── backend/ → REST API server (Node.js + Express)
├── Image/ → README screenshots
└── .github/ → Issue templates, PR template, CODEOWNERS
Frontend src/
├── components/
│ ├── ai-hub/ → AI Property Hub (search form, results, trends)
│ ├── common/ → Navbar, Footer, SEO, PageTransition
│ ├── home/ → Homepage sections
│ ├── properties/ → Filter sidebar, property cards
│ ├── property-details/ → Gallery, amenities, booking form
│ ├── about/ → About page sections
│ └── contact/ → Contact page sections
├── contexts/ → AuthContext (JWT state management)
├── hooks/ → useSEO
├── pages/ → All pages (lazy loaded via React.lazy)
└── services/ → api.ts (Axios client + API key injection)
Backend
├── config/ → MongoDB, ImageKit, Nodemailer config
├── controller/ → Route handlers (property, appointment, AI search)
├── middleware/ → JWT auth, Multer uploads, stats tracking, request transform
├── models/ → Mongoose schemas (Property, User, Appointment, Stats)
├── routes/ → Express route definitions
├── services/
│ ├── firecrawlService.js → Smart 99acres scraping (30+ cities, URL construction, retry logic)
│ └── aiService.js → GPT-4.1 property analysis + location trends
├── utils/ → AI response validation & safe parsing
└── server.js → Entry point (Helmet, CORS, rate limiting)
Admin src/
├── components/ → Login, Sidebar, ProtectedRoute, modals
├── config/ → Property types, amenities constants
├── contexts/ → AuthContext (admin JWT state)
└── pages/ → Dashboard, PendingListings (review queue), List,
Users, UserDetails, Appointments, AIModels,
ActivityLogs, Add, Update
📜 Available Scripts
| Directory | Command | Description | |---|---|---| | backend/ | npm run dev | Start with nodemon (auto-reload) | | backend/ | npm start | Start production server | | frontend/ | npm run dev | Start Vite dev server | | frontend/ | npm run build | Production build | | admin/ | npm run dev | Start Vite dev server | | admin/ | npm run build | Production build |
🤝 Contributing
Contributions are welcome! Please read the Contributing Guide first.
# 1. Fork the repository
2. Create your branch
git checkout -b feature/your-feature
3. Commit your changes
git commit -m "feat: add your feature"
4. Push and open a PR
git push origin feature/your-feature
See also: Code of Conduct · Security Policy
📝 License
MIT License — see LICENSE for details.