# What Asynchronous Library Does Holehe Use? Exploring Trio and httpx

> Discover Holehe's asynchronous libraries. Holehe leverages Trio for task orchestration and httpx for efficient non-blocking HTTP requests, enhancing performance.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: deep-dive
- Published: 2026-09-01

---

**Holehe uses Trio for asynchronous task orchestration and httpx's `AsyncClient` for non-blocking HTTP requests**, combining a structured concurrency runtime with a modern async HTTP client.

[Holehe](https://github.com/megadose/holehe) is an OSINT tool that checks whether an email address is registered across hundreds of websites. Its performance depends on executing hundreds of network requests concurrently without blocking. The project achieves this through a deliberate two-layer async architecture: **Trio** manages the concurrent execution flow, while **httpx** handles the actual HTTP I/O.

## Core Asynchronous Stack: Trio + httpx

Holehe's concurrency model separates concerns between task scheduling and network operations. This design provides structured concurrency guarantees that prevent common async pitfalls like unbounded growth or orphaned tasks.

### Trio: Structured Concurrency Runtime

In [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py), the main entry point imports Trio and creates a **nursery**—Trio's primitive for managing concurrent tasks:

```python

# holehe/core.py – Trio provides the async runtime

import trio
import httpx

async def maincore():
    # ...

    client = httpx.AsyncClient(timeout=10)
    async with trio.open_nursery() as nursery:      # ← Trio nursery

        for website in websites:
            nursery.start_soon(launch_module, website, email, client, out)
    await client.aclose()

```

The `async with trio.open_nursery()` context manager ensures all spawned tasks complete before exiting, even if errors occur. This **structured concurrency** approach eliminates the "fire and forget" anti-pattern common in other async frameworks.

### httpx: Async HTTP Client

While Trio orchestrates execution, **network I/O** is delegated to `httpx.AsyncClient`. The client is instantiated once and shared across all site-checking coroutines:

```python

# holehe/core.py L13-L14

client = httpx.AsyncClient(timeout=10)

```

Each module receives this client instance and performs non-blocking requests:

```python

# Example: holehe/modules/social_media/twitter.py

async def twitter(email, client, out):
    response = await client.get("https://api.twitter.com/...")
    # Process response without blocking other concurrent checks

```

## Why This Combination Matters

| Component | Role | Benefit |
|-----------|------|---------|
| **Trio** | Task scheduling, cancellation, error propagation | Prevents resource leaks; enforces clean shutdown |
| **httpx** | HTTP/1.1 and HTTP/2 requests, connection pooling | Modern API, `async`/`await` native, faster than `requests` |

This architecture enables Holehe to check hundreds of websites simultaneously while maintaining predictable resource usage. The Trio nursery guarantees that if one site check fails, others continue and all resources are properly cleaned up.

## Key Implementation Files

Understanding which asynchronous library Holehe uses requires examining these specific source locations:

- **[`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)** (L4-L5, L13-L14, L18-21): Imports Trio, creates the `httpx.AsyncClient`, and schedules all module execution via `nursery.start_soon()`
- **`holehe/modules/`** subdirectories: Each site's `async def <site>(email, client, out)` function executes within the Trio-managed nursery

Every module follows the same contract: accept the shared httpx client, perform async HTTP operations, and write results to the `out` dictionary. This uniformity allows Trio to schedule them interchangeably.

## Comparison with Alternatives

Holehe could have used other async libraries, but the Trio + httpx combination offers distinct advantages:

- **asyncio + aiohttp**: More common, but lacks Trio's structured concurrency; cancellation is less reliable
- **asyncio + httpx**: Trio's cancellation semantics are more robust than asyncio's
- **anyio**: Holehe does not use this; it uses Trio directly

According to the holehe source code, the direct Trio dependency (`import trio`) indicates the authors prioritized correctness guarantees over ecosystem familiarity.

## Summary

- Holehe's **asynchronous library is Trio**, used for structured task concurrency via nurseries
- **httpx's `AsyncClient`** provides non-blocking HTTP requests, not Trio itself
- The pattern appears in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py): `trio.open_nursery()` schedules modules that receive a shared `httpx.AsyncClient`
- This stack ensures hundreds of simultaneous site checks execute safely without resource leaks

## Frequently Asked Questions

### Does Holehe use asyncio or Trio?

Holehe uses **Trio**, not asyncio. The [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) file imports `trio` directly and uses `trio.open_nursery()` to manage concurrent execution. This is a deliberate architectural choice for structured concurrency.

### Why does Holehe use httpx instead of aiohttp?

Holehe uses **httpx** because it provides a modern, `requests`-compatible API with native async support. The `httpx.AsyncClient` accepts the same parameters as synchronous clients and supports HTTP/2, making it ideal for high-concurrency OSINT operations.

### Can I use Holehe's modules with asyncio instead of Trio?

No—Holehe's modules are designed for Trio's nursery pattern and cancellation semantics. While `httpx` works with both asyncio and Trio, the module execution in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) specifically uses `trio.open_nursery()` and `nursery.start_soon()`, which are Trio-specific APIs.

### What timeout does Holehe use for HTTP requests?

According to [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py#L13-L14), Holehe instantiates `httpx.AsyncClient(timeout=10)` with a **10-second timeout** by default. This prevents individual slow sites from blocking the entire batch of checks.