⚡ SkillSwap — Project Story

🌟 Inspiration

The idea came from a simple frustration — great skills exist everywhere, but quality learning is locked behind paywalls. A friend wanted to learn web development but couldn't afford courses. He already knew graphic design — something others were paying hundreds for. That sparked the question:

Why can't people just trade what they know?

SkillSwap was born from that — a platform where knowledge is the only currency, and everyone has something worth sharing.


🛠️ How We Built It

Layer Technology
Frontend React, Vite, Redux Toolkit, Tailwind CSS
Backend Node.js, Express.js, Socket.io, Passport.js
Database PostgreSQL + Supabase + Drizzle ORM
Auth Google OAuth 2.0 + JWT + OTP Email Verification
Real-time Socket.io (chat) + WebRTC (video)
Deployment Vercel (frontend) + Render (backend)

📚 What We Learned

  • Real-time systems with Socket.io across separate deployment domains require careful CORS and transport configuration
  • OAuth 2.0 flows are extremely sensitive — a single character mismatch in redirect URIs breaks the entire auth flow
  • Designing a fair skill exchange system requires as much UX thinking as technical implementation
  • Drizzle ORM + Supabase connection pooling behaves differently from standard PostgreSQL drivers

⚡ Challenges We Faced

1. Cross-Domain Authentication

Deploying frontend on Vercel and backend on Render meant Google OAuth redirect URIs had to be perfectly matched — a single typo broke everything.

2. Real-time Across Domains

Socket.io connections fail silently when CORS isn't configured correctly for separate domains. Debugging this took significant time.

3. Ephemeral File Storage

Render's free tier has no persistent disk — file uploads vanished on every redeploy. Solved by integrating Supabase Storage.

4. Session Planning Logic

Both users get a fair, auto-calculated exchange plan using:

$$\text{Sessions} = \left\lceil \frac{\text{Total Hours}}{\text{Hours per Session}} \right\rceil$$

So if User A needs 6 hours of Python and each session is 1.5 hours:

\( \lceil 6 / 1.5 \rceil = 4 \text{ sessions} \)

5. Database Connection Pooling

Supabase required prepare: false in the Drizzle config to prevent prepared statement conflicts under connection pooling.


🚀 What's Next

  • 📱 Mobile App — React Native for iOS & Android
  • 🤖 AI Skill Matching — Smart recommendations based on goals
  • 💬 Community Forums — Per-skill category discussions
  • 🏆 Reputation System — Endorsements & verified skill badges

🔗 Links


"Everyone knows something worth sharing — SkillSwap just makes it possible."

Built With

Share this project:

Updates