Sky ECS
Sky ECS is a typed, chunk-based Entity Component System for Rust. It is the ECS used by SkyEngine, but the crate can be used independently.
Documentation
Features
- Chunk-columnar archetype storage
- Generational entity identifiers
- Bundle-based spawning and cached structural transitions
- World-bound typed queries and reusable
PreparedQuery - Optional query parameters and
With,Without, andAnyfilters - Entity and chunk iteration, with sequential and parallel variants
- Named query items through
#[derive(QueryData)] - Typed resources, systems, stages, fixed steps, and deferred commands
- Runtime-typed access under
sky_ecs::dynamic - Low-level storage APIs under
sky_ecs::expert
Usage
[]
= "0.1.3"
use World;
For repeated random access to one component type, bind a component accessor to the world before entering the hot loop:
let positions = world.;
for entity in entities
The accessor resolves matching component columns once and keeps a read-only
borrow of the world while it is alive. Use World::get for occasional lookups,
or when the world must be structurally changed between accesses.
Repeated random updates use an exclusive accessor:
let mut positions = world.;
for entity in entities
Queries
Queries are created from a World. Matching archetype plans are cached by the
world and refreshed after structural changes.
use ;
;
;
let query = world
.
.;
Use query_mut when a query contains mutable component references. Use
PreparedQuery when the query plan needs to be stored explicitly or reused
across worlds.
Named query items are available for wider queries:
use QueryData;
world..for_each;
Parallel iteration uses the same query types:
world
.
.par_for_each;
Small workloads fall back to sequential iteration. par_for_each_chunk is
available when the inner loop benefits from component slices.
Systems
System access is inferred from typed parameters. Compatible systems may run in parallel, while conflicting systems keep registration order.
use ;
let mut world = new;
world.stage.add;
world.tick_with_delta.unwrap;
Structural changes made by systems can be deferred through Commands. Outside
the scheduler, use an owned CommandBuffer.
Benchmarks
The repository includes a Criterion comparison of six ECS implementations. Compare-ECS limits conclusions to its single-threaded public-API workloads, uses each implementation's fastest suitable reusable query, view, or accessor state, and validates every adapter before measurement. Results are machine-specific. The benchmark guide records current-protocol local measurements from 2026-07-17, including a Clang/LLVM 22.1.2 remeasurement of the Flecs column; see it for workload classifications, compiler configuration, and measurement boundaries. Prepared random access excludes preparation cost and cache memory, while scenarios and diagnostics are reported separately from comparable workloads.
The methodology and recorded results are kept in the
benchmark guide.
Internal Sky ECS benchmarks are kept separate and run with cargo bench.
API overview
| Need | API |
|---|---|
| Read-only query | World::query |
| Mutable query | World::query_mut |
| Repeated random component access | World::accessor, World::accessor_mut |
| Explicit reusable query plan | PreparedQuery |
| Parallel entity iteration | par_for_each |
| Parallel chunk iteration | par_for_each_chunk |
| Archetype filters | With<T>, Without<T>, Any<(...)> |
| Deferred structural changes | Commands, CommandBuffer |
| Runtime-known component types | sky_ecs::dynamic |
| Low-level storage access | sky_ecs::expert |
Typed component tuples for bundles, queries, and filters support up to 16
entries. A single internal archetype can store up to 32 distinct component
types; that limit applies per archetype, not per World.
Sky ECS requires Rust 1.85 or newer. The crate is currently versioned as 0.x.
License
MIT. See LICENSE.