Thank you for your interest in contributing to LearnLens! This project is designed as a progressive learning tutorial for JavaScript, and we welcome contributions from learners, educators, and developers alike.
LearnLens is an educational platform that teaches JavaScript through building a real webcam filter application. Our goal is to help learners master JavaScript concepts from React basics to machine learning in the browser.
As someone going through the tutorial, you can contribute by:
- Report confusing sections - Help us improve explanations
- Suggest additional examples - Share what helped you understand
- Share your progress - Post your completed projects
- Ask questions - Your questions help improve documentation
- Fix typos or errors - Even small corrections matter!
As an instructor or mentor, you can contribute by:
- Classroom feedback - Share how the tutorial works in your classes
- Additional exercises - Suggest practice problems for each level
- Assessment materials - Create quizzes or project rubrics
- Supplementary guides - Add teaching notes or lesson plans
- Accessibility improvements - Help make content more inclusive
As an experienced developer, you can contribute by:
- Code improvements - Enhance existing features
- New features - Add educational features that teach concepts
- Performance optimizations - Improve app performance
- New filter effects - Create interesting visual effects
- Documentation - Improve technical explanations
- Create level branches - Help build the learning branches
The project is divided into 8 levels, each teaching specific concepts:
| Level | Topic | Key Concepts |
|---|---|---|
| 1 | React Basics | Components, State, Hooks |
| 2 | Webcam & Canvas | WebRTC, Canvas API |
| 3 | Filters & Effects | CSS Filters, Color Theory |
| 4 | Photo Capture | Canvas to Image, Downloads |
| 5 | Stickers & Drag | Events, Drag-and-Drop |
| 6 | AI Integration | APIs, Async/Await |
| 7 | AI Vision | Multimodal AI, Image Analysis |
| 8 | Face Detection | TensorFlow.js, ML Models |
main- Complete working code (reference implementation)level-N-topic- Learning branches with TODOs for studentslevel-N-solution- Solution branches for reference
README.md- Main project overview and learning roadmapdocs/README-LEVEL-N.md- Detailed tutorials for each levelCONTRIBUTING.md- This file (contribution guidelines).env.example- Environment variable template
If something in the tutorial is unclear:
**Issue**: Confusing explanation in Level 3
**Section**: README-LEVEL-3.md - "Color Theory Basics"
**What's confusing**:
The explanation of HSL vs RGB doesn't include examples of when to use each.
**Suggestion**:
Add a comparison table or real-world examples of when HSL is better than RGB.
**Your background**:
Beginner - completed Levels 1-2Before creating a bug report:
- Check existing issues to avoid duplicates
- Verify the bug exists in the latest version
- Try to reproduce it consistently
When reporting a bug:
**Bug**: Camera doesn't stop when switching modes
**Steps to reproduce**:
1. Start webcam in Level 2
2. Switch to Photos mode
3. Camera indicator stays on
**Expected**: Camera should stop
**Actual**: Camera keeps running
**Level**: Level 2 - Webcam & Canvas
**Environment**:
- Browser: Chrome 120
- OS: Windows 11
- Node: v18.0.0We especially welcome suggestions for:
-
Better Explanations
**Level**: 4 **Topic**: Base64 encoding **Current**: Technical explanation **Suggestion**: Add visual diagram showing how base64 works **Why**: Visual learners would benefit from seeing the encoding process
-
Additional Challenges
**Level**: 5 **Challenge**: Multi-finger pinch-to-zoom for stickers **Concepts taught**: Touch events, gesture recognition **Difficulty**: Advanced **Learning value**: Teaches advanced touch event handling
-
Better Examples
**Level**: 6 **Current example**: Basic API call **Suggested example**: API call with retry logic and exponential backoff **Reason**: Teaches real-world error handling patterns
When suggesting new features, consider the educational value:
**Feature**: GIF Export
**Educational Value**:
- Teaches: File APIs, ArrayBuffer, binary data manipulation
- Level: 4 (after Photo Capture)
- Complexity: Intermediate
**Implementation approach**:
- Use gif.js library
- Teach: npm package integration, third-party libraries
- Documentation: Explain how GIF encoding works
**Why it fits the curriculum**:
Natural progression after learning image capture and manipulation.- Node.js v14 or higher
- npm or yarn
- Git
- Modern web browser
- Webcam (for testing camera features)
- Google Gemini API key (for AI features)
-
Fork and clone
# Fork on GitHub, then: git clone https://github.com/YOUR-USERNAME/LearnLens.git cd LearnLens
-
Install dependencies
npm install
-
Set up environment variables
cp .env.example .env # Add your Gemini API key to .env -
Start development server
npm start
-
Create your branch
git checkout -b feature/your-contribution
Code in this project should be educational first:
// ❌ Clever but confusing for learners
const result = data.reduce((a, b) => ({...a, [b.id]: b}), {});
// ✅ Clear and educational
const result = {};
data.forEach(item => {
result[item.id] = item;
});
// Or with explanatory comments:
const result = data.reduce((accumulator, item) => {
// Build an object where each item's ID is the key
return { ...accumulator, [item.id]: item };
}, {});Comments should explain why and what learners gain:
// ❌ Obvious comment
// Set the filter
setActiveFilter(filterName);
// ✅ Educational comment
// Update active filter state, which triggers a re-render
// This demonstrates React's reactive data flow pattern
setActiveFilter(filterName);// ✅ Explain complex concepts
// We use requestAnimationFrame instead of setInterval because:
// 1. It syncs with browser repaints (smoother animation)
// 2. It pauses when tab is hidden (saves CPU)
// 3. It runs at optimal ~60 FPS automatically
requestAnimationFrame(renderLoop);Code should match the level's learning objectives:
// Level 1 (React Basics) - Simple, direct
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
// Level 4 (Advanced) - More sophisticated
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);Wait until appropriate levels to introduce:
- Level 1-2: Basic hooks, props, state
- Level 3-4: useCallback, useMemo (only if beneficial)
- Level 5-6: Custom hooks, context
- Level 7-8: Performance optimization patterns
For level branches, add educational TODOs:
// TODO: Implement the capturePhoto function
// HINT: Use canvas.toDataURL() to convert canvas to image
// LEARNING: This teaches you how browsers represent images as data
const capturePhoto = () => {
// Your code here
};Follow these conventions for consistency:
// ✅ Use functional components with hooks
const MyComponent = () => {
const [state, setState] = useState(initial);
return <div>{state}</div>;
};
// ✅ Use descriptive names
const [isLoading, setIsLoading] = useState(false);
const [userProfile, setUserProfile] = useState(null);
// ✅ Handle errors gracefully with user-friendly messages
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
} catch (error) {
console.error('Camera error:', error);
setError('Unable to access camera. Please check permissions.');
}
// ✅ Clean up resources in useEffect
useEffect(() => {
const interval = setInterval(() => {}, 1000);
return () => clearInterval(interval);
}, []);/* ✅ Use descriptive class names */
.filter-button { }
.filter-button.active { }
/* ✅ Follow existing naming conventions */
.section-header { }
.section-content { }
/* ✅ Comment complex CSS for learners */
/* Glassmorphism effect: semi-transparent background with blur */
.card {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
}When contributing to level READMEs:
-
Start with learning objectives
## 📚 Learning Objectives By the end of this level, you will be able to: - ✅ Understand concept A - ✅ Implement feature B - ✅ Apply pattern C
-
Explain concepts before code
- What is it?
- Why do we use it?
- When should you use it?
- How does it work?
-
Provide multiple examples
- Simple example first
- Complex example second
- Real-world use case third
-
Add practice exercises
- Guided tasks (step-by-step)
- Challenges (problem-solving)
- Extensions (creative exploration)
-
Include common pitfalls
**Common Mistake:** ❌ Forgetting to cleanup listeners **Correct Approach:** ✅ Always remove event listeners in cleanup function
# Level N: Topic 📚
## Learning Objectives
## What You'll Build
## Concepts Covered
### Concept 1
- Explanation
- Code examples
- Visual diagrams
### Concept 2
...
## Implementation Guide
### Step 1
### Step 2
...
## Practice Tasks
## Testing Your Knowledge
### Quiz Questions
### Challenges
## Additional Resources
## Key Takeaways
## Ready for Next Level?# Run all tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run tests with coverage
npm test -- --coverageTests should also be educational:
describe('Filter functionality', () => {
test('applies grayscale filter when button clicked', () => {
// LEARNING: Testing React components with user interactions
render(<App />);
// Find the button (accessible by text)
const grayscaleButton = screen.getByText(/grayscale/i);
// Simulate user click
fireEvent.click(grayscaleButton);
// Verify the filter was applied
expect(grayscaleButton).toHaveClass('active');
});
});Use clear, educational commit messages:
# ✅ Good - describes what and why
git commit -m "Add sticker rotation feature to Level 5"
git commit -m "Fix canvas cleanup in useEffect for Level 2"
git commit -m "Improve base64 explanation in Level 4 README"
# ❌ Bad - too vague
git commit -m "update"
git commit -m "fix bug"
git commit -m "changes"<type>(<level>): <description>
<body explaining educational value>
<footer>
Types:
feat- New feature (code or educational content)fix- Bug fixdocs- Documentation improvementstutorial- Tutorial content updatesexample- New examples or exercisesrefactor- Code improvements (maintaining functionality)
Examples:
feat(level-3): Add color picker for custom filters
- Adds color picker UI component
- Teaches input[type="color"] usage
- Demonstrates real-time state updates
- Includes practice exercise for HSL conversion
Addresses #45
docs(level-6): Improve async/await explanation
- Add visual flowchart of async execution
- Include common pitfalls section
- Add more real-world examples
- Simplify Promise chaining explanation
Helps learners understand asynchronous patterns better.
-
Ensure educational value
- Does this help learners understand concepts better?
- Is it appropriate for the target level?
- Does it follow the progressive learning path?
-
Update documentation
- Update README-LEVEL-N.md if needed
- Add code comments explaining concepts
- Update main README if adding features
-
Test thoroughly
- Test in multiple browsers
- Verify camera/AI features work
- Check that examples run correctly
- Validate all code snippets
-
Create Pull Request
- Fill out the template
- Explain educational impact
- Include screenshots if visual
- Link related issues
## Description
Brief description of changes and their educational value
## Type of Contribution
- [ ] Tutorial content (documentation, examples)
- [ ] Code feature (new functionality)
- [ ] Bug fix
- [ ] Educational improvements (better explanations)
## Target Level(s)
Which levels does this affect? (Level 1-8, or General)
## Educational Value
How does this help learners?
- What concepts does it teach?
- What skills will learners gain?
- How does it fit in the curriculum?
## Related Issues
Closes #issue-number
## Testing
- [ ] Code works in development
- [ ] Examples are accurate and tested
- [ ] No console errors
- [ ] Tested in Chrome/Firefox/Safari
- [ ] Accessible (keyboard navigation, screen readers)
## Screenshots (if applicable)
Add screenshots or GIFs demonstrating the feature
## Checklist
- [ ] Code includes educational comments
- [ ] Documentation updated
- [ ] Examples are clear and tested
- [ ] Follows project style guidelines
- [ ] No new warnings or errors
- [ ] Appropriate for target learning levelPerfect for beginners:
- Fix typos in documentation
- Improve code comments with better explanations
- Add examples to existing tutorials
- Create quiz questions for level READMEs
- Improve error messages to be more helpful
- Add visual diagrams to explain concepts
For those with some experience:
- Create new challenges for practice sections
- Add new filter effects with explanations
- Improve accessibility features
- Create video walkthroughs of levels
- Write supplementary guides (e.g., "Debugging Tips")
- Add keyboard shortcuts with documentation
For experienced developers:
- Create new learning levels (Level 9+)
- Build assessment tools for educators
- Add advanced features (video recording, effects timeline)
- Create alternative implementations (Vue.js version, etc.)
- Performance optimizations with educational explanations
- Create teaching resources (slides, workshop materials)
Contributors are recognized in:
- README.md - Contributors section
- Release notes - Feature acknowledgments
- Documentation - Author credits
- Special thanks - In tutorial materials
- Questions about learning: Open a GitHub Discussion
- Questions about contributing: Comment on issues
- Bug reports: Create an issue with "bug" label
- Feature suggestions: Create an issue with "enhancement" label
- Security concerns: Email maintainers privately
- Be welcoming - This is a learning environment for all skill levels
- Be patient - Everyone learns at their own pace
- Be helpful - Share knowledge generously
- Be respectful - Value diverse perspectives and experiences
- Be constructive - Offer helpful feedback, not criticism
- Use welcoming and inclusive language
- Respect different viewpoints and experiences
- Accept constructive feedback gracefully
- Focus on what's best for learners
- Show empathy toward other contributors
- Gatekeeping or elitism ("this is obvious")
- Dismissing beginners' questions
- Harassment or discriminatory language
- Publishing others' private information
- Unprofessional or disrespectful conduct
This project exists to help people learn JavaScript. Every contribution, whether it's:
- Fixing a typo
- Clarifying a confusing explanation
- Adding a new feature
- Helping another learner
...makes this educational resource better for everyone.
You're not just writing code—you're helping others learn to code. 🚀
Happy teaching and learning! 🎓
Questions? Open an issue or discussion—we're here to help!