Install
Synapse is distributed as a Maven artifact, com.aaravlabs:synapse:0.4.0, published to Maven Central. Maven Central needs no authentication — if your project already has mavenCentral() in its repositories (the FTC template does), you can add the dependency and you’re done:
dependencies {
implementation 'com.aaravlabs:synapse:0.4.0'
}
Prefer GitHub Packages? Synapse is also mirrored on GitHub Packages at
maven.pkg.github.com/IamCoder18/synapse. That mirror requires a GitHub token with theread:packagesscope even for public packages — a GitHub restriction, not a Synapse one. See the advanced section at the bottom of this page for the full walkthrough.
Prerequisites
- An FTC project built on the standard
FtcRobotControllertemplate (usesbuild.dependencies.gradle). - Android Studio with the FTC project already syncing.
Step 1 — Add the dependency
Open build.dependencies.gradle in your FTC project and add the dependency:
dependencies {
implementation 'com.aaravlabs:synapse:0.4.0'
// ... your other FTC deps
}
No repository block needed? Correct — the
FtcRobotControllertemplate ships withmavenCentral()andgoogle()in itsrepositories {}. If your project removed them, re-addmavenCentral()next togoogle().
Using a version catalog or a newer SDK? The Maven coordinates stay the same (
com.aaravlabs:synapse) — only the surrounding syntax changes:dependencies { implementation("com.aaravlabs:synapse:0.4.0") }
Step 2 — Sync and verify
Sync Gradle (the Sync Now banner, or the Gradle elephant in Android Studio), then confirm the JAR landed:
./gradlew dependencies --configuration debugRuntimeClasspath | grep synapse
You should see com.aaravlabs:synapse:0.4.0 in the output.
Sync fails with “Could not resolve com.aaravlabs:synapse”? Make sure the dependency is in the project-level
dependencies {}ofbuild.dependencies.gradle(notbuildscript), and thatmavenCentral()is present in that file’srepositories {}.
R8 / minification
Synapse ships its ProGuard keep rules inside the JAR at META-INF/proguard/synapse.pro, so minifyEnabled builds work with no extra configuration. The keep rules are exercised in CI by running the full test suite through R8 minification.
What you get
A ~40 KB JAR with zero runtime dependencies, containing:
Orchestrator— the pub/sub bus and thread owner.- The four annotations:
@SubscribedTo,@RunPeriodically,@RunnableAction,@OnHardwareThread. - The FTC layer:
SafeOpMode,HardwareActions,SafeDevice,SafeHardwareMap,GamepadAdaptor.
Advanced: GitHub Packages mirror
Everything above is the recommended path. Synapse is additionally mirrored on GitHub Packages at maven.pkg.github.com/IamCoder18/synapse. Use the mirror if your team already authenticates against GitHub — for example because your organization proxies GitHub repositories, or your build pipeline signs in with a GitHub App. If in doubt, stay on Maven Central: it needs no credentials.
GitHub Packages requires authentication for downloads even though the package is public. This is a GitHub restriction, not a Synapse one.
1 — Configure a GitHub token
Create a personal access token (classic) with the read:packages scope — fine-grained tokens are not accepted by GitHub Packages — then put it in ~/.gradle/gradle.properties (never commit this file):
githubUser=<your-github-username>
githubToken=<your-token>
Why a token at all? GitHub Packages requires authenticated downloads even when the package is public. The token lives in your local
gradle.propertiesand is only transmitted tomaven.pkg.github.comover HTTPS when Gradle resolves the dependency; it has no scopes beyond package reads.
In a GitHub Actions workflow? Use the workflow’s built-in
GITHUB_TOKENwithpackages: readpermission instead of a personal token — the snippets below already fall back to theGITHUB_TOKENenvironment variable.
If you are on a team, each member (and the driver station’s build environment) needs their own token in their own gradle.properties.
2 — Add the repository and dependency
Open build.dependencies.gradle in your FTC project and add the mirror repository and the dependency.
Groovy DSL (the default FTC template):
repositories {
mavenCentral()
google()
maven {
url = uri("https://maven.pkg.github.com/IamCoder18/synapse")
credentials {
username = findProperty("githubUser") ?: System.getenv("GITHUB_USER") ?: System.getenv("GITHUB_ACTOR")
password = findProperty("githubToken") ?: System.getenv("GITHUB_TOKEN")
}
}
}
dependencies {
implementation 'com.aaravlabs:synapse:0.4.0'
}
Kotlin DSL (if your project uses build.dependencies.gradle.kts):
repositories {
mavenCentral()
google()
maven {
url = uri("https://maven.pkg.github.com/IamCoder18/synapse")
credentials {
username = (findProperty("githubUser") as String?)
?: System.getenv("GITHUB_USER")
?: System.getenv("GITHUB_ACTOR")
password = (findProperty("githubToken") as String?)
?: System.getenv("GITHUB_TOKEN")
}
}
}
dependencies {
implementation("com.aaravlabs:synapse:0.4.0")
}
Using a version catalog or a newer SDK? The coordinates stay the same — only the surrounding syntax changes. Keep the
maven { ... }block as-is.
3 — Sync and verify
Sync Gradle, then confirm the JAR landed:
./gradlew dependencies --configuration debugRuntimeClasspath | grep synapse
You should see com.aaravlabs:synapse:0.4.0 in the output.
Sync fails with 401 Unauthorized?
- Check that
githubUserandgithubTokenare spelled exactly like that in~/.gradle/gradle.properties.- Check that the token has
read:packages.- Run
./gradlew --refresh-dependenciesonce to force re-authentication.- If you copied the token with surrounding whitespace, remove it.
Sync fails with “Could not resolve com.aaravlabs:synapse”? Make sure the
maven { ... }block is insiderepositories { }(notbuildscript), and that the credentials block usesfindPropertyexactly as shown.
Next steps
- Write your first OpMode — one motor, one stick, five minutes.
- Understand the architecture before scaling past one motor.