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 forkrootProject.name = "how_to_use_a_local_fork"
include("my-app")
includeBuild("my-fork")  // Path to your local forkThis 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 subprojectrootProject.name = "my-fork"
include("okhttp") // The forked module as a subprojectThe 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.ktscorrectly references your local fork withincludeBuild.
Summary
Gradle composite builds provide a straightforward and efficient method to substitute external module dependencies with local forks.