How to Contribute to holehe Development: A Complete Guide for Open-Source Contributors

Contribute to holehe by forking the repository, adding or improving modules in holehe/modules/, and submitting a pull request that follows the project's async check() pattern and module structure.

Holehe is a Python-based open-source tool maintained by megadose that verifies whether an email address is registered across hundreds of online services. If you want to expand its coverage or improve existing functionality, this guide walks you through the exact contribution workflow based on the actual source code structure.

Understanding the holehe Codebase Structure

Before making changes, familiarize yourself with how the project organizes its code. This knowledge prevents structural mistakes and ensures your contribution integrates seamlessly.

Core Architecture

  • holehe/core.py – Contains the Holehe orchestration class that discovers modules and executes checks
  • holehe/modules/ – Category-based subdirectories holding individual service implementations
  • setup.py – Declares dependencies, entry points, and packaging metadata
  • .github/workflows/codeql-analysis.yml – CI pipeline that validates pull requests

Each service lives in a category folder such as music/, programming/, or social/, following the pattern established by existing modules like holehe/modules/music/spotify.py.

Setting Up Your Development Environment

A proper local setup lets you test changes before submitting. Install holehe in editable mode so code modifications take effect immediately.


# Fork the repository on GitHub, then clone your fork

git clone https://github.com/<your-username>/holehe.git
cd holehe

# Install in editable mode with all dependencies

pip install -e .

Verify the installation works:

holehe -u test@example.com

Adding a New Service Module

New modules follow a strict async pattern. Study holehe/modules/music/spotify.py or holehe/modules/software/docker.py as reference implementations.

Step-by-Step Module Creation

1. Choose the correct category folder

Place your module under the appropriate subdirectory of holehe/modules/. Create a new category folder if no existing one matches your service.

2. Implement the check() function

All modules expose an async function (or class method) named check returning a standardized dictionary:


# file: holehe/modules/website/example.py

import aiohttp
from holehe.core import BaseModule

class Example(BaseModule):
    async def check(self):
        """Check if email is registered on example.com."""
        url = "https://example.com/api/users/check"
        
        async with self.session.get(url, params={"email": self.email}) as response:
            data = await response.json()
            
            return {
                "name": "example",
                "domain": "example.com",
                "method": "register",
                "frequent_rate_limit": False,
                "rateLimit": False,
                "exists": data.get("user_exists", False),
                "emailrecovery": None,
                "phoneNumber": None,
                "others": None
            }

3. Use the central logger for debug output

Import and use holehe.logger as demonstrated in holehe/modules/software/docker.py:

from holehe.core import logger

logger.debug(f"Checking {self.email} against example.com")

4. Register your module

Ensure the module is importable so check_all() discovers it. The project typically uses an auto-loader or explicit imports in holehe/__init__.py.

Testing Your Changes

Validate functionality before committing. Run both automated tests and manual verification.


# Run pytest if configured

pytest

# Manual verification with your specific module

python -c "
from holehe.modules.website.example import Example
import asyncio

async def test():
    ex = Example('youremail@example.com')
    result = await ex.check()
    print(result)

asyncio.run(test())
"

Test edge cases: rate-limited responses, invalid emails, and service downtime.

Committing and Opening a Pull Request

Clean git history and clear communication speed up review.

Branch Naming and Commits


# Create descriptive branch

git checkout -b add-strava-module

# Make atomic commits with clear messages

git commit -m "Add Strava fitness platform email check module"

Pull Request Requirements

Include in your PR description:

  • Summary – What service you added or what bug you fixed
  • Issue reference – Closes #42 if addressing a reported issue
  • Testing notes – How you verified the module works
  • Documentation update – Confirm you edited the Supported services table in README.md

The maintainers will trigger the CodeQL workflow defined in .github/workflows/codeql-analysis.yml to analyze your code for security issues and style problems.

Improving Existing Modules

Refactoring contributions are equally valuable. Common improvement areas include:

  • Regex pattern updates – Sites change their registration flows; update detection logic in modules like holehe/modules/programming/github.py
  • Rate-limit handling – Add intelligent backoff or frequent_rate_limit flags
  • Error resilience – Wrap HTTP calls in try/except blocks with proper logging

When modifying existing code, preserve the original function signature and return structure to maintain backward compatibility.

Staying Aligned with Project Standards

Holehe has no separate CONTRIBUTING.md, so follow these implicit conventions visible throughout the codebase:

  • Async/await throughout – All network operations must be non-blocking
  • Consistent return dictionaries – Include all standard keys even if None
  • Minimal dependencies – Prefer standard library and aiohttp; add new requirements to setup.py only when essential
  • Categorized organization – Respect the existing folder hierarchy for service types

Summary

  • Fork the megadose/holehe repository and install locally with pip install -e .
  • Study existing modules in holehe/modules/ to understand the async check() pattern
  • Place new modules in appropriate category subdirectories and use holehe.logger for debugging
  • Register modules properly so holehe.core.Holehe discovers them during check_all()
  • Run tests manually and verify with holehe -u <email> before submitting
  • Write clear commit messages and comprehensive PR descriptions referencing any related issues
  • Update README.md to document new supported services

Frequently Asked Questions

Does holehe require a formal CLA or contributor agreement?

No. The repository does not specify a Contributor License Agreement. By submitting a pull request, you agree to license your contribution under the same terms as the project's existing license. Review the repository's license file for specifics.

What Python version should I target for holehe contributions?

The setup.py file determines supported versions. Based on the codebase structure and common practice for similar tools, Python 3.7+ with async/await support is expected. Verify by checking python_requires in setup.py and test your changes against the minimum specified version.

How do I handle services that block or rate-limit holehe checks?

Set frequent_rate_limit: True in your return dictionary and implement exponential backoff using asyncio.sleep(). Study modules with similar behavior, and ensure your code gracefully handles HTTP 429 responses without crashing the entire check sequence.

Can I contribute documentation or translation improvements?

Yes. Documentation contributions follow the same PR workflow. Edit README.md directly for user-facing changes. The project does not currently maintain separate translation infrastructure, so focus on improving the English documentation clarity or adding clarifying comments within module source files.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →