Getting Started
Thank you for contributing to Gumroad! This guide will help you write high-quality code and create effective pull requests.All contributors must follow these guidelines. Pull requests that don’t meet these standards may be rejected or require significant revisions.
Communication Standards
Use native-sounding English in all communication:- ❌ Bad: “HOW IS THIS GOING???”, “how’s dis going”, “thnx fr update”
- ✅ Good: “Is this actively being worked on? I’ve started work on it here…”
- Excessive capitalization
- Multiple question marks
- Grammatical errors
- Typos
- Informal abbreviations
Pull Request Guidelines
Required Elements
Every non-trivial pull request must include:PR Description Structure
Non-trivial PRs should follow this format:PR Size Guidelines
Testing Requirements
Your PR must:- Include tests for all new features
- Update existing tests for modified features
- Include end-to-end tests for user-facing changes
- Show test results passing locally
Tests must fail when the fix is reverted. If the test passes without the application code change, it is invalid.
Code Standards
General Principles
Always write the code
Always write the code
Don’t leave TODOs or placeholders. Complete the implementation in your PR.
No comments in code
No comments in code
Code should be self-documenting. Don’t leave explanatory comments. Use clear variable and method names instead.
Don't apologize for errors
Don't apologize for errors
Just fix them. Don’t add comments saying “sorry” or “I know this is bad”.
Business logic in Rails
Business logic in Rails
Pricing, calculations, and discount application belong in Rails, not the frontend. The frontend renders state provided by the backend. Enforce all constraints on the server.
Language Versions
Always use the latest stable versions:- Ruby 3.4.3
- Rails 7.1.6
- TypeScript 5.5.0
- React 18.1.0
- Node 20.17.0
Code Style
Text Formatting
Use sentence case, not title case:- ✅ “Save changes”
- ❌ “Save Changes”
Constants
Assign raw numbers to named constants:Testing Guidelines
Test Structure
Test Data
- Use factories for test data instead of creating objects directly
- Use
@example.comfor emails in tests - Use
example.com,example.org,example.netfor custom domains - Write descriptive test names that explain the behavior
- Keep tests independent and isolated
- Group related tests together
VCR Cassettes
Sidekiq Assertions
Sidekiq Jobs
Naming Convention
New Sidekiq job class names must end with “Job”:Queue Selection
Queue priorities (highest to lowest):- critical - Receipt/purchase emails only
- default - Time-sensitive background jobs
- low - Most background jobs (use this by default)
- mongo - Legacy queue for one-time scripts
Job Deduplication
For deduplication using sidekiq-unique-jobs:Feature Development
Feature Flags
Use feature flags (Flipper) for new features:Database Patterns
No foreign key constraints
No foreign key constraints
Do not use database-level foreign key constraints (
add_foreign_key). This simplifies data migration and sharding operations at scale.Copy values, don't reference
Copy values, don't reference
When creating financial records (receipts, sales), copy specific values (amount, currency, percentage) at purchase time instead of referencing mutable data like a
DiscountCode ID. This ensures historical records remain accurate if the original object is edited or deleted.Reuse deprecated flags
Reuse deprecated flags
Prefer re-using deprecated boolean flags instead of creating new ones. Deprecated flags are named
DEPRECATED_<something>. Reset values on staging and production first, then rename.Backfilling Data
Why:- Gumroad has millions of users and products
- Callback-based backfilling can enqueue millions of uncontrollable jobs
- This can crash Sidekiq (Redis out of memory)
- Creates massive replica lag
Code Organization
File Locations
Concerns
Don’t create new files in
app/modules/ (legacy). Use concerns in the right directory: app/models/concerns/, app/controllers/concerns/Path/URL methods
Don’t create methods ending in
_path or _url - they might collide with Rails route helpers. Use a module like CustomDomainRouteBuilderPublic IDs
Use Nano IDs to generate external/public IDs for new models
Modern naming
Use
product instead of link, buyer instead of customer, seller instead of creator in new codeWriting Issues
Issue Structure
Issues for enhancements, features, or refactors:Writing Bug Reports
A great bug report includes:Steps to reproduce
Be specific! Include:
- Exact steps taken
- Sample code if applicable
- Environment details
Code Patterns to Avoid
Reasoning Over Changes
Explain the reasoning behind your changes, not just the change itself:- Describe the architectural decision
- Identify the specific problem being solved
- For bug fixes, identify the root cause
- Don’t apply a fix without explaining how the invalid state occurred
Reviewers need to understand WHY you made these changes, not just WHAT changed.
Help Wanted
Looking for issues to contribute to? Any issue with labelhelp wanted is open for contributions: View open issues
License
By contributing, you agree that your contributions will be licensed under the MIT License.Next Steps
Architecture
Understand the system architecture
Testing
Write comprehensive tests
Authentication
Learn authentication patterns
Deployment
Deploy your changes