{"id":51431592,"url":"https://github.com/code-hemu/truehuman","last_synced_at":"2026-07-05T04:04:09.754Z","repository":{"id":366420889,"uuid":"1268344184","full_name":"code-hemu/truehuman","owner":"code-hemu","description":"Detect bots, verify humans.","archived":false,"fork":false,"pushed_at":"2026-06-29T19:08:47.000Z","size":499,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-29T20:22:22.373Z","etag":null,"topics":["anti-bot","bot-detection","browser","browser-fingerprinting","captcha-alternative","detection","fingerprint","fraud-detection","headless-detection","human-verification","security","truehuman","typescript","visitor-identifier","webdriver-detection"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/code-hemu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-13T12:22:54.000Z","updated_at":"2026-06-29T19:06:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/code-hemu/truehuman","commit_stats":null,"previous_names":["code-hemu/truehuman"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/code-hemu/truehuman","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-hemu%2Ftruehuman","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-hemu%2Ftruehuman/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-hemu%2Ftruehuman/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-hemu%2Ftruehuman/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/code-hemu","download_url":"https://codeload.github.com/code-hemu/truehuman/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-hemu%2Ftruehuman/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35142835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anti-bot","bot-detection","browser","browser-fingerprinting","captcha-alternative","detection","fingerprint","fraud-detection","headless-detection","human-verification","security","truehuman","typescript","visitor-identifier","webdriver-detection"],"created_at":"2026-07-05T04:04:08.928Z","updated_at":"2026-07-05T04:04:09.681Z","avatar_url":"https://github.com/code-hemu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/code-hemu/truehuman\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/code-hemu/truehuman/refs/heads/main/resources/light_logo.png\" /\u003e\n      \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/code-hemu/truehuman/refs/heads/main/resources/dark_logo.png\" /\u003e\n      \u003cimg src=\"https://raw.githubusercontent.com/code-hemu/truehuman/refs/heads/main/resources/dark_logo.png\" alt=\"TrueHuman logo\" width=\"312px\" /\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/truehuman\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/truehuman\" alt=\"Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/code-hemu/truehuman/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/code-hemu/truehuman\" alt=\"License\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/code-hemu/exprify/issues\"\u003e\u003cimg src=\"https://img.shields.io/github/issues/code-hemu/exprify\" alt=\"License\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.jsdelivr.com/package/npm/truehuman\"\u003e\u003cimg src=\"https://data.jsdelivr.com/v1/package/npm/truehuman/badge?style=rounded\" alt=\"jsDelivr\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/code-hemu/truehuman/graphs/contributors\"\u003e\u003cimg src=\"https://img.shields.io/github/contributors/code-hemu/truehuman\" alt=\"jsDelivr\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nTrueHuman is a bot detection library for web applications. It performs browser integrity checks and uses passive fingerprinting signals to create a risk score. Optional reCAPTCHA and Turnstile plugins offer extra server-side verification.\n\n- **20+ detectors** - Inspects canvas output, WebGL metadata, installed fonts, audio context latency, screen geometry, navigator object properties, and known automation flags left behind by headless browsers and driver frameworks.\n- **Plugin system** - Integrates with Google reCAPTCHA v3 and Cloudflare Turnstile to add server-validated signals on top of the passive client-side checks, giving you a layered defence that is much harder to spoof.\n- **Risk scoring** - Produces a cumulative 0 to 100 risk score alongside a verdict of `human`, `suspicious`, or `bot`, and a confidence value that is the direct inverse of the risk score.\n- **Zero runtime dependencies** - The entire library ships as roughly 10 KB when gzipped, with no third-party packages required at runtime. Optional plugin dependencies are loaded only when you configure a plugin.\n- **UMD / ESM / CJS** - Distributed in all three module formats so it works natively with any modern bundler, import system, or via a plain script tag from a CDN.\n\n## Quick Start\n\nInstall the package from npm:\n\n```bash\nnpm install truehuman\n```\n\nImport and call `analyze()` anywhere in your client-side code. The function is synchronous by default and returns a result object immediately:\n\n```typescript\nimport { analyze } from \"truehuman\"\n\nconst result = analyze()\nconsole.log(result.visitor)      // \"human\" | \"suspicious\" | \"bot\"\nconsole.log(result.risk.score)   // 0 to 100\nconsole.log(result.confidence)   // 0 to 100\n```\n\nThe `visitor` field gives you a plain-language verdict. The `risk.score` field gives you the raw number behind that verdict so you can apply your own thresholds if needed.\n\n\n### CDN\n\nIf you are not using a bundler, load TrueHuman directly from jsDelivr and access it through the global `truehuman` namespace:\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/truehuman/dist/truehuman.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  const result = truehuman.analyze()\n  console.log(result.visitor)\n\u003c/script\u003e\n```\n\n### Sync vs Async\n\n`analyze()` supports both synchronous and asynchronous usage depending on whether you configure any plugins:\n\n```typescript\n// Synchronous usage: no plugins configured, result is returned immediately\nconst result = analyze()\n\n// Asynchronous usage: plugins require a network round-trip, so analyze() returns a Promise\nconst result = await analyze({ plugins: [...] })\n```\n\nWhen called without plugins, `analyze()` is entirely local and produces no network traffic. As soon as you add a plugin, the call becomes asynchronous and must be awaited.\n\n\n### Debug Mode\n\nPass the string `\"debug\"` as the first argument to enable debug mode. In this mode, the result object includes an additional `debug` field that exposes the internal signals collected during analysis:\n\n```typescript\nconst result = analyze(\"debug\")\nconsole.log(result.debug)\n// {\n//   integrityCodes: [...],   codes that fired during this evaluation\n//   iframeComparisons: N,    number of cross-frame property mismatches detected\n//   environmentFlag: ...,    set when running in a file:// origin or NN environment\n//   errors: [...]            list of detectors that threw an exception at runtime\n// }\n```\n\nDebug mode is useful during development to understand why a particular visitor received a specific score, or to audit which detectors are firing in your environment. It is not recommended for production use as it exposes internal signal data.\n\n\n### Result Fields\n\nEvery call to `analyze()` returns an object with the following fields:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `visitorId` | `string` | An 8-character hexadecimal hash derived from canvas output, WebGL renderer data, and the user agent string. Consistent for the same real browser across short sessions. |\n| `referrer` | `string` | Categorised referrer context. One of `direct`, `internal`, `external`, `file`, or `localhost`. |\n| `visitor` | `string` | The human-readable verdict. `human` for scores 0 to 15, `suspicious` for 16 to 40, and `bot` for 41 to 100. |\n| `risk.score` | `number` | Cumulative risk score from 0 to 100. Higher values indicate stronger bot signals. |\n| `risk.level` | `string` | Banded risk label. One of `low`, `medium`, `high`, or `critical`. |\n| `confidence` | `number` | Confidence that the visitor is human, expressed as `100 minus risk.score`. A score of 20 yields a confidence of 80. |\n| `components` | `object` | A map of every detector that ran, including its execution duration in milliseconds and the raw value it produced. Useful for auditing which signals contributed to the score. |\n| `debug` | `object` | Present only when `analyze(\"debug\")` is called. Contains internal signal details as described in the Debug Mode section above. |\n\n\n### With Plugins\n\nTo enable server-side verification alongside the passive client-side checks, import the `detector` namespace and pass one or more plugin instances in the options object:\n\n```typescript\nimport { analyze, detector } from \"truehuman\"\n\nconst result = await analyze({\n  plugins: [\n    detector.grecaptcha({\n      siteKey: \"YOUR_SITE_KEY\",\n      endpoint: \"/api/verify-recaptcha\",\n    }),\n  ],\n})\n```\n\nThe `endpoint` field should point to a server route you control. TrueHuman sends the token generated by the third-party service to that endpoint, and your server is responsible for verifying it against the reCAPTCHA or Turnstile API and returning a result. This keeps your secret keys off the client. See the plugin-specific guides in the documentation for the full request and response shape expected by each plugin.\n\n\n## Documentation\n\nFull documentation is available in the [`docs/`](docs/) folder. Each file covers a specific area of the library:\n\n| File | Contents |\n|------|----------|\n| [docs/getting-started.md](docs/getting-started.md) | Installation instructions, CDN usage, and a basic integration walkthrough |\n| [docs/api/analyze.md](docs/api/analyze.md) | Full reference for the `analyze()` function including all options and return types |\n| [docs/api/detector.md](docs/api/detector.md) | Reference for the `detector` plugin factory, including available plugins and their configuration options |\n| [docs/api/types.md](docs/api/types.md) | Complete TypeScript type definitions for all public interfaces and enumerations |\n| [docs/plugins/recaptcha.md](docs/plugins/recaptcha.md) | Step-by-step guide for integrating the reCAPTCHA v3 plugin, including the required server-side verification endpoint |\n| [docs/plugins/turnstile.md](docs/plugins/turnstile.md) | Step-by-step guide for integrating the Cloudflare Turnstile plugin |\n| [docs/plugins/custom.md](docs/plugins/custom.md) | Guide for writing and registering your own custom verification plugins |\n| [docs/detectors.md](docs/detectors.md) | Descriptions of every passive detector component, what it measures, and what signals it looks for |\n| [docs/scoring.md](docs/scoring.md) | Explanation of how individual detector signals are weighted and combined into the final risk score |\n| [docs/error-codes.md](docs/error-codes.md) | Full reference for every integrity code that can appear in `debug.integrityCodes` |\n\n\n## Examples\n\nA working vanilla JavaScript demo is available in the [`examples/vanilla-js/`](examples/vanilla-js/) directory. It shows how to call `analyze()`, render the result fields into the DOM, and use debug mode to inspect the raw signals.\n\n\n## Error Codes Overview\n\nIntegrity codes are short numeric identifiers assigned to specific signals that fire during analysis. Each code maps to a particular category of browser behaviour. When a code fires, its associated weight is added to the cumulative risk score.\n\n| Range | Category |\n|-------|----------|\n| 10.x | User-Agent string inconsistencies, such as mismatches between the UA string and detected browser capabilities |\n| 11.x | Missing essential browser APIs that all real browsers expose but headless environments often omit |\n| 20.x | Navigation timing anomalies, including suspiciously fast page loads or missing timing entries |\n\n\nSee [docs/error-codes.md](docs/error-codes.md) for the full code-by-code reference including individual weights and recommended response actions.\n\n\n## Browser Support\n\nTrueHuman supports all modern versions of Chrome, Firefox, Safari, and Edge. The library requires an ES2017 or later environment because it uses `async/await` syntax internally. All browser APIs used by the detectors are stable and widely available across current browser versions. No polyfills are required for supported targets.\n\n\n## Development\n\nThe following npm scripts are available for building and testing the library locally:\n\n```bash\nnpm run build      # Compiles the source into dist/ in UMD, ESM, and CJS formats\nnpm test           # Runs the test suite using Vitest\nnpm run typecheck  # Runs the TypeScript compiler in check-only mode with tsc --noEmit\n```\n\n\n## License\n\nTrueHuman is licensed under **GPL-3.0**. Copyright © [Hemanta Gayen](https://github.com/hemanta-gayen).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-hemu%2Ftruehuman","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcode-hemu%2Ftruehuman","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-hemu%2Ftruehuman/lists"}