switchbrew_bevy 🦀🎮
A Rust crate to help port Bevy games to Nintendo Switch using emulators - no NDAs required.
Background
As noted in the Bevy Cheatbook:
The Rust Programming Language aims to make Nintendo Switch a supported target, but that work is in its early days and has not progressed enough to be useful for Bevy yet. It should be possible to work on Nintendo Switch support in the open, without NDAs, using emulators.
This crate aims to bridge that gap by providing:
- Platform abstractions for Switch vs Desktop
- Joy-Con input mapping and abstractions
- Window/display management for Switch resolutions
- Utilities for cross-platform game development
Status
Highly experimental. The aarch64-nintendo-switch-freestanding target is Tier 3 in Rust, meaning:
- Not automatically tested
- Limited standard library support
- May not build at any given time
Installation
Add to your Cargo.toml:
[]
= { = "https://github.com/ibrahimcesar/bevy-switch" }
Usage
use *;
use *;
Features
desktop(default) - Build for desktop development/testingswitch- Build for Nintendo Switch target
Project Structure
switchbrew_bevy/
├── src/
│ ├── lib.rs # Main plugin and prelude
│ ├── platform.rs # Platform detection & config
│ ├── input.rs # Joy-Con input abstractions
│ └── window.rs # Display management
├── examples/
│ └── crab_crossing.rs # Demo game
└── ...
Running the Example
# Run Crab Crossing demo
Controls
| Switch | Keyboard | Action |
|---|---|---|
| Left Stick | WASD / IJKL | Movement |
| D-Pad | Arrow Keys | Movement |
| A | X | Confirm |
| B | Z | Cancel |
| L/R | Q/W | Shoulders |
| ZL/ZR | 1/2 | Triggers |
| + | Enter | Start/Plus |
| - | Backspace | Select/Minus |
Prerequisites
Rust Toolchain
# Nightly required for build-std
# Optional: cargo-nx for Switch builds
Emulators for Testing
Since Yuzu and Ryujinx were shut down by Nintendo in 2024, use community forks:
- Ryubing - Fork of Ryujinx, most stable
- Citron - Fork of Yuzu, good performance
- Sudachi - Cross-platform Yuzu fork
API Overview
SwitchPlugin
Main plugin - adds input handling, window management, and platform detection.
SwitchInput
Resource for unified input across keyboard/gamepad:
movement()- Get movement vector from stick or D-padpressed(button)/just_pressed(button)- Check button stateleft_stick/right_stick- Raw stick positions
SwitchConfig
Resource for platform configuration:
platform- Current platform (Desktop/SwitchDocked/SwitchHandheld)resolution- Target resolutiondisplay_mode- Docked/Handheld/Tabletop
SwitchButton
Enum mapping all Joy-Con buttons with keyboard equivalents.
Roadmap
- Platform abstraction layer
- Joy-Con button mapping
- Unified input system
- Window/resolution helpers
- Investigate Bevy
no_stdcompatibility (see docs/NO_STD_ANALYSIS.md) - Test with actual Switch emulator homebrew
- Switch-specific rendering backend
- Audio subsystem abstraction
- File I/O abstraction
- HD Rumble support
Bevy no_std Status
Good news! As of Bevy 0.16 (April 2025), many core crates support no_std:
| Status | Crates |
|---|---|
| ✅ Ready | bevy_ecs, bevy_app, bevy_math, bevy_input, bevy_transform, bevy_color, bevy_state, bevy_time, bevy_hierarchy, bevy_reflect |
| ❌ Not Planned | bevy_render, bevy_audio, bevy_asset, bevy_winit (platform-specific) |
This means game logic using ECS can run on Switch! But rendering/audio need custom backends.
See docs/NO_STD_ANALYSIS.md for full analysis.
Challenges
Graphics
Switch uses NVN (NVIDIA proprietary) or OpenGL ES. Bevy uses wgpu (Vulkan/Metal/DX12/WebGPU). A custom backend would be needed.
no_std
Switch target is freestanding. As of Bevy 0.16+, core ECS is no_std compatible! Rendering still requires std.
Audio
Switch has its own audio subsystem requiring a custom Bevy backend.
Resources
- Rust aarch64-nintendo-switch-freestanding
- aarch64-switch-rs - Rust Switch homebrew ecosystem
- nx crate - Switch userland library
- cargo-nx - Build tool
- Bevy Engine
Legal
This project is for educational purposes. It uses only open-source tools and does not require Nintendo NDAs or proprietary SDKs.
License
MIT