See what sticks.
Gumroad is an e-commerce platform that enables creators to sell products directly to consumers. This repository contains the source code for the Gumroad web application.
Contributing
We don't run an inbound review queue on this repo. To contribute a change: fork the repo, open the pull request on your own fork, then email [email protected] with a link to it. We read every submission and merge the ones we want on our side, keeping your authorship — though we can't promise a reply to each one or a timeline.
Your PR still has to meet the same bar as our own work — visual evidence for anything user-facing, QA steps, test results, and an AI disclosure naming the model. See CONTRIBUTING.md for the full guidelines and the substitutions that apply when working from a fork.
Table of Contents
Getting Started
Prerequisites
💡 If you're on Windows, follow our Windows setup guide instead.
Before you begin, ensure you have the following installed:
Ruby
- https://www.ruby-lang.org/en/documentation/installation/
- Install the version listed in the .ruby-version file
Node.js
- https://nodejs.org/en/download
- Install the version listed in the .node-version file
Docker
We use Docker to setup the services for development environment.
- For MacOS: Download the Docker app from the Docker website
- For Linux:
sudo wget -qO- https://get.docker.com/ | sh
sudo usermod -aG docker $(whoami)
MySQL & Percona Toolkit
Install a local version of MySQL 8.0.x to match the version running in production.
The local version of MySQL is a dependency of the Ruby mysql2 gem. You do not need to start an instance of the MySQL service locally. The app will connect to a MySQL instance running in the Docker container.
- For MacOS:
brew install [email protected] percona-toolkit
brew link --force [email protected]
# to use Homebrew's `openssl`:
brew install openssl
bundle config --global build.mysql2 --with-opt-dir="$(brew --prefix openssl)"
# ensure MySQL is not running as a service
brew services stop [email protected]
- For Linux:
- MySQL:
- https://dev.mysql.com/doc/refman/8.0/en/linux-installation.html
apt install libmysqlclient-dev
- Percona Toolkit: https://www.percona.com/doc/percona-toolkit/LATEST/installation.html
- MySQL:
ImageMagick
We use imagemagick for preview editing.
- For MacOS:
brew install imagemagick - For Linux:
sudo apt-get install imagemagick
FFmpeg
We use ffprobe that comes with FFmpeg package to fetch metadata from video files.
- For MacOS:
brew install ffmpeg - For Linux:
sudo apt-get install ffmpeg
PDFtk
We use pdftk to stamp PDF files with the Gumroad logo and the buyers' emails.
- For MacOS: Download from here
- Note: pdftk may be blocked by Apple's firewall. If this happens, go to Settings > Privacy & Security and click "Open Anyways" to allow the installation.
- For Linux:
sudo apt-get install pdftk
wkhtmltopdf
While generating invoices, to convert HTML to PDF, PDFKit expects wkhtmltopdf to be installed on your system. Download and install the version 0.12.6 for your platform.
- Note similar to pdftk, this may also be blocked by Apple's firewall on MacOS. Follow a similar process as above.
Installation
Bundler and gems
We use Bundler to install Ruby gems.
gem install bundler
Install gems:
bundle install
Also make sure to install dotenv as it is required for some console commands:
gem install dotenv
npm and Node.js dependencies
Make sure the correct version of npm is enabled:
corepack enable
Install dependencies:
npm install
Configuration
Set up Custom credentials
App can be booted without any custom credentials. But if you would like to use services that require custom credentials (e.g. S3, Stripe, Resend, etc.), you can copy the .env.example file to .env and fill in the values.
Running Locally
Start Docker services
If you installed Docker Desktop (on a Mac or Windows machine), you can run the following command to start the Docker services:
make local
If you are on Linux, or installed Docker via a package manager on a mac, you may need superuser access to expose container ports. To do that, use sudo make local instead.
This command will not terminate. You run this in one tab and start the application in another tab.
If you want to run Docker services in the background, use LOCAL_DETACHED=true make local instead.
Set up the database
bin/rails db:prepare
For Linux (Debian / Ubuntu) you might need the following:
apt install libxslt-dev libxml2-dev
Start the application
bin/dev
This starts the Rails server, the JavaScript build system, and a Sidekiq worker.
You can now access the application at http://localhost:3000. Seller subdomains and the asset/api hosts use *.localhost (e.g. http://seller.localhost:3000, http://api.localhost:3000) — modern browsers auto-resolve these to 127.0.0.1, so no /etc/hosts edits are needed.
Local dev limitations
*.localhost over HTTP is treated as a secure context by browsers (so Stripe.js, Stripe Elements, and other secure-context APIs work), but a couple of features that need either HTTPS or a registrable cookie domain don't work in this setup:
- Apple Pay — Stripe requires HTTPS for Apple Pay domain registration. Workaround: expose the app over HTTPS with ngrok (
ngrok http 3000) and register the resulting hostname in the Stripe Apple Pay dashboard. - Cross-subdomain cookies (affiliate attribution,
_gumroad_guid, multi-account "switch seller", session) — browsers rejectDomain=localhost, so cookies set onlocalhost:3000aren't sent toseller.localhost:3000. Test these flows on a single host, or front the app with a local HTTPS reverse proxy on a registrable hostname (e.g.gumroad.testvia mkcert) whereDomain=.gumroad.testworks.
Testing
Run the full test suite:
bin/rspec
Run a single file or specific test:
bin/rspec spec/requests/dashboard_spec.rb
bin/rspec spec/requests/dashboard_spec.rb:75
Dependencies
Before running tests:
make local # start Docker services (db, Redis, etc.)
RAILS_ENV=test bin/rails db:setup # set up the test database
RAILS_ENV=test bin/rails js:export # generate JS constants for the test environment
Integration tests
Integration specs use Capybara with Selenium driving Chrome. Install Chrome from google.com/chrome.
See docs/testing.md for details on preventing flaky specs, VCR cassettes, debugging widgets, and purchase testing with Stripe/PayPal.
Development
Logging in
You can log in with the username [email protected] and the password password. The two-factor authentication code is 000000.
Read more about logging in as a user with a different team role at Users & authentication.
Resetting Elasticsearch indices
You will need to explicitly reindex Elasticsearch to populate the indices after setup, otherwise you will see index_not_found_exception errors when you vis