Sherlock.Net 0.16.0

dotnet add package Sherlock.Net --version 0.16.0
                    
NuGet\Install-Package Sherlock.Net -Version 0.16.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sherlock.Net" Version="0.16.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sherlock.Net" Version="0.16.0" />
                    
Directory.Packages.props
<PackageReference Include="Sherlock.Net" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Sherlock.Net --version 0.16.0
                    
#r "nuget: Sherlock.Net, 0.16.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Sherlock.Net@0.16.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Sherlock.Net&version=0.16.0
                    
Install as a Cake Addin
#tool nuget:?package=Sherlock.Net&version=0.16.0
                    
Install as a Cake Tool

<p align="center"> <br> <img src="https://user-images.githubusercontent.com/27065646/53551960-ae4dff80-3b3a-11e9-9075-cef786c69364.png" width="200"/> <br> <b>Sherlock.Net</b> <br> <i>Hunt down social media accounts by username across 400+ social networks</i> <br> <i>A .NET port of the <a href="https://github.com/sherlock-project/sherlock">Sherlock Project</a></i> <br> </p>

<p align="center"> <a href="https://dotnet.microsoft.com/download/dotnet/10.0"><img src="https://img.shields.io/badge/.NET-10.0-512BD4?logo=dotnet" alt=".NET 10.0"></a> <a href="https://github.com/totpero/Sherlock.Net/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue" alt="License: Apache 2.0"></a> <a href="https://totpero.github.io/Sherlock.Net/"><img src="https://img.shields.io/badge/docs-GitHub%20Pages-brightgreen" alt="Documentation"></a> </p>


About

Sherlock.Net is a cross-platform .NET rewrite of the popular Sherlock Python tool. It searches for usernames across 400+ social networks simultaneously, using parallel async HTTP requests for fast results.

Why .NET?

  • Native cross-platform binary (Windows, Linux, macOS)
  • High-performance async I/O with IAsyncEnumerable streaming
  • Connection pooling via IHttpClientFactory (no socket exhaustion)
  • Clean architecture: use as a CLI tool or reference Sherlock.Net.Core as a library

Installation

Prerequisites

Install globally as a .NET tool — this makes the sherlock command available everywhere in your terminal:

dotnet tool install --global Sherlock.Net.Cli

After installation, simply run:

sherlock user123

To update to the latest version:

dotnet tool update --global Sherlock.Net.Cli

To uninstall:

dotnet tool uninstall --global Sherlock.Net.Cli

Note: Make sure ~/.dotnet/tools (Linux/macOS) or %USERPROFILE%\.dotnet\tools (Windows) is in your PATH. The .NET SDK adds this automatically on first tool install, but you may need to restart your terminal.

Build from source

git clone https://github.com/totpero/Sherlock.Net.git
cd Sherlock.Net
dotnet build

Run directly from source (without installing):

dotnet run --project src/Sherlock.Net.Cli -- <username>

Publish as single executable

dotnet publish src/Sherlock.Net.Cli -c Release -r win-x64 --self-contained
dotnet publish src/Sherlock.Net.Cli -c Release -r linux-x64 --self-contained
dotnet publish src/Sherlock.Net.Cli -c Release -r osx-arm64 --self-contained

Quick Start

# Install the tool globally
dotnet tool install --global Sherlock.Net.Cli

# Search for a username across 400+ sites
sherlock johndoe

# Search multiple usernames and export to CSV
sherlock --csv johndoe janedoe

# Search only on GitHub and Twitter
sherlock --site GitHub --site Twitter johndoe

Usage

Search for a single username

sherlock user123

Search for multiple usernames

sherlock user1 user2 user3

Limit to specific sites

sherlock --site GitHub --site Twitter user123

Export results

sherlock --txt user123          # Save to user123.txt
sherlock --csv user123          # Save to user123.csv
sherlock --json-export user123  # Save to user123.json

Use a proxy or Tor

sherlock --proxy socks5://127.0.0.1:9050 user123

Username wildcards

Use {?} to try common separator variants (_, -, .):

sherlock john{?}doe
# Searches: john_doe, john-doe, john.doe

Command-Line Options

USAGE:
    sherlock <USERNAMES> [OPTIONS]

ARGUMENTS:
    <USERNAMES>    One or more usernames to search for

OPTIONS:
                                 DEFAULT
    -h, --help                              Prints help information
    -v, --version                           Prints version information
        --timeout <SECONDS>      60         Time in seconds to wait for response
        --proxy <URL>                       Proxy URL (e.g., socks5://127.0.0.1:9050 for Tor)
        --site <NAME>                       Limit search to specific site(s)
        --json <PATH_OR_URL>                Custom data.json file path or URL
        --csv                               Export results as CSV
        --txt                               Export results as TXT
        --json-export                       Export results as JSON
    -o, --output <DIR>                      Output directory for export files
        --print-all                         Show all results, not just found accounts
        --nsfw                              Include NSFW sites in search
    -b, --browse                            Open found URLs in default browser
        --no-color                          Disable colored output
        --concurrency <COUNT>    20         Maximum concurrent requests

Project Structure

Sherlock.Net/
├── src/
│   ├── Sherlock.Net.Core/         # Class library (models, services, exporters)
│   │   ├── Models/                # SiteData, QueryResult, QueryStatus, SherlockOptions
│   │   ├── Serialization/         # JSON converters for data.json quirks
│   │   ├── Services/              # SiteChecker, SherlockService, WafDetector
│   │   └── Resources/             # Embedded data.json (400+ sites)
│   │
│   └── Sherlock.Net.Cli/          # Console app (thin CLI layer)
│       ├── Commands/              # SearchCommand, SearchCommandSettings
│       └── Rendering/             # Spectre.Console colored output
│
└── tests/
    └── Sherlock.Net.Core.Tests/   # xUnit tests + JSON Schema validation

Architecture

Component Responsibility
SiteDataProvider Loads site definitions from embedded resource, URL, or file
SiteChecker Executes HTTP requests and applies detection logic per site
SherlockService Orchestrates parallel checks with Channel<T> + SemaphoreSlim
WafDetector Identifies WAF blocks (Cloudflare, PerimeterX, Akamai)
IResultExporter Exports results to TXT, CSV, or JSON

Detection Mechanisms

Each site in data.json uses one of three detection strategies:

Type How it works
StatusCode HTTP 404 or specific error code = username not found
Message Response body contains error string(s) = username not found
ResponseUrl Server redirects to a different URL = username not found

Using as a Library

Reference Sherlock.Net.Core in your project to integrate username searching programmatically:

dotnet add package Sherlock.Net.Core

Minimal usage (no DI container)

The simplest way — one static call, no ServiceCollection, no setup:

using Sherlock.Net.Core;
using Sherlock.Net.Core.Models;

// Search across all 400+ sites with a single call
await foreach (var result in SherlockFactory.SearchAsync("johndoe"))
{
    if (result.Status == QueryStatus.Claimed)
        Console.WriteLine($"[+] {result.SiteName}: {result.ProfileUrl}");
}

With options:

await foreach (var result in SherlockFactory.SearchAsync("johndoe", options =>
{
    options.Timeout = TimeSpan.FromSeconds(30);
    options.MaxConcurrency = 10;
    options.SiteFilter = ["GitHub", "Twitter", "Instagram"];
}))
{
    if (result.Status == QueryStatus.Claimed)
        Console.WriteLine($"[+] {result.SiteName}: {result.ProfileUrl}");
}

If you need more control (e.g., custom data.json source), use SherlockFactory.Create():

var (sherlock, siteProvider) = SherlockFactory.Create();
var sites = await siteProvider.LoadSitesAsync("path/to/custom-data.json");
await foreach (var result in sherlock.SearchAsync("johndoe", sites, new SherlockOptions()))
{
    // ...
}

With DI container (AddSherlock)

Register all services with a single call to AddSherlock():

using Microsoft.Extensions.DependencyInjection;
using Sherlock.Net.Core;
using Sherlock.Net.Core.Models;
using Sherlock.Net.Core.Services;

var services = new ServiceCollection();
services.AddSherlock();

var provider = services.BuildServiceProvider();
var siteDataProvider = provider.GetRequiredService<ISiteDataProvider>();
var sherlockService = provider.GetRequiredService<ISherlockService>();

var sites = await siteDataProvider.LoadSitesAsync();
var options = new SherlockOptions { MaxConcurrency = 20 };

await foreach (var result in sherlockService.SearchAsync("johndoe", sites, options))
{
    if (result.Status == QueryStatus.Claimed)
        Console.WriteLine($"[+] {result.SiteName}: {result.ProfileUrl}");
}

Custom configuration

Use the lambda overload to configure defaults:

services.AddSherlock(options =>
{
    options.UserAgent = "MyApp/1.0";
    options.Timeout = TimeSpan.FromSeconds(30);
    options.MaxConcurrency = 10;
    options.ProxyUrl = "socks5://127.0.0.1:9050";
    options.IncludeNsfw = false;
});

ASP.NET Core / Hosted services

AddSherlock() integrates with standard .NET dependency injection:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSherlock(options =>
{
    options.Timeout = TimeSpan.FromSeconds(15);
    options.MaxConcurrency = 5;
});

var app = builder.Build();

app.MapGet("/search/{username}", async (string username,
    ISiteDataProvider siteDataProvider, ISherlockService sherlockService) =>
{
    var sites = await siteDataProvider.LoadSitesAsync();
    var results = new List<object>();

    await foreach (var result in sherlockService.SearchAsync(username, sites, new SherlockOptions()))
    {
        if (result.Status == QueryStatus.Claimed)
            results.Add(new { result.SiteName, result.ProfileUrl });
    }

    return Results.Ok(results);
});

app.Run();

Running Tests

dotnet test

Tests include JSON Schema validation of data.json against the upstream data.schema.json.


Acknowledgements

This project is a .NET port of Sherlock, originally created by Siddharth Dushantha and maintained by the Sherlock Project community. The site database (data.json) is sourced directly from the upstream project.

License

Apache 2.0

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.16.0 46 4/7/2026