"Wear it again, wear it well."
Threadly is a full-stack sustainable fashion marketplace where users can buy, sell, and swap pre-loved clothing. Built with React + Node.js, it features real-time chat, AI-assisted listing creation, Stripe payments, and a unique item-swap system.
π Live Demo: threadly-liart.vercel.app
π§ Backend API: threadly-eigu.onrender.com
| Feature | Description |
|---|---|
| ποΈ Buy & Sell | List pre-loved clothes with AI-generated descriptions |
| π Swap System | Propose item-for-item swaps β no money needed |
| π¬ Real-time Chat | Socket.IO powered messaging between buyers and sellers |
| π Auth | JWT access tokens + httpOnly refresh token cookies |
| π§ Forgot Password | Secure email reset flow via Gmail SMTP (Nodemailer) |
| β€οΈ Wishlist | Save favourite listings |
| β Reviews | Seller trust scores built from verified buyer reviews |
| π³ Stripe Payments | Secure checkout with Stripe |
| π Notifications | Real-time in-app notifications |
| π€ AI Listings | Gemini AI assists with listing title & description |
| π Admin Panel | Manage users and listings |
- React 18 + Vite
- Redux Toolkit β auth state management
- React Router v6 β client-side routing
- Axios β API client with auto token refresh
- Socket.IO Client β real-time chat
- Stripe.js β payment UI
- Tailwind CSS β utility-first styling
- React Hot Toast β notifications
- Node.js + Express 5
- MongoDB + Mongoose
- Socket.IO β real-time events
- JWT β access & refresh token auth
- Nodemailer β transactional email
- Cloudinary β image storage
- Stripe β payment processing
- Google Gemini AI β listing assistant
- Helmet + CORS β security
project1/
βββ server/ # Node.js Express backend
β βββ controllers/ # Route handlers (auth, listings, swaps...)
β βββ models/ # Mongoose schemas
β βββ routes/ # Express routers
β βββ middleware/ # Auth, error handling
β βββ services/ # Notification, email services
β βββ socket/ # Socket.IO chat handler
β βββ utils/ # Token generation, helpers
β βββ server.js # Entry point
β
βββ threadly/ # React frontend
βββ src/
β βββ pages/ # Route-level components
β β βββ Auth/ # Login, Register, ForgotPassword, ResetPassword
β β βββ Home.jsx
β β βββ Explore.jsx
β β βββ ListingDetail.jsx
β β βββ SwapPropose.jsx
β β βββ BuyerDashboard.jsx
β β βββ SellerDashboard.jsx
β β βββ ...
β βββ components/ # Shared UI components
β βββ services/ # API service functions
β βββ store/ # Redux store & slices
β βββ hooks/ # Custom hooks (useSocket)
βββ public/
βββ threadly.svg # Custom brand favicon
- Node.js 18+
- MongoDB Atlas account
- Cloudinary account
- Stripe account
- Gmail + App Password (for email)
git clone https://github.com/your-username/threadly.git
cd threadlycd server
npm installCreate server/.env:
PORT=5000
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret
JWT_REFRESH_SECRET=your_refresh_secret
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
GEMINI_API_KEY=your_gemini_key
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
CLIENT_URL=http://localhost:5173
NODE_ENV=development
EMAIL_USER=your_gmail@gmail.com
EMAIL_PASS=your_gmail_app_passwordnpm run devcd ../threadly
npm installCreate threadly/.env:
VITE_API_URL=http://localhost:5000
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_...npm run devApp runs at http://localhost:5173
Backend β Render
| Setting | Value |
|---|---|
| Root Directory | server |
| Build Command | npm install |
| Start Command | npm start |
Add all env vars from server/.env in the Render dashboard. Set CLIENT_URL to your Vercel frontend URL (no trailing slash).
Frontend β Vercel
| Setting | Value |
|---|---|
| Root Directory | threadly |
| Framework | Vite |
| Build Command | npm run build |
| Output Directory | dist |
Add in Vercel Environment Variables:
VITE_API_URL=https://your-render-api.onrender.com
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_...
Note:
vercel.jsonwith URL rewrites is included for React Router support.
Register / Login
β Access Token (localStorage, 15 min)
β Refresh Token (httpOnly cookie, 7 days)
Every API request β Authorization: Bearer <accessToken>
On 401 β Auto-refresh via /api/auth/refresh-token
Forgot Password Flow:
Enter email β Hashed token saved to DB (15 min TTL)
β Raw token sent via email link
User clicks link β Submits new password
β Token validated + cleared from DB
Threadly's swap system allows item-for-item exchanges:
- Sellers β Select one of their active listings to offer
- Buyers (no listings) β Describe their item via freeform form
- Receiver can accept, reject, or counter with a different item
- Proposer can accept the counter or cancel
| Home | Explore | Swap Propose |

MIT Β© 2025 Threadly β Give clothes a second life. π§΅