Sloth is the fastest hot code reload library for FTC.
Hot reloading involves sending only your teamcode to the robot when you make a change, to get very fast Write -> Run -> Test development cycles. Say goodbye to waiting 40+ seconds for your teamcode to be uploaded, Sloth gets code on your robot in under a second.
Sloth is also a Sinister runtime that enables the use of Sinister's classpath scanning and dynamic loading capabilities on the android FTC platform. This allows Sloth to support a wide range of libraries that need to know about and react to hot reloading your code.
Sloth has some major improvements over its predecessor, fastload:
- Sloth is much faster than fastload. fastload advertises ~7 seconds upload time; Sloth has a upper ceiling of 2 seconds, but often is less than 1.
- Sloth will keep changes across restarts and power cycles of the robot.
- Sloth only processes the change in code when your OpMode ends, which means it is safe to deploy with Sloth while running other code.
@Pinnedcan be put on classes to prevent dynamically changing it, or any subclasses of it.- Sloth is a more capable runtime, that does more than just swap over your
code:
- Sloth sets up Dairy.
- Sloth updates parts of the SDK properly when you upload code changes, including your hardwaremap if you're uploading drivers with your teamcode (e.g. the goBILDA Pinpoint driver before it was part of the SDK).
- Libraries that rely on looking at your code, like FTC Dashboard, can be easily tweaked to be compatible with Sloth, and thus load faster, and support hotreloading. (Please open an issue if you have a favourite library that is currently incompatible with Sloth; I don't mind maintaining a fork, or doing the setup work to make it easy for others to maintain.)
- Sloth supports custom user classpath scanning, so you can write your own systems that listen and react to hot reloads.
- Sloth includes a drop-in replacement of FTC Dashboard and Panels that
replaces some internal mechanisms of FTC Dashboard / Panels to use the Sloth
and Sinister equivalents. This fork fully supports hot reloading for
Configuration (
@Config) and OpModes.
There are some precautions to take when using Sloth:
- Sloth will only dynamically hot reload classes in the
org.firsinspires.ftc.teamcodepackage (and subpackages). - It is possible to upload code that compiles, but does not work when hot
reloaded due to:
- Installing or changing libraries.
- Changing files that are not hot reloaded.
- Changing
@Pinnedon files. Be careful to ensure that you make changes that will be changed, and if make changes that will not, that you perform a full install in order to propagate them.
Note
If you are using FTC Dashboard, check out the FTC Dashboard section.
Note
If you're interested in an easier way to manage your ftc gradle build and dependencies, check out Dairy Templates, which have a template for using Sloth with all the work done for you.
We maintain some plugins and templates that make setting up FTC projects very easy for teams, and makes it easy to keep all your ftc libraries up to date and in sync.
Learn more about Dairy's gradle plugins and project templates here
If you're using the Dairy gradle plugins this process is well supported:
you can find an example here.
ftc {
dairy {
implementation(Sloth)
// if you want slothboard too
implementation(slothboard)
// if you want panels too
implementation(ftControl.fullpanels)
}
}You do not need to worry about excluding dashboard from roadrunner, it has already been done.
You do not need to add the repositories either.
You do need to install the Load plugin:
plugins {
// you should already have this line
id("dev.frozenmilk.teamcode") version "12.0.0-1.2.2"
// add this line
id("dev.frozenmilk.sinister.sloth.load") version "0.3.2"
}Then follow the steps to set up the gradle tasks.
Add the dairy repositories to your TeamCode build.gradle, above the
dependencies block:
repositories {
// Dairy releases repository
maven {
url = "https://repo.dairy.foundation/releases"
}
}This is a bit different depending on whether you are using other Dairy libraries or not:
Add sloth to the dependencies block:
dependencies {
implementation("dev.frozenmilk.sinister:Sloth:0.3.2")
}To use this release of Sloth with Dairy you need to install a snapshot version of Dairy's Core.
Add core to the dependencies block:
dependencies {
implementation("dev.frozenmilk.dairy:Core:2.2.4")
}Warning
You do not need to install Sloth as well, and if you currently have any
installations of either "dev.frozenmilk.dairy:Util" or
"dev.frozenmilk:Sinister" then you need to remove those, as this Core
version will provide the correct versions of these libraries.
Add this to the top of your TeamCode build.gradle:
buildscript {
repositories {
mavenCentral()
google()
maven {
url "https://repo.dairy.foundation/releases"
}
}
dependencies {
classpath "dev.frozenmilk:Load:0.3.2"
}
}Add this after the apply plugin: lines in the same file:
// there should be 2 or 3 more lines that start with 'apply plugin:' here
apply plugin: 'dev.frozenmilk.sinister.sloth.load'Sync and download the code onto your robot via standard install.
Now add the Gradle tasks.
NOTE: If you use FTC Dashboard, install that now, then setup the gradle tasks:
Add the dairy releases repository to your TeamCode build.gradle, above the
dependencies block (if you already have it, no need to do so again)
repositories {
maven {
url = "https://repo.dairy.foundation/releases"
}
}Then add dashboard to the dependencies block:
dependencies {
implementation("com.acmerobotics.slothboard:dashboard:0.3.2+0.6.0")
}Note
If you use a library that imports dashboard via a implementation or api
dependency, ask the library maintainers to consider changing it to
compileOnly. This will allow it to work with the modified version of FTC
Dashboard that Sloth uses.
Change the implementation like so:
implementation("com.acmerobotics.roadrunner:ftc:0.1.25") {
exclude group: "com.acmerobotics.dashboard"
}
implementation ("com.acmerobotics.roadrunner:actions:1.0.1"){
exclude group: "com.acmerobotics.dashboard"
}Road Runner version numbers may not be up to date; they are provided only as an example.
Add the dairy releases repository to your TeamCode build.gradle, above the
dependencies block (if you already have it, no need to do so again)
repositories {
maven {
url = "https://repo.dairy.foundation/releases"
}
}Then add panels to the dependencies block:
dependencies {
implementation("com.bylazar.sloth:fullpanels:0.3.2+1.0.13")
}Note
You can also add all the panels dependencies one-by-one if you want to be
selective, which works the same way: com.bylazar -> com.bylazar.sloth and
<version> -> 0.3.2+<version>, you can see all the details at the
dairy repository
Note
If you use a library that imports dashboard via a implementation or api
dependency, ask the library maintainers to consider changing it to
compileOnly. This will allow it to work with the modified version of Panels
that Sloth uses.
Edit configurations:
Add new configuration:
Select gradle:
Add deploySloth and save it:
NOTE: android studio will not auto complete the names of these tasks, just write
it and it will work.
Edit TeamCode configuration:
Add new gradle task:
Add removeSlothRemote:
Note: Type :TeamCode into the Gradle Project box to get the right contents,
do not copy mine.
Put removeSlothRemote first and save:
Run the deploySloth task you just added to deploy the code.
Congratulations! You are now set up with lightning-fast software deployment using Sloth.
If your robot previously had Sloth and Load set up, but now you only have Sloth and have no interest in setting up Load, then you may need to manually remove the sloth loaded code from your robot. Not doing this can make it impossible for you to upload code to your robot, as the old sloth loaded code keeps replacing it.
This is a common issue for teams getting nextv2 or pedro3 in the 2026-2027 season.
There are two ways to do this:
Graphically, you can go to the device file explorer in android studio while connected to it, locate this directory, and delete it:
Or, you can use an adb shell command to do it from the cli:
adb shell rm -rf /storage/emulated/0/FIRST/dairy/sloth/*Both methods require that you are already connected to the robot with adb.







