Thank you for your interest in contributing! 🎉
If you find a bug or have a suggestion:
- Check if the issue already exists
- Create a new issue with:
- Clear title and description
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Your environment (OS, Node version, etc.)
You can help by:
- Fixing typos or errors in README files
- Improving explanations - make concepts clearer
- Adding better examples - show real-world usage
- Enhancing tests - add edge cases
- Completing Levels 4-15 - fill in placeholder exercises
When creating a new exercise:
-
Follow the existing structure:
exercises/XX-topic/YY-exercise-name/ ├── README.md ├── exercise.ts ├── solution.ts └── exercise.test.ts -
README.md should include:
- Concept explanation
- Assignment description
- Examples
- Hints
- Bonus challenges
-
exercise.ts should have:
- Clear TODO comments
- Type signatures
- Function stubs
-
solution.ts should show:
- Reference implementation
- Comments on complex parts
- Best practices
-
exercise.test.ts should cover:
- Happy path
- Edge cases
- Error scenarios
- Fork the repository
- Create a branch from
main:git checkout -b feature/improve-error-handling
- Make your changes
- Run tests:
npm test npm run check - Commit with clear messages:
git commit -m "feat: add advanced error handling examples" - Push to your fork:
git push origin feature/improve-error-handling
- Create a Pull Request with:
- Description of changes
- Why the change is needed
- Any breaking changes
We use conventional commits:
feat:- new feature or exercisefix:- bug fixdocs:- documentation changestest:- test additions or fixesrefactor:- code refactoringchore:- maintenance tasks
Examples:
feat: add Deferred exercise to advanced concurrency
fix: correct type signature in flatMap example
docs: improve explanation of Effect.gen
test: add edge cases for error handling
- Use TypeScript strict mode
- Follow existing code formatting
- Add comments for complex logic
- Keep functions focused and small
- Use descriptive variable names
All exercises must have tests:
import { describe, expect, it } from "@effect/vitest"
import { Effect } from "effect"
import * as Exercise from "./exercise"
describe("exercise-name", () => {
it("should handle basic case", () => {
const result = Effect.runSync(Exercise.myFunction(input))
expect(result).toBe(expected)
})
it("should handle edge case", () => {
// Test edge cases
})
it("should handle errors", () => {
const exit = Effect.runSyncExit(Exercise.myFunction(badInput))
expect(Exit.isFailure(exit)).toBe(true)
})
})When writing documentation:
- Use clear, simple language
- Provide practical examples
- Explain the "why", not just the "what"
- Link to official Effect docs when relevant
- Use code blocks with syntax highlighting
- Ask in Effect Discord
- Open a GitHub Discussion
- Tag maintainers in your PR
# Clone your fork
git clone https://github.com/yourusername/effect-learn.git
cd effect-learn
# Install dependencies
npm install
# Run tests
npm test
# Type check
npm run check
# Build
npm run buildeffect-learn/
├── exercises/ # All exercises
├── scripts/ # Helper scripts
├── test/ # Additional tests
├── README.md # Main documentation
├── GUIDE.md # User guide
├── CONTRIBUTING.md # This file
└── PROJECT_STATUS.md # Current status
Contributors will be:
- Listed in the README
- Mentioned in release notes
- Credited in commit history
Thank you for helping make Effect more accessible to everyone! 🚀