How to Use a Local Fork of a Module Dependency with Gradle
This guide explains how to replace a module dependency with a local fork of the module’s sources, assuming the module itself is built with Gradle.
Using a local fork allows you to:
-
Apply and test custom patches to a dependency.
-
Work with an unreleased version of a library.
-
Avoid relying on the published binary version.
Prerequisites
-
The module must be built with Gradle.
-
You must have a local copy of the module’s source code.
-
The local module should be set up as a Gradle build.
Gradle composite builds automatically substitute external dependencies with local forks.
Step 1: Create a Composite Build
Assume your initial project structure looks like this:
project
├── settings.gradle(.kts) (1)
└── my-app
├── build.gradle(.kts) (2)
└── src (3)
1 | Existing settings file |
2 | Existing build file |
3 | Existing app project that uses the external dependency |
In this example, our app depends on com.squareup.okhttp:okhttp:2.7.5
, and we want to use a local fork of it:
dependencies {
implementation("com.squareup.okhttp:okhttp:2.7.5")
}
dependencies {
implementation("com.squareup.okhttp:okhttp:2.7.5")
}
First, create a new folder for your local fork of the dependency:
project
├── settings.gradle(.kts)
├── my-app
│ ├── build.gradle(.kts)
│ └── src
└── my-fork (1)
1 | New directory for the composite build containing the local fork |
In your root project’s settings.gradle(.kts)
file, add an includeBuild
statement pointing to my-fork
:
rootProject.name = "how_to_use_a_local_fork"
include("my-app")
includeBuild("my-fork") // Path to your local fork
rootProject.name = "how_to_use_a_local_fork"
include("my-app")
includeBuild("my-fork") // Path to your local fork
This instructs Gradle to automatically substitute the external dependency coordinates with your local build.
Step 2: Include The Local Fork
Composite builds allow us to use a local version of okhttp
with minimal configuration changes.
Assuming the local fork is already a Gradle build, copy or move it into the my-fork
directory.
The forked module will have its own settings and build files.
The updated project structure will look like this:
project
├── settings.gradle(.kts)
├── my-app
│ ├── build.gradle(.kts)
│ └── src
└── my-fork (1)
├── settings.gradle(.kts) (2)
└── okhttp
├── build.gradle(.kts) (3)
└── src (4)
1 | New included build for fork of okhttp |
2 | Settings file for the forked module |
3 | Build file for the forked module |
4 | Source code of the forked module |
The source code of com.squareup.okhttp:okhttp:2.7.5
is in the okhttp/src
folder.
The settings file should look like this:
rootProject.name = "my-fork"
include("okhttp") // The forked module as a subproject
rootProject.name = "my-fork"
include("okhttp") // The forked module as a subproject
The build file must have the same GAV coordinates as required by my-app
:
plugins {
id("java-library")
}
// Matches implementation("com.squareup.okhttp:okhttp:2.7.5") in my-app build file
group = "com.squareup.okhttp" // Matches original dependency
version = "2.7.5" // Matches original dependency version = "2.7.5"
plugins {
id("java-library")
}
// Matches implementation("com.squareup.okhttp:okhttp:2.7.5") in my-app build file
group = "com.squareup.okhttp" // Matches original dependency
version = "2.7.5" // Matches original dependency version = "2.7.5"
Step 3: Declare the Dependency Normally
In your project’s build.gradle(.kts)
, continue declaring the dependency using the same external coordinates as originally:
repositories {
mavenCentral() // Don't remove this!
}
dependencies {
implementation("com.squareup.okhttp:okhttp:2.7.5") // This doesn't need to change!
}
repositories {
mavenCentral() // Don't remove this!
}
dependencies {
implementation("com.squareup.okhttp:okhttp:2.7.5") // This doesn't need to change!
}
You don’t need explicit substitution statements in the build.gradle(.kts)
file; Gradle handles substitution automatically.
With this setup, Gradle will automatically use your local fork instead of downloading the dependency from remote repositories.
Step 4: Troubleshooting
If Gradle is still attempting to resolve your dependency externally, verify that:
-
The local fork (
build.gradle.kts
) specifies exactly the same coordinates (group
,name
, andversion
) as your external dependency. -
Your
settings.gradle.kts
correctly references your local fork withincludeBuild
.
Summary
Gradle composite builds provide a straightforward and efficient method to substitute external module dependencies with local forks.