First off — thank you for taking the time to contribute! 🎉
Whether you're fixing a bug, adding a feature, improving docs, or just asking a question — every contribution matters and you are welcome here.
This guide will walk you through everything you need to know to contribute to FitMart, whether you're contributing to open source for the first time or you're a seasoned developer.
- Code of Conduct
- How Can I Contribute?
- Getting Started (Step-by-Step)
- Picking an Issue
- Branching Strategy
- Making Your Changes
- Commit Message Convention
- Submitting a Pull Request
- PR Review Process
- Project Structure Reference
- Style Guide
- Need Help?
By participating in this project, you agree to be respectful and constructive. We expect everyone to:
- Use welcoming and inclusive language
- Be respectful of different viewpoints and experiences
- Gracefully accept constructive feedback
- Focus on what's best for the community
Harassment or toxic behavior of any kind will not be tolerated.
You don't need to write code to contribute! Here are all the ways you can help:
| Type | Examples |
|---|---|
| 🐛 Bug Fix | Fix broken functionality, handle edge cases |
| ✨ New Feature | Add something new to the app |
| 📖 Documentation | Improve README, add JSDoc comments, fix typos |
| 🎨 UI/UX | Improve design, responsiveness, accessibility |
| 🧪 Tests | Add unit or integration tests |
| 🔧 Refactor | Clean up code without changing behavior |
| 💬 Discussion | Comment on issues, review PRs, share ideas |
If this is your first time contributing to open source, follow every step below. Don't skip anything!
Go to the FitMart GitHub page and click the Fork button (top right corner).
This creates your own copy of the project under your GitHub account.
git clone https://github.com/<your-username>/FitMart.git
cd FitMartReplace
<your-username>with your actual GitHub username.
This connects your local copy to the original FitMart repo so you can pull in future updates:
git remote add upstream https://github.com/parthnarkar/FitMart.gitVerify it worked:
git remote -v
# Should show both origin (your fork) and upstream (original)Follow the Quick Start guide in README.md to get both the client and server running locally.
You will need accounts or API keys for the following services:
| Service | Required? | Purpose |
|---|---|---|
| MongoDB Atlas (or local) | ✅ Required | Primary database |
| Firebase | ✅ Required | Authentication |
| Razorpay | Payment processing | |
| Google Gemini API | AI chatbot | |
| RapidAPI (ExerciseDB) | Exercise library | |
| SMTP provider | Transactional emails |
✅ Make sure the app runs on your machine before making any changes. Optional services fail gracefully — you don't need all of them to run the app locally.
Before starting any new work, always sync with the latest changes from the original repo:
git checkout main
git fetch upstream
git merge upstream/main
git push origin mainBrowse the Issues tab and look for these labels:
| Label | Meaning |
|---|---|
good first issue |
🌱 Great for beginners — well-scoped and documented |
help wanted |
Open for anyone to pick up |
bug |
Something is broken |
enhancement |
New feature or improvement |
documentation |
Docs-related work |
Always comment on the issue first! Say something like:
"Hey, I'd like to work on this! I'll have a PR ready by [rough timeline]."
This prevents two people from working on the same thing. The maintainer will assign it to you.
If you're not sure where to start, here are some concrete areas that always benefit from attention:
- Replacing any hardcoded
http://localhost:5000API URLs withimport.meta.env.VITE_API_URL - Improving responsiveness of existing pages on mobile viewports
- Adding JSDoc comments to utility functions in
client/src/utils/ - Writing more thorough input validation on form components
- Improving accessibility (ARIA labels, keyboard navigation)
Open a new issue first and describe what you'd like to do. Wait for a maintainer to respond before starting large changes — this avoids wasted effort.
Never commit directly to main. Always work on a separate branch.
Use this format: type/short-description
# Examples:
git checkout -b fix/cart-reservation-bug
git checkout -b feat/product-search
git checkout -b docs/improve-contributing-guide
git checkout -b refactor/api-url-standardize
git checkout -b feat/workout-sync| Prefix | Use For |
|---|---|
feat/ |
New features |
fix/ |
Bug fixes |
docs/ |
Documentation changes |
refactor/ |
Code cleanup |
test/ |
Adding/updating tests |
chore/ |
Build scripts, config, etc. |
-
Make sure you're on your feature branch:
git checkout -b feat/your-feature-name
-
Make your changes in small, logical steps.
-
Test your changes locally — make sure everything still works.
-
If you've added a new route to the server, verify it appears correctly in the API Reference section of the README, and update it if not.
-
If you've added a new page or component, verify the Project Structure in the README accurately reflects it.
-
Stage and commit your changes (see commit format below):
git add . git commit -m "feat: add product search functionality"
-
Push to your fork:
git push origin feat/your-feature-name
We follow the Conventional Commits standard. This keeps the history clean and readable.
type(scope): short description
[optional longer description]
[optional: closes #issue-number]
feat(cart): add quantity update button on cart page
fix(auth): resolve Google sign-in redirect loop
docs(readme): add environment variable instructions
refactor(client): replace hardcoded API URLs with VITE_API_URL
feat(exercises): add exercise browser with ExerciseDB integration
fix(chatbot): add Gemini fallback responses for API unavailability
chore: update dependencies| Type | When to Use |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only |
style |
Formatting (no logic change) |
refactor |
Code restructure (no feature/fix) |
test |
Adding or updating tests |
chore |
Build, config, tooling changes |
💡 Keep the subject line under 72 characters and in lowercase.
Once your changes are pushed to your fork:
- Go to the original FitMart repo.
- You'll see a "Compare & pull request" banner — click it.
- Fill out the PR template completely (see below).
- Set the base branch to
main. - Click "Create Pull Request".
Use the same convention as commits:
feat(product): add product filter by category
fix(payment): handle failed payment edge case
docs(contributing): update env variable table
Please fill this out when opening a PR:
## 📋 What does this PR do?
A clear summary of the changes made.
## 🔗 Related Issue
Closes #<issue-number>
## 🧪 How was this tested?
Describe how you tested your changes (manual steps, screenshots, etc.)
## 📸 Screenshots (if UI changes)
Before / After screenshots if you changed any UI.
## ✅ Checklist
- [ ] I've read the CONTRIBUTING guide
- [ ] My code follows the project's style guidelines
- [ ] I've tested my changes locally
- [ ] I've linked the related issue
- [ ] I haven't introduced any new secrets or API keys
- [ ] I've updated README.md if I added a new route, page, component, or env variableAfter you open a PR:
- Automated checks may run (linting, etc.) — make sure they pass.
- The maintainer (Parth) will review your PR and may leave comments.
- If changes are requested:
- Make the changes on the same branch
- Push the new commits — the PR updates automatically
- Reply to comments once addressed
- Once approved, your PR will be merged 🎉
⏱️ Be patient — reviews can take a few days. Feel free to ping if there's no response after a week.
FitMart/
├── client/ # React + Vite Frontend
│ ├── src/
│ │ ├── components/ # Reusable UI components (uses Framer Motion for animations)
│ │ ├── auth/ # Firebase auth setup & hooks
│ │ ├── pages/ # Route-level page components
│ │ └── utils/ # Helper/utility functions
│ └── .env.local # ⚠️ Not committed — create manually
│
├── server/ # Node.js + Express Backend
│ ├── middleware/ # Express middleware (logger, auth verification)
│ ├── models/ # Mongoose schemas
│ ├── routes/ # Route handlers
│ ├── services/ # Business logic services (email, etc.)
│ ├── db.js # MongoDB connection
│ ├── firebaseAdmin.js # Firebase Admin SDK setup
│ ├── index.js # Server entry point (middleware, routes, error handler)
│ ├── seed.js # Product DB seed script
│ └── seedFitnessCenters.js # Fitness center DB seed script
│
└── docs/
├── CONTRIBUTING.md # This file
├── FIRST_PURCHASE_EMAIL_SETUP.md # Email feature setup guide
└── SECURITY.md # Responsible disclosure policy
Adding a new backend route:
- Create your route file in
server/routes/your-feature.js - Register it in
server/index.jswithapp.use('/api/your-feature', require('./routes/your-feature')) - Create the corresponding Mongoose model in
server/models/YourModel.jsif needed - Update the API Reference table in
README.md
Adding a new frontend page:
- Create your component in
client/src/pages/YourPage.jsx - Import it in
client/src/App.jsxand add the<Route>entry - Update the Pages & Routes table in
README.md - If your page needs auth guarding, wrap it in
<AdminRoute>or<NonAdminRoute>
Adding a new environment variable:
- Add it to
server/.envorclient/.envlocally - Document it in the Environment Variables section of
README.md - Add a
.env.exampleentry if one exists for that directory
Adding a new service (email, third-party API, etc.):
- Create it in
server/services/your-service.js - Fail gracefully when env variables are missing — never crash the server
- Document the required env variables in
README.mdanddocs/FIRST_PURCHASE_EMAIL_SETUP.md(or a new doc) if the setup is non-trivial
- Use functional components with hooks (no class components)
- Prefer
constoverlet; avoidvar - Use async/await over raw Promises where possible
- Keep components small and single-purpose
- Name component files with PascalCase (e.g.,
ProductCard.jsx) - Name utility files with camelCase (e.g.,
formatPrice.js) - Use the
normalizeProductutility fromclient/src/utils/normalizeProduct.jswhen working with product data from the API to safely handle bothidandproductIdfields
- Use Tailwind utility classes wherever possible
- Stick to the
stone-*color palette only — no blue, green, or purple (see the Design System inclient/DesignSystem.md) - Keep custom CSS to a minimum
- Ensure UI is responsive and works on mobile
- Use
rounded-fullfor buttons,rounded-2xlfor cards, androunded-lgfor inputs - Always precede major section headings with the eyebrow label pattern:
text-xs tracking-[0.2em] uppercase text-stone-400 - Use
DM Serif Displayfor headings andDM Sansfor body/UI text
- Keep route files focused on a single resource
- Put business logic and reusable logic in
server/services/— not directly in routes - Always validate input (required fields, types) and return clear error messages
- Always handle errors with try/catch and return a clean JSON error response
- Use the
verifyFirebaseTokenmiddleware fromserver/middleware/verifyFirebaseToken.jsfor any endpoint that requires a logged-in user - Never log or expose sensitive values (API keys, passwords) — the request logger already redacts
password,token,secret, andapiKeykeys - New services that depend on env variables must fail gracefully (log a warning, return null, and allow the rest of the app to function) — do not call
process.exit()
- Use Framer Motion for all UI animations — page transitions, modal entrances, hover effects
- Keep animations quick (150-300ms) and subtle — no distracting or overly complex movements
- Prefer
motioncomponents over CSS transitions for interactive elements - Use
AnimatePresencefor exit animations on unmounting components - Example pattern:
import { motion, AnimatePresence } from 'framer-motion'; <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.2 }} >
- No hardcoded URLs — use
import.meta.env.VITE_API_URLon the client and environment variables on the server - No committed secrets —
.envfiles are gitignored for a reason - Delete commented-out code before submitting a PR
- Write clear variable and function names — code should read like English
- When touching
UserProfile, remember it tracksemail,firstPurchaseEmailSentAt, andlastReminderEmailSentAtfor the email services — don't overwrite these fields unintentionally - Animations — Use Framer Motion for all animations and transitions (page entrances, modals, hover effects, etc.). Keep animations subtle and performant — avoid over-animating.
Stuck? Don't worry — everyone was a beginner once.
- 💬 Comment on the issue you're working on with your question
- 🐛 Open a new issue with the
questionlabel - 📖 Re-read the README — the setup steps cover most common problems
- 🔐 For security issues, follow the responsible disclosure process in
docs/SECURITY.md— do not open a public issue
There are no dumb questions. Ask away! 🙌
Happy coding! We're glad you're here. 🚀
Made with ❤️ by Parth Narkar and the Parth Builds Community