You need labels to name various things in your app, such as systems (for order control), run criteria, stages, and ambiguity sets.

Bevy uses some clever Rust type system magic, to allow you to use strings as well as your own custom types for labels, and even mix them!

Using strings for labels is quick and easy for prototyping. However, they are easy to mistype and are unstructured. The compiler cannot validate them for you, to catch mistakes.

You can also use custom types (usually enums) to define your labels. This allows the compiler to check them, and helps you stay organized in larger projects.

You need to derive the appropriate trait, depending on what they will be used for: StageLabel, SystemLabel, RunCriteriaLabel, or AmbiguitySetLabel.

Any Rust type is suitable, as long as it has the following standard Rust traits: Clone + PartialEq + Eq + Hash + Debug (and the implied Send

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum MySystems {

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum MyStages {

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct DebugStage;

fn main() {

        // Add our game systems:

        // temporary debug system, let's just use a string label

        // Add our custom stages:
        // note that Bevy's `CoreStage` is an enum just like ours!
        .add_stage_before(CoreStage::Update, MyStages::Prepare, SystemStage::parallel())
        .add_stage_after(CoreStage::Update, MyStages::Cleanup, SystemStage::parallel())

        .add_stage_after(CoreStage::Update, DebugStage, SystemStage::parallel())

        // we can just use a string for this one:
        .add_stage_before(CoreStage::PostUpdate, "temp-debug-hack", SystemStage::parallel())


For quick prototyping, it is convenient to just use strings as labels.

However, by defining your labels as custom types, the Rust compiler can check them for you, and your IDE can auto-complete them. It is the recommended way, as it prevents mistakes, and helps you stay organized in larger projects.