Library for hotreload in Rust. Hotreload allows you to change your code without restarting application.
Though you can use it in --release build, it's primarily intended to speed-up development process and shouldn't be
used in production.
Usage with software renderer:

Usage with bevy example:

Your crate must be lib crate. You can have separate binaries in it though.
Steps to use this library:
- Add
code_reloadtoCargo.tomldependencies:
[dependencies]
code_reload = *- Add
crate-type = ["cdylib", "lib"]tolibsection inCargo.toml(your crate must produce dynamic library):
[lib]
crate-type = ["cdylib", "lib"]- Label function you want to make hotreloadable with
#[hotreload]attribute:
use code_reload::hotreload;
#[hotreload]
fn add(a: i32, b: i32) -> i32 {
a + b
}Run your binary application, change add function and then try to rebuild it without stopping running application. You
should see that add now returns different value!
This approach makes it so that each call to function labeled with #[hotreload] actually loads your dynamic library,
searches this method there, calls it and unloads library, which is of course very slow.
But there is faster approach! We don't need to load/unload dynamic library with each call, we can keep it in memory and reload only when new version is available. Next section tells how to utilize this approach.
This approach is only more complicated in that it requires more to do in one time setup. After you've completed set up
you'll only need to add #[hotreload(runtime)] to your functions just like in simple approach.
Your crate must be lib crate. You can have separate binaries in it though.
This approach also uses build script (later on that).
Steps to use this library:
- Add
code_reloadwithruntimefeature toCargo.tomldependencies and build dependencies:
[dependencies]
code_reload = { version = "*", features = ["runtime"] }
[build-dependencies]
code_reload = { version = "*", features = ["runtime"] }- Add
crate-type = ["cdylib", "lib"]tolibsection inCargo.toml(your crate must produce dynamic library):
[lib]
crate-type = ["cdylib", "lib"]- Add
code_reload::runtime::build()to your build script (thebuild.rsfile in the root of your crate). This function parses your code and generates dynamic library wrapper structures that hold pointers to hotreloadable functions.
// build.rs
fn main() {
code_reload::runtime::build();
}-
Add
code_reload::runtime::add_runtime!();anywhere in your crate's root (presumably inlib.rsfile, if you're not sure see examples). -
Add
code_reload::runtime::start_watchers!(your_crate_name)somewhere in your binary'smainfunction. This spawns watcher that looks after your dynamic library file and reloads dynamic library when it changes.your_crate_nameis eitherpackage.namefromCargo.tomlor justcrateif your binary is located in the same place as your library's code.
// main.rs
fn main() {
code_reload::runtime::start_watchers!(your_crate_name);
// your code
}- Label function you want to make hotreloadable with
#[hotreload(runtime)]attribute:
use code_reload::hotreload;
#[hotreload(runtime)]
fn add(a: i32, b: i32) -> i32 {
a + b
}Run your binary application, change add function and then try to rebuild it without stopping. You should see that
add now returns different value!
You can see usage examples in examples directory.
See LIMITATIONS.md (yes, unfortunately there are enough of them for justifying creation of separate file, but their number could be reduced in future).
Benchmarks are located in benchmarks folder. You can run them to see the execution time of no hotreload, simple hotreload and runtime hotreload invocation of same function that calculates Fibonacci numbers.
Here is random sample of benchmark results from my PC (i7-14700HX):
no hotreload fibonacci time: [16.245 ns 16.348 ns 16.469 ns]
simple hotreload fibonacci time: [95.439 µs 96.832 µs 98.403 µs]
runtime hotreload fibonacci time: [19.498 ns 19.692 ns 19.917 ns]
- write about
code_reload::runtime::buildfor tests and separate directories