RepoPilotOpen in app →

skypjack/entt

Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2d ago
  • MIT licensed
  • CI configured
Show 2 more →
  • Tests present
  • Solo or near-solo (1 contributor active in recent commits)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/skypjack/entt)](https://repopilot.app/r/skypjack/entt)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/skypjack/entt on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: skypjack/entt

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/skypjack/entt shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 2d ago
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Solo or near-solo (1 contributor active in recent commits)

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live skypjack/entt repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/skypjack/entt.

What it runs against: a local clone of skypjack/entt — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in skypjack/entt | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>skypjack/entt</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of skypjack/entt. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/skypjack/entt.git
#   cd entt
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of skypjack/entt and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "skypjack/entt(\\.git)?\\b" \\
  && ok "origin remote is skypjack/entt" \\
  || miss "origin remote is not skypjack/entt (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "src/entt/entity/registry.hpp" \\
  && ok "src/entt/entity/registry.hpp" \\
  || miss "missing critical file: src/entt/entity/registry.hpp"
test -f "src/entt/entity/sparse_set.hpp" \\
  && ok "src/entt/entity/sparse_set.hpp" \\
  || miss "missing critical file: src/entt/entity/sparse_set.hpp"
test -f "src/entt/core/any.hpp" \\
  && ok "src/entt/core/any.hpp" \\
  || miss "missing critical file: src/entt/core/any.hpp"
test -f "src/entt/entity/group.hpp" \\
  && ok "src/entt/entity/group.hpp" \\
  || miss "missing critical file: src/entt/entity/group.hpp"
test -f "src/entt/container/dense_map.hpp" \\
  && ok "src/entt/container/dense_map.hpp" \\
  || miss "missing critical file: src/entt/container/dense_map.hpp"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/skypjack/entt"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

EnTT is a header-only C++ library implementing a fast, modern Entity Component System (ECS) for game development and real-time applications. It provides zero-overhead abstractions for managing entities, components, and systems with compile-time optimization and runtime efficiency used in production by Minecraft (Mojang), ArcGIS Runtime SDKs (Esri), and Ragdoll. Monorepo structure: headers in src/entt/ (core ECS logic), docs/ contains Doxygen markdown documentation (docs/md/{core,entity,container,config}.md), cmake/ and bazel/ provide dual build system support, conan/ and test infrastructure (conanfile.py, BUILD.bazel) enable package distribution, examples/ (inferred) contain runnable demonstrations.

👥Who it's for

Game developers and real-time systems engineers building performance-critical applications in C++17 and later who need efficient data-oriented design patterns without runtime overhead, particularly those working on large-scale projects like game engines or spatial computing platforms.

🌱Maturity & risk

Highly mature and production-ready: widely adopted by AAA studios (Minecraft), actively maintained with comprehensive CI/CD via GitHub Actions (build, coverage, sanitizer, analyzer workflows), 5.3M lines of C++ codebase, header-only distribution via vcpkg and Conan Center. The README proudly states 'we haven't found a single bug to date', indicating long-term stability.

Very low risk: single maintainer (skypjack) is a potential concern, but mitigated by header-only design (no binary compatibility issues), active community (Gitter, Discord channels), comprehensive test coverage visible in CI workflows, and zero external dependencies as a header-only library. No breaking changes indicated; API stability is explicit.

Active areas of work

Active development: dual build system maintenance (CMake and Bazel with MODULE.bazel), continuous integration across 8 GitHub Actions workflows (sanitizer, coverage, Bazel-specific releases), documentation generation (docs/doxy.in), and package manager support (Conan integration in conan/ci/).

🚀Get running

Clone and explore: git clone https://github.com/skypjack/entt.git && cd entt. No build required for header-only usage; to verify: mkdir build && cd build && cmake .. && ctest or bazel build //src/entt:entt for Bazel.

Daily commands: This is a header-only library; no runtime to start. For testing: cd build && ctest. For exploring: include #include <entt/entt.hpp> in C++ code and compile with C++17. Bazel: bazel test //....

🗺️Map of the codebase

  • src/entt/entity/registry.hpp — Core ECS registry that manages entities, components, and systems — the primary entry point for all ECS operations.
  • src/entt/entity/sparse_set.hpp — Fundamental data structure for efficient entity-component storage and iteration — underpins registry performance.
  • src/entt/core/any.hpp — Type-erased container for storing arbitrary component types — enables the flexible dynamic component system.
  • src/entt/entity/group.hpp — Groups entities with specific component combinations for optimized iteration — critical for query performance.
  • src/entt/container/dense_map.hpp — High-performance associative container used throughout the library for component and entity lookups.
  • src/entt/core/type_info.hpp — Runtime type identification system that enables component type tracking without RTTI overhead.
  • single_include/entt/entt.hpp — Header-only amalgamation entry point — check this to understand the public API surface.

🛠️How to make changes

Add a new component type

  1. Define your component as a simple C++ struct or class with no special requirements (POD or move-constructible) (src/entt/entity/component.hpp)
  2. Register the component in your registry: registry.emplace<MyComponent>(entity, args...) (src/entt/entity/registry.hpp)
  3. Query entities with the component via view: registry.view<MyComponent>() or group for sorted access (src/entt/entity/group.hpp)

Create an efficient entity query

  1. For static queries, use registry.group<ComponentA, ComponentB>() to create a pre-sorted cache (src/entt/entity/group.hpp)
  2. For dynamic queries, use registry.view<ComponentA>(exclude<ComponentC>) with compile-time exclusion (src/entt/entity/ranges.hpp)
  3. For runtime-determined queries, use registry.runtime_view() with ID-based component selection (src/entt/entity/runtime_view.hpp)

Serialize and persist entity state

  1. Create a snapshot of the registry state: entt::snapshot snap{registry} (src/entt/entity/snapshot.hpp)
  2. Archive entities and components to a persistent medium (file, network, etc.) (src/entt/entity/snapshot.hpp)
  3. Restore from archive into a new/existing registry using the snapshot loader pattern (src/entt/entity/snapshot.hpp)

Optimize iteration over grouped components

  1. Identify hot-path queries that iterate multiple times per frame (src/entt/entity/registry.hpp)
  2. Use registry.group<A, B>() instead of separate views to ensure contiguous memory layout (src/entt/entity/group.hpp)
  3. If group size changes, use registry.group<A, B>().less<C>() or owned/get clauses for cache-friendly SoA storage (src/entt/container/table.hpp)

🔧Why these technologies

  • Header-only library (C++17/20) — Zero linking overhead, easy integration, enables aggressive template specialization and inlining for performance-critical ECS operations.
  • Sparse-dense sets (sparse_set.hpp) — Provides O(1) entity lookup, O(1) add/remove, and O(n) cache-friendly iteration — optimal for ECS workloads.
  • Dense maps and sets (dense_map.hpp, dense_set.hpp) — Replaces std::unordered_map with higher cache locality and lower fragmentation for component storage and metadata.
  • Type-erased any (core/any.hpp) + family-based IDs — Avoids RTTI overhead while enabling dynamic component instantiation, reflection, and runtime polymorphism in systems.
  • Bazel + CMake + Conan — Multi-build-system support accommodates diverse game engine ecosystems and CI/CD pipelines; Bazel for monorepos.

⚖️Trade-offs already made

  • Header-only design

    • Why: Eliminates ABI compatibility issues and enables aggressive inlining.
    • Consequence: Compilation time increases; binary bloat possible if not carefully templated; no stable ABI across versions.
  • Sparse-dense indexing instead of pure dense SoA

    • Why: Fast O(1) entity removal without full array rebuild; critical for dynamic entity lifetimes.
    • Consequence: Iteration slightly less cache-friendly than pure SoA; two allocations per component type.
  • No intrusive RTTI or virtual bases

    • Why: Zero overhead reflection and component identity via compile-time family IDs.
    • Consequence: Requires template metaprogramming; component types must be known at compile time (except via type_info for runtime polymorphism).
  • Group pre-caching with explicit cache invalidation

    • Why: Enables cache-optimal iteration without automatic synchronization cost.
    • Consequence: Programmer responsibility to invalidate groups when entities are removed; potential correctness bugs if misused.

🚫Non-goals (don't propose these)

  • Does not provide a serialization format specification — users implement serialize() methods themselves.
  • Does not include a graphics renderer or physics engine — ECS is data/logic only.
  • Does not enforce single-threaded operation — thread safety is opt-in per registry instance.
  • Does not automate system scheduling or ordering — manual or via organizer framework.
  • Not a game engine — is a foundational library for building engines.

🪤Traps & gotchas

Header-only consumption requires C++17 minimum (enforced by template usage, not explicit CMake check visible). Bazel users must have Bazel 7.0+ for MODULE.bazel support; older versions require WORKSPACE.bazel. No hidden env vars or service requirements, but .bazel* config files (.bazelrc, .bazeliskrc) enable Bazel-specific optimizations that may differ from CMake defaults.

🏗️Architecture

💡Concepts to learn

  • Entity Component System (ECS) — Fundamental architectural pattern EnTT implements; understanding composition-over-inheritance is critical to using this library effectively rather than fighting against its design
  • Sparse Set Data Structure — EnTT uses sparse sets internally for O(1) component lookup and iteration; understanding cache locality and memory layout explains performance guarantees
  • SFINAE (Substitution Failure Is Not An Error) — Core metaprogramming technique used throughout EnTT's template code for compile-time type introspection and constraint satisfaction without runtime overhead
  • Template Specialization & Partial Specialization — EnTT's API leverages both to provide compile-time polymorphism for different component types and query patterns; essential to understanding API surface
  • Constexpr & Compile-Time Computation — Heavy use of constexpr in EnTT enables zero-runtime-overhead abstractions where possible; critical for understanding performance characteristics
  • View & Iterator Patterns — EnTT's core query mechanism uses custom iterators over component views; understanding this pattern prevents O(n) performance regressions
  • Dual Build System (CMake & Bazel) — EnTT maintains both CMake and Bazel support; understanding build system choice impacts integration strategy and available configuration options in downstream projects
  • gaia-org/gaia — Modern C++ ECS library with similar zero-overhead goals; comparison benchmark baseline for performance-critical applications
  • skypjack/meta — Companion library by same author (skypjack) providing compile-time reflection utilities often paired with EnTT for serialization and introspection
  • jbkunst/highcharts-core — Example of downstream adoption: game engines and tools integrating EnTT for entity management with visualization/tooling layers
  • celery/celery — Ecosystem context: while unrelated technically, EnTT users building distributed game servers often complement it with task queues for backend systems

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive Bazel integration tests in bazel-release-archive.yml workflow

The repo has mature Bazel support (BUILD.bazel, MODULE.bazel, bazel/copts.bzl) with multiple Bazel workflows, but bazel-release-archive.yml appears to only handle release packaging. There's no CI validation that the release archive itself can be consumed via Bazel (testing the published artifact extraction and reuse). This is critical for users relying on Bazel binary distributions.

  • [ ] Examine .github/workflows/bazel-release-archive.yml to understand current release process
  • [ ] Create a test job that extracts the published release archive and validates it can be used in a fresh Bazel workspace
  • [ ] Add verification that all src/BUILD.bazel targets build correctly from the archived source
  • [ ] Test that MODULE.bazel dependency resolution works when consuming the archived release

Add cross-platform MSVC/Clang-CL specific tests in sanitizer.yml workflow

The repo has .clang-tidy and extensive CI (analyzer.yml, sanitizer.yml, build.yml) but sanitizer.yml likely focuses on GCC/Clang-standard sanitizers. MSVC and Clang-CL have different addressing/undefined-behavior sanitizers (/fsanitize flags). For a modern C++ library targeting game engines, validating MSVC sanitizer compatibility is crucial but appears missing.

  • [ ] Review .github/workflows/sanitizer.yml to identify current compiler coverage
  • [ ] Add a new job using cl.exe with /fsanitize=address /fsanitize=undefined flags on Windows runners
  • [ ] Add Clang-CL testing with -fsanitize=address -fsanitize=undefined on Windows
  • [ ] Ensure CMakeLists.txt properly propagates these flags through the toolchain configuration

Create integration test suite for Conan package metadata and cross-package compatibility

The repo has conanfile.py and conan/test_package/ but conan/test_package/CMakeLists.txt appears minimal. There's no CI validation that the Conan package published to Conan Center works correctly with different profile configurations (settings like C++ standard, build type, ABI). Given EnTT's header-only nature with C++17+ requirements, profile compatibility testing is essential.

  • [ ] Examine conan/test_package/test_package.cpp and conanfile.py to identify current scope
  • [ ] Add test_package scenarios for multiple C++ standards (17, 20, 23) validating feature availability
  • [ ] Create tests validating Conan package works with both shared and static linking contexts (even if library is header-only, consumers may link differently)
  • [ ] Add a GitHub Actions job that installs from Conan Center and runs full test suite with different profile settings

🌿Good first issues

  • Add comprehensive unit tests for src/entt/graph/ (graph.md exists but test coverage in conan/test_package/ is minimal) to verify directed acyclic graph component types introduced as a feature
  • Extend docs/md/links.md with concrete code examples (currently sparse) showing entity linking patterns alongside the core.md entity reference documentation
  • Implement missing .clang-tidy check integration into CI: .clang-tidy config exists but no GitHub Action workflow runs it; add clang-tidy step to analyzer.yml to catch style issues early

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 1333fa5 — entity: refine requires on entt_traits for enum (skypjack)
  • 1717001 — stl: internal changes (skypjack)
  • 0ebf837 — entt_traits: relax class constraints for backward compatibility (skypjack)
  • 093bb5b — entity: let the traits check the concept for us (skypjack)
  • 720dda4 — entity_like: move the concept to the file it belongs to, and fix it - see #1244 (skypjack)
  • 05d11b7 — sparse_set: reduce impact of entity_like, and prepare to fix it (skypjack)
  • 9b94f09 — component_traits: reduce impact of entity_like, and prepare to fix it (skypjack)
  • ca32a36 — test: reduce impact of entity_like, and prepare to fix it (skypjack)
  • 060eda7 — davey: reduce impact of entity_like, and prepare to fix it (skypjack)
  • 7c46351 — storage_for (skypjack)

🔒Security observations

EnTT is a modern C++ header-only ECS library with a relatively secure posture. The codebase follows good practices with Bazel/CMake build systems and CI/CD workflows. No critical vulnerabilities were detected in the static analysis. Primary concerns are organizational: lack of a defined security policy, need for robust dependency management practices, and ensuring build system configurations don't expose sensitive data. The project would benefit from implementing automated security scanning in its CI/CD pipelines and establishing a clear vulnerability disclosure policy.

  • Low · Potential Information Disclosure via GitHub Workflows — .github/workflows/. Multiple GitHub workflow files (.github/workflows/*.yml) are configured for automated builds and testing. While this is standard practice, workflows can inadvertently expose sensitive information through logs or build artifacts if not properly configured. The analyzer.yml, sanitizer.yml, and coverage.yml workflows may generate verbose output. Fix: Ensure all workflows have proper access controls, use GitHub Secrets for any sensitive data, and review workflow logs retention settings. Implement branch protection rules to restrict workflow execution on main/master branch.
  • Low · No Security Policy Defined — Repository root. The repository does not appear to have a SECURITY.md file (not listed in the file structure), which could indicate the absence of a clear security vulnerability disclosure policy. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file in the repository root with clear instructions for reporting security vulnerabilities, expected response times, and the responsible disclosure policy.
  • Low · Build System Configuration Exposure — .bazelrc, .bazeliskrc, BUILD.bazel, CMakeLists.txt, conanfile.py. Multiple build system configuration files are present (.bazelrc, BUILD.bazel, CMakeLists.txt, conanfile.py) which could potentially expose build secrets or sensitive configuration if not properly managed. The .bazelrc file in particular could contain sensitive settings. Fix: Ensure .bazelrc and similar config files do not contain hardcoded credentials or sensitive paths. Use environment variables or secure configuration management for sensitive build parameters. Add these files to .gitignore if they contain local secrets.
  • Low · Third-Party Dependency Management — conanfile.py, CMakeLists.txt, BUILD.bazel, MODULE.bazel. The project uses multiple package managers (Conan, Vcpkg, Bazel, CMake) which increases the complexity of dependency tracking. While not directly visible in the provided file structure, ensure all transitive dependencies are properly vetted. Fix: Regularly audit dependencies using tools like OWASP Dependency-Check or Snyk. Pin versions explicitly in dependency files. Review the security advisories for all direct and transitive dependencies. Enable automated dependency scanning in CI/CD.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · skypjack/entt — RepoPilot