vexide v0.8 is a new version of the runtime including improvements such as: support for the Rust Standard Library, new async runtime APIs, support for encoders with custom resolutions, the option to use the official VEX SDK, and various bug fixes. While we have aimed to minimize breaking changes, you will need to update your existing projects to make them compatible with this new release.
Project Migration Tool
For this release, we’ve added an automatic migration tool to do much of the hard part for you:
cargo v5 migrate
This will handle updating vexide, enabling the Rust Standard Library, and updating your project’s Cargo configuration. However, it won’t handle any changes to vexide’s API, so if you encounter any build errors after the update, consult the API Changes section.
You’ll need to have the latest version of cargo-v5 installed to use this command, so make sure to update it beforehand with cargo v5 self-update. We also strongly suggest testing the upgrade on a separate branch, then merging it once you’ve reviewed the changes to your code and verified that they work.
Even if you run the upgrade tool with no complications, we still recommend reading through all of the API Changes included in 0.8.0 to get a good idea of what’s changed and make sure the upgrade tool didn’t miss anything.
Manual Upgrade Guide
Here’s a comprehensive guide on upgrading to vexide v0.8 from v0.7. Apart from the API Changes, most of these differences can be handled by our Project Migration Tool.
Update cargo-v5
Update to the latest version of cargo-v5 (0.12.0 at the time of writing this).
cargo v5 self-update
Update Rust
Update your rust-toolchain.toml file to install a newer version of Rust nightly (must be 1.91 or newer).
[toolchain]channel = "nightly-2025-11-26"channel = "nightly"components = ["rust-src"]Update vexide
To use vexide 0.8.0, you’ll need to update it in your dependencies table, then choose which SDKs you’d like to enable. Use the configuration below to keep your project’s existing behavior.
[dependencies]vexide = "0.7.0"[dependencies.vexide]version = "0.8.0"features = ["full", "default-sdk"]
If you’re updating a library that uses vexide, don’t enable full
or any of the SDK features.
Please read the
vexide features guide for more information.
Enable Standard Library Support
In vexide 0.8.0, projects use Rust’s new builtin support for VEX V5 devices. As a result, you may now use the comprehensive Rust Standard Library (std) in your vexide projects! Enable it by taking the following steps:
Update .cargo/config.toml to use Rust’s builtin VEX V5 support and enable the standard library.
[build]target = "./armv7a-vex-v5.json"[unstable]build-std = ["std", "panic_abort"]build-std = ["core", "compiler_builtins", "alloc"]build-std-features = ["compiler-builtins-mem"]Delete the old armv7a-vex-v5.json target file.
{ "cpu": "cortex-a9", "arch": "arm", "abi": "eabihf", // ...etc...}Update your project’s source code to allow importing from the standard library.
#![no_main]#![no_std]extern crate alloc;use vexide::prelude::*;#[vexide::main]async fn main(peripherals: Peripherals) { println!("Hello, world!");}Enable vexide’s Custom Memory Layout
In order to support features like differential uploading and async task-locals, vexide v0.8 requires all projects to enable its custom memory layout in the Cargo config file:
[target.'cfg(target_os = "vexos")']rustflags = ["-Clink-arg=-Tvexide.ld"][unstable]build-std = ["std", "panic_abort"]build-std-features = ["compiler-builtins-mem"]API Changes
This section describes the most common breakages in projects when updating to v0.8.0. Some changes are not included here. Check out the vexide changelog for a comprehensive list!
Position Arithmetic
Position structs are now internally represented as floating point values.
let pos1 = Position::from_degrees(90.0);let pos2 = pos1 / 2;let pos3 = pos1 * 2;let pos2 = pos1 / 2.0;let pos3 = pos1 * 2.0;
ADI Encoder Ticks
The AdiEncoder struct now requires you to specify a custom encoder Ticks Per Revolution value. To keep the old behavior, use AdiOpticalEncoder.
let encoder = AdiEncoder::new(peripherals.adi_a, peripherals.adi_b);let encoder = AdiOpticalEncoder::new(peripherals.adi_a, peripherals.adi_b);
New Angle type
There is a new unit-aware Angle type used to store rotational displacements, replacing the old Position type. Functions and structs that previously worked with an angle in degrees or radians now use the new Angle type.
let gyro = AdiGyroscope::new(peripherals.adi_a);let yaw_pos: Position = gyro.yaw()?;let yaw_pos: Angle = gyro.yaw()?;let potentiometer = AdiPotentiometer::new(peripherals.adi_a, PotentiometerType::V2);let angle: f64 = potentiometer.angle()?;let angle: Angle = potentiometer.angle()?;let mut sensor = InertialSensor::new(peripherals.port_1);sensor.calibrate().await?;let rotation: f64 = sensor.rotation()?;let rotation: Angle = sensor.angle()?;
Angle revolutions are now called turns.
let pos = Position::from_revolutions(10.0);let angle = Angle::from_turns(10.0);
Display coordinates are half-open
When using vexide’s shape-drawing APIs, the bottom-right coordinate is no longer included in the shape’s bounds. As a result, you no longer need to add 1 when calculating a rectangle’s width or height.
Additionally, the points in a Rect have been renamed to bottom_right and top_left.
// Create a 20x20 rectangle:let rect = Rect::new([30, 40], [49, 59]);let rect = Rect::new([30, 40], [50, 60]);// Check its width:let width = 1 + rect.end.x - rect.start.x;let width = rect.bottom_right.x - rect.top_left.x;assert_eq!(width, 20);
Rotation Sensor Calculation Interval
The function for changing the calculation interval of a RotationSensor was renamed from set_computation_interval to set_data_interval.
let mut sensor = RotationSensor::new(peripherals.port_1, Direction::Forward);let interval = Duration::from_millis(10);sensor.set_computation_interval(interval)?;sensor.set_data_interval(interval)?;
Buffer stride removed
The Display::draw_buffer function no longer takes a stride argument.
let buf: &[u32] = [ 0, 0, 0, 0, // row 1 // ...etc...];let region = Rect::new([1, 1], [4, 4]);let width = 1 + region.end.x - region.start.x;display.draw_buffer(region, buf, width);display.draw_buffer(region, buf);
Crate submodule layout
The vexide crate now has fewer deeply-nested modules. For instance, all vexide::devices:: modules are now imported from vexide::.
use vexide::devices::smart::motor::MotorStatus;use vexide::smart::motor::MotorStatus;
Additionally, items that are included in the Rust Standard Library should no longer be imported from vexide.
use vexide::io::Error;use std::io::Error;
New Color type
The Color type should now be used instead of Rgb. It’s now imported from vexide::color.
use vexide::devices::rgb::Rgb;use vexide::color::Color;let rect = Rect::new([20, 30], [40, 50]);display.fill(&rect, Rgb::new(0xFF, 0xFF, 0xFF));display.fill(&rect, Color::new(0xFF, 0xFF, 0xFF));// Or...display.fill(&rect, Color::WHITE);
Touch events have a Point
Display touch events now store their x and y coordinates in a Point.
// Draw a circle wherever the user touches.loop { let event = display.touch_status(); let circle = Circle::new( [event.x, event.y], event.point, 10, ); display.fill(&circle, Color::WHITE); sleep(Duration::from_millis(5)).await;}
Error types updated
Some functions now return different error types, or their errors types have been renamed.
| Before | After |
|---|---|
MotorError | PortError |
DistanceError | DistanceObjectError |
AiVisionError | AiVisionObjectError |
AdiGyroscopeError | YawError |
Cargo features renamed
Some of vexide’s optional features have been renamed.
| Before | After |
|---|---|
backtraces | backtrace |
dangerous_motor_tuning | dangerous-motor-tuning |
force_rust_libm | (removed) |
[dependencies.vexide]version = "0.8"default-features = falsefeatures = ["backtraces"]features = ["backtrace"]See the features page for a full list of features available in 0.8.0.
Text drawing uses C Strings
The Text::new function now requires you to pass in a C string.
let text = Text::new( "Hello, world", c"Hello, world", Font::default(), [50, 50],);
You can use the new Text::from_string to keep the old behavior.
let string = "Hello, world".to_string();let text = Text::from_string( string, Font::default(), [50, 50],);
Text alignment uses one struct
The HAlign and VAlign structs have been merged into the Alignment type.
let mut text = Text::new( c"Hello, world", Font::default(), [50, 50],);text.align( HAlign::Center, VAlign::Center, Alignment::Center, Alignment::Center,);
Manual usage of startup function
This is an advanced feature and it is unlikely your project is affected. If you use the
#[vexide::main] attribute, this change does not affect your project.
The vexide::startup::startup() function no longer handles printing vexide’s banner message.
If you are manually calling vexide::startup::startup(), you will need to explicitly print vexide’s banner to keep the previous behavior.
unsafe { vexide::startup::startup::<true>(); vexide::startup::startup(); vexide::startup::banner::print();}