Bevy Android Setup

2025-11-07

Right now Android support on Bevy is not as great as in Unity. But it is improving and it is possible to use Bevy on Android.

In case of the issues with touch input on Android check out my note on touch input in Android.

I also recommend listening to Bevy meetup where Marco Meijer describes how he uses Bevy on Android already: YouTube

Basic setup

Check out Bevy's mobile example. It provides a sample project that lets you build game for Android in different ways. Be aware that:

Before building android_example install Android SDK and NDK first, then install cargo-ndk following the guide on repo: cargo-ndk. Then you would be able to build the game as a library that will be loaded by GameActivity. To do that run:

cargo ndk -t arm64-v8a -o android_example/app/src/main/jniLibs build --package bevy_mobile_example

After that in the CLI go to the android_example directory and run:

./gradlew build

You should now have the APK file in the android_example/app/build/outputs/apk/debug directory.

GLES3 setup

While Vulkan is already supported on most of the Android devices, going with GLES3 is still a good choice that lets cover more devices.

Setup the RenderPlugin in the DefaultPlugins:

// ...
use bevy::render::RenderPlugin;
use bevy::render::settings::{Backends, RenderCreation, WgpuLimits, WgpuSettings};
app.add_plugins(DefaultPlugins
    .set(RenderPlugin {
        render_creation: RenderCreation::Automatic(WgpuSettings {
            backends: Some(Backends::GL),
            limits: WgpuLimits::downlevel_webgl2_defaults(),
            instance_flags: InstanceFlags::default(),
            features: WgpuFeatures::empty(),
            ..default()
        }),
        ..default()
    }))
// ...

In the AndroidManifest.xml file, add the following line before the <application> tag:

    <uses-feature android:glEsVersion="0x00030002" android:required="true" />
    <uses-feature android:name="android.hardware.vulkan.version" android:required="false" />

    <!-- ... -->
    <application
        android:icon="@mipmap/ic_launcher"

Since Bevy 0.17 OpenGL is not enabled by default. To enable it, you need to add the following to your Cargo.toml file:

[target.'cfg(target_os = "android")'.dependencies.bevy_render]
version = "0.17"
features = ["gles"]

I learned it the hard way. On game startup on Android I was getting error: Unable to find a GPU! Make sure you have installed required drivers!.

Too weak device for PBR

If on startup of Bevy game on Android you get the following error:

Device::create_bind_group_layout, label = 'mesh_view_layout_oit'
 Too many bindings of type StorageBuffers in Stage ShaderStages(FRAGMENT), limit is 4, count was 5.
 Check the limit `max_storage_buffers_per_shader_stage` passed to `Adapter::request_device`

Good chance is that your device is too weak to run PBR. Make sure that you have bevy_pbr disabled in your Cargo.toml file. Or you can disable it by hand while doing setup for DefaultPlugins:

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins
            .set(LogPlugin {
                // This will show some log events from Bevy to the native logger.
                level: Level::INFO,
                filter: "wgpu=error".to_string(),
                ..Default::default()
            })
            .disable::<PbrPlugin>())
        .run();
}

Other notes

I also recommend checking out:

This work is licensed under CC BY-NC-SA 4.0.

avatar

Piotr Siuszko

GameDev tool engineer, C#/C++ at day, Rust at night.