# How to Use a Local Fork of a Module Dependency with Gradle

version 9.0.0

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:

my-app/build.gradle.kts

    dependencies {
        implementation("com.squareup.okhttp:okhttp:2.7.5")
    }

my-app/build.gradle

    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`:

settings.gradle.kts

    rootProject.name = "how_to_use_a_local_fork"

    include("my-app")
    includeBuild("my-fork")  // Path to your local fork

settings.gradle

    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:

my-fork/settings.gradle.kts

    rootProject.name = "my-fork"

    include("okhttp") // The forked module as a subproject

my-fork/settings.gradle

    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`:

my-fork/okhttp/build.gradle.kts

    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"

my-fork/okhttp/build.gradle

    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:

my-app/build.gradle.kts

    repositories {
        mavenCentral() // Don't remove this!
    }

    dependencies {
        implementation("com.squareup.okhttp:okhttp:2.7.5") // This doesn't need to change!
    }

my-app/build.gradle

    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`, and `version`) as your external dependency.

- Your `settings.gradle.kts` correctly references your local fork with `includeBuild`.

## Summary

Gradle composite builds provide a straightforward and efficient method to substitute external module dependencies with local forks.