A modern, full-stack postal analytics platform and interactive directory for India's 150,000+ PIN codes (Postal Index Numbers). Built with a high-performance Node.js / Express 5 REST API backed by MongoDB Atlas, paired with a reactive, glassmorphic React 19 frontend powered by Redux Toolkit, Tailwind CSS, and Recharts.
- Overview
- Key Features
- System Architecture
- Tech Stack
- Project Directory Structure
- Backend API Documentation
- Data Model & MongoDB Optimization
- Environment Variables
- Getting Started & Local Setup
- Deployment Guide
- License & Data Attribution
The Indian Postal network is one of the largest physical delivery networks in the world. PinCode Explorer simplifies exploring, searching, and analyzing this vast dataset:
- Provides high-level postal telemetry (total post offices, delivery coverage, postal divisions, circle hierarchies).
- Allows users to drill down hierarchically from State → District → Taluk → Individual Post Office.
- Powers lightning-fast debounced search with typeahead suggestions across PIN codes, office names, and regions.
- Offers instantaneous CSV export for data science and offline analysis.
-
National Postal Analytics Dashboard:
- High-level metric cards: Total PIN Codes, Active States/UTs, Delivery Offices, and Non-Delivery Offices.
- State Distribution: Bar chart comparing postal density across top states (e.g., Uttar Pradesh, Andhra Pradesh, Maharashtra).
- Office Type Breakdown: Head Offices (H.O), Sub Offices (S.O), and Branch Offices (B.O) distribution.
- Regional Share: Color-coded donut/pie chart displaying top postal regions.
- Top Districts: Ranked list of districts with the densest postal office distribution.
-
Hierarchical Geographic Filtering:
- Cascading dropdowns: Select State to unlock its Districts, then pick a district to dynamically load Taluks.
- Server-side pagination with dynamic page size calculations.
-
Instant Search & Typeahead:
- Debounced search bar (400ms delay) queryable by 6-digit numeric PIN, office name, district, or state.
- Auto-suggest dropdown with direct deep links into specific PIN code records.
-
Detailed PIN Code Inspector (
/pincode/:id):- Complete dossier on each PIN code: Office name, office type badge, delivery status, circle, division, region, taluk, district, and state.
- Dedicated fallback state and route handling when searching directly.
-
Filtered CSV Export:
- Streamed CSV export generated directly on the server via
json2csvaccording to currently applied state and region filters.
- Streamed CSV export generated directly on the server via
-
Refined Design System:
- Clean color palette featuring warm coral accents (
#FF6B4E), crisp typographic hierarchy using Inter and JetBrains Mono, glassmorphic sticky navigation, and subtle micro-interactions.
- Clean color palette featuring warm coral accents (
graph TD
User([User Browser])
subgraph Frontend ["Frontend (Vite + React 19)"]
UI[Tailwind CSS Components]
Router[React Router v7]
Store[Redux Toolkit Store / Thunks]
Charts[Recharts Visualization]
end
subgraph Backend ["Backend (Express 5 & Node.js)"]
Server[Express Server on :5000]
CORS[CORS & JSON Middleware]
RouterAPI[Express Router /api]
Controller[pincodeController.js]
end
subgraph Database ["Database (MongoDB Atlas)"]
Mongo[(Collection: data)]
end
User <-->|HTTP / DOM| UI
UI <--> Router
UI <--> Store
Store <--> Charts
Store <-->|Axios API Requests| RouterAPI
RouterAPI --> Controller
Controller <-->|Mongoose / Native Driver Aggregations| Mongo
| Technology | Purpose |
|---|---|
| React 19 | Modern UI component rendering |
| Redux Toolkit (RTK) | Global state management & asynchronous thunks |
| React Router DOM v7 | Client-side declarative routing |
| Tailwind CSS v3 | Utility-first responsive design system |
| Recharts | Interactive SVG charts (Bar & Pie visualizations) |
| Axios | HTTP client for backend communication |
| Vite 8 | Next-generation fast development server & bundler |
| Heroicons & Lucide | Clean UI iconography |
| Technology | Purpose |
|---|---|
| Node.js (18+) | JavaScript runtime environment |
| Express.js (5.2) | RESTful API web application framework |
| MongoDB & Mongoose (9.x) | Document database & Object Document Modeling (ODM) |
| json2csv | Fast server-side conversion of JSON documents to CSV format |
| cors | Cross-Origin Resource Sharing middleware |
| dotenv | Environment variable management |
| nodemon | Development live reload |
PinCode_Explorer/
├── .gitignore # Git ignore patterns
├── README.md # Comprehensive project documentation
│
├── backend/ # Express API server
│ ├── package.json # Backend scripts & dependencies
│ ├── server.js # Express app entry point & CORS configuration
│ ├── config/
│ │ └── db.js # Mongoose database connection setup
│ ├── models/
│ │ └── Pincode.js # Mongoose Schema definition for postal records
│ ├── routes/
│ │ └── pincodeRoutes.js # API route declarations
│ └── controllers/
│ └── pincodeController.js # Query logic, aggregation pipelines & data sanitization
│
└── frontend/ # Vite + React application
├── index.html # Main HTML entry with Inter & JetBrains Mono fonts
├── package.json # Frontend dependencies & scripts
├── vite.config.js # Vite configuration
├── tailwind.config.cjs # Tailwind custom colors, fonts & borders
├── postcss.config.cjs # PostCSS plugins
├── vercel.json # Vercel SPA client-side rewrite rules
└── src/
├── main.jsx # React root mount with Redux Provider
├── App.jsx # App layout, router & navigation shell
├── index.css # Global styles, animations & design tokens
├── store/
│ ├── store.js # Redux store config
│ └── slices/
│ └── pincodeSlice.js # Async thunks (fetchStates, fetchStats, etc.) & state
├── components/
│ ├── Navbar.jsx # Sticky glassmorphic navigation bar
│ ├── Footer.jsx # Minimal footer with stack tags & attribution
│ ├── SearchBar.jsx # Debounced search bar with live auto-complete
│ ├── StatsCard.jsx # Metric cards for national statistics
│ ├── FilterPanel.jsx # Cascading dropdowns (State, District, Taluk) & Export
│ └── DataTable.jsx # Paginated tabular records with office type badges
└── pages/
├── Dashboard.jsx # National dashboard with analytics charts & KPI summaries
├── Explore.jsx # Full-featured interactive directory table & filters
├── Pincode.jsx # Individual PIN code detail view & single search prompt
└── About.jsx # Mission statement, architecture steps & tech stack logos
Base URL (Local): http://localhost:5000/api
- Route:
GET /api/states - Description: Returns a sorted list of unique Indian States and Union Territories.
- Sample Response:
[ "ANDAMAN & NICOBAR ISLANDS", "ANDHRA PRADESH", "ASSAM", "BIHAR", "CHANDIGARH", "DELHI", "GUJARAT", "MAHARASHTRA" ]
- Route:
GET /api/states/:state/districts - Example:
GET /api/states/DELHI/districts - Sample Response:
[ "Central Delhi", "East Delhi", "New Delhi", "North Delhi", "South Delhi" ]
- Route:
GET /api/states/:state/districts/:district/taluks - Example:
GET /api/states/DELHI/districts/Central%20Delhi/taluks - Sample Response:
[ "Central Delhi", "Darya Ganj", "Karol Bagh" ]
- Route:
GET /api/pincodes - Query Parameters:
state(optional): Filter by State name.district(optional): Filter by District name.taluk(optional): Filter by Taluk name.page(optional, default:1): Page number.limit(optional, default:20): Number of records per page.
- Sample Response:
{ "data": [ { "_id": "64f1c...", "pincode": 110001, "officeName": "Baroda House S.O", "officeType": "S.O", "deliveryStatus": "Non-Delivery", "divisionName": "New Delhi Central", "regionName": "Delhi", "circleName": "Delhi", "taluk": "New Delhi", "districtName": "Central Delhi", "stateName": "DELHI" } ], "total": 650, "page": 1, "limit": 20 }
- Route:
GET /api/search?q=:query - Example:
GET /api/search?q=380001orGET /api/search?q=Ahmedabad - Description: Returns up to 10 matching records searching across PIN code, office name, district, or state.
- Route:
GET /api/pincode/:pincode - Example:
GET /api/pincode/110001 - Sample Response:
{ "_id": "64f...", "officeName": "New Delhi G.P.O.", "pincode": 110001, "officeType": "H.O", "deliveryStatus": "Delivery", "divisionName": "New Delhi Central", "regionName": "Delhi", "circleName": "Delhi", "taluk": "New Delhi", "districtName": "Central Delhi", "stateName": "DELHI" }
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/stats |
National totals: count of PIN codes, states, delivery & non-delivery offices |
GET |
/api/stats/state-distribution |
Array of { state, count } sorted descending by post office density |
GET |
/api/stats/delivery-distribution |
Breakdown of { delivery, nonDelivery } counts |
GET |
/api/stats/office-type-distribution |
Office type frequencies: H.O (Head Office), S.O (Sub Office), B.O (Branch Office) |
GET |
/api/stats/region-distribution |
Top 15 postal regions with office counts |
GET |
/api/stats/top-districts |
Top 10 districts by total office count |
- Route:
GET /api/export - Query Parameters:
state(optional) - Response: Triggers an attachment download named
pincodes.csvwith fields:pincode,officeName,officeType,deliveryStatus,divisionName,regionName,circleName,taluk,districtName,stateName.
In the MongoDB collection (data), documents correspond to postal service points with the following fields:
{
officeName: String, // e.g. "Ahmedabad G.P.O."
pincode: Number, // 6-digit integer, e.g. 380001
officeType: String, // "H.O", "S.O", "B.O"
deliveryStatus: String, // "Delivery" or "Non-Delivery"
divisionName: String, // Postal Division
regionName: String, // Postal Region
circleName: String, // Postal Circle
taluk: String, // Tehsil / Sub-district
districtName: String, // District
stateName: String, // State / Union Territory
telephone: String, // Contact number if recorded
relatedSuboffice: String, // Parent Sub-Office (if applicable)
relatedHeadoffice: String, // Parent Head-Office (if applicable)
longitude: String, // Geolocation coordinate
latitude: String // Geolocation coordinate
}Note
Dataset Field Sanitization: In the raw dataset, the MongoDB field for state name contains trailing whitespace:
'stateName ' (39 trailing spaces).
The backend controller (pincodeController.js) handles this seamlessly by targeting the exact field with MongoDB Aggregation $trim and RegExp matchers, automatically cleaning up values before serializing responses.
Create a .env file in the backend/ directory:
# Port on which Express server listens
PORT=5000
# MongoDB Connection String (Atlas or Local)
MONGO_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/<database_name>?retryWrites=true&w=majority
# Application environment
NODE_ENV=developmentCreate a .env file in the frontend/ directory:
# Backend API base endpoint
VITE_API_URL=http://localhost:5000/api- Node.js: v18.0.0 or higher
- npm: v9.0.0 or higher
- MongoDB: Access to a MongoDB Atlas cluster or local MongoDB instance with the pincode dataset loaded into a database collection named
data.
git clone https://github.com/Vachhani-Tapan/PinCode_Explorer.git
cd PinCode_Explorer# Navigate to backend directory
cd backend
# Install dependencies
npm install
# Create environment configuration
# On Linux/macOS:
cp .env.example .env 2>/dev/null || touch .env
# On Windows PowerShell:
# New-Item -ItemType File -Name .env
# Add your MONGO_URI and PORT to backend/.env
# PORT=5000
# MONGO_URI=your_mongodb_connection_string
# Start backend server in development mode (with nodemon)
npm run devThe backend API server will initialize on http://localhost:5000. You can verify it by opening http://localhost:5000 in your browser (should return { status: 'ok', message: 'PinCode Explorer API is running' }).
In a new terminal window:
# Navigate to frontend directory
cd frontend
# Install dependencies
npm install
# Optional: configure frontend/.env if using a custom backend port/URL
# VITE_API_URL=http://localhost:5000/api
# Run Vite development server
npm run devThe web application will be accessible at:
👉 http://localhost:5173
To test a production bundle locally:
npm run build
npm run preview- Push your repository to GitHub.
- Go to Render Dashboard and click New → Web Service.
- Connect your repository.
- Set Root Directory to
backend. - Set Build Command to
npm install. - Set Start Command to
npm start. - In the Environment Variables section, configure:
MONGO_URI: Your MongoDB Atlas URI.PORT:5000(or Render's automatic$PORT).NODE_ENV:production.
- Deploy and note your Render API URL (e.g.,
https://pincode-explorer-api.onrender.com).
- Go to Vercel Dashboard and click Add New Project.
- Import the
PinCode_Explorerrepository. - Configure the build settings:
- Root Directory:
frontend - Framework Preset:
Vite - Build Command:
npm run build - Output Directory:
dist
- Root Directory:
- In Environment Variables, add:
VITE_API_URL:https://your-backend-app.onrender.com/api
- Click Deploy. Vercel will automatically read
frontend/vercel.jsonto handle client-side Single Page Application (SPA) routing.
- Postal Data: Official data attribution belongs to the Department of Posts, Ministry of Communications, Government of India (India Post).
- Application Code: Licensed under the ISC License for open research, educational, and developer exploration.