#bevy #bevy-ecs #macro #bevy-macro

mevy

A growing set of macros, which add witchcraft into bevy!

8 releases

Uses new Rust 2024

new 0.3.1 Nov 2, 2025
0.3.0 Oct 27, 2025
0.2.2 Apr 25, 2025
0.1.3 Mar 9, 2025
0.1.2 Jan 9, 2025

#549 in Game dev

Download history 2/week @ 2025-07-09 90/week @ 2025-10-22

90 downloads per month

MIT/Apache

40KB

A growing set of macros which add some witchcraft into bevy, currently available: 🪄

  • Simpler Entity spawning & modifying
  • Style Sheet Notation for bevy_ui components (and your own) - ui!(( width: 20px; ))
  • Simplified Notation for Color, Val and UiRect - code!{ let red = #ff0000; //..any code }

[!IMPORTANT] This crate is meant to provide macros only - no additional bevy plugins, resources, components or systems

Setup

Multiple bevy versions are supported and managed by features:

# bevy 0.17
mevy = {version="0.3",features=["0.17"]}

# bevy 0.16
mevy = {version="0.3",features=["0.16"]}

# bevy 0.15
mevy = {version="0.3",features=["0.15"]}

Then just use all of it:

use bevy::prelude::*;
use mevy::*;

Simpler Hierarchy Spawning

Spawn children just by stating [] - the 'names' are just variables containing their Entity

entity!{
    <world> // pass a mut World, Commands, ... variable
    SpecificChild(optional_child_name); // insert component
    .observe(..);                       // use method
    > Pointer<Click>{..};               // quick observe (e.g. 'on click')
    // component/bundle;
    // .method(..);
    [optional_child_name][
        // component;
        // .method(..);
    ]
}

Modify entities in a 'quick and dirty' way:

entity!{
    <world|#Component> // select every entity with this Component
    <Children.iter()>  // > select all children of those
    <Children.iter()>  // >> infinitely chain those selectors
    .despawn();        // despawn all of the last selected
}

CSS-like notation for bevy_ui

Using ui!((..)) (inner round braces) will return a tuple of mentioned components only.

// Slim Mode
c.spawn(ui!(
    w:100 h:100 bg:#fff round:6 border:5#f00 
    shadow:10%10%3+8#fa4 neat_outline
));

// CSS-Like Mode (does the same)
c.spawn(ui!((
    size:          100px 100px;
    border:        5px #ff0000;
    box_shadow:    10% 10% 3px 8px #ffaa44;
    background:    #ffffff;
    border_radius: 6px;
    neat_outline;
)?));
//^ optional ? (or any token): hovering shows the returned tuple (if LSP used)

/// function as custom fields or p refabs
fn neat_outline() -> Outline {ui!((
    outline: 3px 1px #00ff00;
))}

Code Replacement Macro

Using the code!{} macro simplifies constructing:

  • Color by writing #rgb/#rgba/#rrggbb/#rrggbbaa
  • Val by writing 0px/0%/0vw/0vh/0vmin/0vmax/@(auto)
  • UiRect by writing [>0px]/[>0px 0px]/[>0px 0px 0px]/[>0px 0px 0px 0px] (css-like)

So you can do fun things like:

let shadow = code!{BoxShadow{
    // use #... is replaced with Color, meaning you can e.g. use methods 
    color: #FF1265.mix(&#F93ECA,0.4).with_alpha(0.2),
    x_offset: 100px,
    y_offset: 50%,
    spread_radius: 3.1vh,
    blur_radius: 40.23vmax,
}}};
let color = code!{#FF0000};
// or multiple things in the macro
code!{
    let color2 = #00FF00;
    let color3 = #6600AA;
}
println!{"{color2:?}"}

Design

Crates are separated into:

  • crate/*/syntax: token handling, meant to be reusable
  • crate/*: actual macros, based on that 'syntax'

[!NOTE] Only relevant if you dig deeper into this crate: The versions of those are not hard linked, since the macros can keep (or gain) features, even if the the syntax api has changed. So if one of those is 0.2.x and the other 0.5.x at some point, don't worry.

Dependencies

~0.8–1.3MB
~23K SLoC