Question

Add a Maven Repository URL in Gradle Kotlin DSL (build.gradle.kts)

kotlingradlegradle-kotlin-dsl

Question

What is the Kotlin DSL equivalent of this Groovy Gradle configuration for adding Maven Central and a custom Maven repository URL?

repositories {
    mavenCentral()
    maven {
        url '<MAVEN REPO URL>'
    }
}

How should this be written in a build.gradle.kts file?

Short Answer

You will learn how Gradle Kotlin DSL configures repositories, why repository URLs are converted with uri(...), and how to add Maven Central alongside a private or third-party Maven repository in build.gradle.kts.

Concept

Gradle needs to know where to download dependencies such as libraries, plugins, and their metadata. The repositories block defines those locations.

In Groovy Gradle scripts (build.gradle), Gradle allows a compact dynamic syntax:

url 'https://example.com/repository/maven-releases/'

Kotlin DSL (build.gradle.kts) is statically typed. The url property of a Maven repository expects a URI, not a plain String. Therefore, convert the URL string with Gradle's uri(...) helper:

url = uri("https://example.com/repository/maven-releases/")

This matters because Kotlin DSL catches more configuration mistakes earlier and provides better IDE completion and navigation than dynamic Groovy syntax.

Mental Model

Think of repositories as package warehouses.

  • mavenCentral() registers the large public Maven Central warehouse.
  • maven { ... } registers another warehouse.
  • url = uri("...") writes the warehouse's precise address in a format Gradle understands.

A dependency declaration tells Gradle what package you need; a repository declaration tells Gradle where to look for it.

Take Quiz

Syntax and Examples

Use a repositories block and assign the Maven repository's url property with uri(...).

repositories {
    mavenCentral()

    maven {
        url = uri("https://repo.example.com/maven/")
    }
}

The Kotlin DSL equivalent of the original configuration is:

repositories {
    mavenCentral()

    maven {
        url = uri("<MAVEN REPO URL>")
    }
}

For example, a project that retrieves dependencies from Maven Central and an internal company repository might use:

repositories {
    mavenCentral()

    maven {
        name = "company-releases"
        url = uri("https://packages.example.com/repository/releases/")
    }
}

Giving a repository a name is optional, but it makes Gradle logs and build diagnostics easier to read.

Step by Step Execution

Consider this build script:

repositories {
    mavenCentral()

    maven {
        name = "company-releases"
        url = uri("https://packages.example.com/repository/releases/")
    }
}

dependencies {
    implementation("com.example:reporting-sdk:1.2.0")
}

When Gradle resolves com.example:reporting-sdk:1.2.0, it generally does the following:

  1. It reads the repositories block and registers Maven Central.
  2. It creates another Maven repository named company-releases.
  3. uri(...) converts the text URL into a URI object and assigns it to the repository.
  4. It reads the dependency coordinate: group com.example, artifact reporting-sdk, version 1.2.0.
  5. Gradle searches the configured repositories in their declared order until it finds matching metadata and the artifact.
  6. Gradle downloads the dependency into its local cache, then compiles or runs the project with it.

Repository order can matter if more than one repository contains the same group, artifact, and version.

Real World Use Cases

Custom Maven repositories are common when dependencies are not published to Maven Central.

  • Private company libraries: A team publishes shared authentication, logging, or UI libraries to an internal repository.
  • Third-party package hosting: Some vendors host their Android, JVM, or Kotlin libraries in a dedicated Maven repository.
  • Release and snapshot separation: Stable versions may be stored in one URL and development snapshots in another.
  • Internal build infrastructure: An organization may proxy Maven Central through Nexus or Artifactory for caching, auditing, and access control.
  • Plugin and library distribution: A project can publish its own artifacts and allow other applications to consume them through a Maven-compatible URL.
Take Quiz

Real Codebase Usage

In production projects, repository configuration is usually kept deliberate and centralized.

Name custom repositories

repositories {
    mavenCentral()

    maven {
        name = "internal"
        url = uri("https://repo.example.com/maven-public/")
    }
}

A name improves error messages and makes it easier to identify the source of a dependency.

Read the URL from a Gradle property

Avoid hard-coding environment-specific URLs when builds run locally and in CI.

val internalRepoUrl: String by project

repositories {
    mavenCentral()
    maven {
        name = "internal"
        url = uri(internalRepoUrl)
    }
}

Then provide the value in gradle.properties or through a CI environment configuration:

internalRepoUrl=https://repo.example.com/maven-public/

Use credentials without committing secrets

val repoUser: String? by project
val repoPassword: String? by project

repositories {
    maven {
        name = "private-repository"
        url = uri("https://repo.example.com/maven-private/")

        credentials {
            username = repoUser
            password = repoPassword
        }
    }
}

Store real credentials in a local, uncommitted Gradle properties file, environment variables, or a CI secret manager—not directly in the build script.

Centralize repositories in multi-project builds

Modern Gradle builds often declare dependency repositories in settings.gradle.kts so all modules follow the same policy:

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        mavenCentral()
        maven {
            name = "internal"
            url = uri("https://repo.example.com/maven-public/")
        }
    }
}

This prevents one module from silently adding an unexpected repository.

Common Mistakes

Using Groovy assignment syntax in Kotlin DSL

This is valid in Groovy, but not Kotlin DSL:

maven {
    url "https://repo.example.com/maven/"
}

Use an assignment and uri(...) instead:

maven {
    url = uri("https://repo.example.com/maven/")
}

Assigning a plain string to url

This does not match the expected URI type:

maven {
    url = "https://repo.example.com/maven/"
}

Correct version:

maven {
    url = uri("https://repo.example.com/maven/")
}

Putting repositories inside dependencies

repositories and dependencies are separate Gradle blocks:

// Incorrect
dependencies {
    repositories {
        mavenCentral()
    }
}

Place them at the project level, or configure them centrally in settings.gradle.kts.

Confusing dependency repositories with plugin repositories

Libraries declared in dependencies {} use dependency repositories. Plugins declared in plugins {} may need repositories under pluginManagement in settings.gradle.kts.

Committing repository passwords

Do not write secrets directly in source-controlled build files:

// Unsafe
password = "my-secret-password"

Use Gradle properties, environment variables, or your CI platform's secret storage instead.

Adding untrusted repositories unnecessarily

Every added repository expands the places from which Gradle can resolve artifacts. Prefer known repositories, use a repository manager where appropriate, and keep the list minimal.

Comparisons

TaskGroovy DSL (build.gradle)Kotlin DSL (build.gradle.kts)
Add Maven CentralmavenCentral()mavenCentral()
Add custom Maven repositorymaven { url 'https://...' }maven { url = uri("https://...") }
Set a repository namename 'internal'name = "internal"
URL value typeGroovy can coerce a string dynamicallyKotlin DSL expects a URI
Repository methodBest use
mavenCentral()Public libraries available from Maven Central
mavenLocal()Testing artifacts published to your local Maven cache; avoid as a default for reproducible builds
maven { url = uri(...) }Private, company, vendor, release, or snapshot Maven repositories
google()Android and Google artifacts in Android projects
Take Quiz

Cheat Sheet

repositories {
    mavenCentral()

    maven {
        name = "optional-readable-name"
        url = uri("https://repo.example.com/maven/")
    }
}
  • Use build.gradle.kts for Kotlin DSL.
  • Use = for property assignment.
  • Wrap repository URL strings in uri(...).
  • name is optional but useful for diagnostics.
  • Repository order affects where Gradle searches first.
  • Put dependency repositories in repositories {}.
  • Configure plugin repositories separately with pluginManagement { repositories { ... } } when needed.
  • Do not commit usernames, passwords, tokens, or private repository credentials.

FAQ

What is the Kotlin DSL syntax for a Maven repository URL?

maven {
    url = uri("https://repo.example.com/maven/")
}

Why is uri(...) required in build.gradle.kts?

The Maven repository url property expects a URI. uri(...) converts a string URL into the required type.

Can I use mavenCentral() and a custom Maven repository together?

Yes. Add both inside the same repositories block.

repositories {
    mavenCentral()
    maven { url = uri("https://repo.example.com/maven/") }
}

Is the repository name required?

No. name = "internal" is optional, but it makes logs and errors clearer.

Where should I place the repositories block?

For a single project, place it in build.gradle.kts. For multi-module projects, dependency repositories are often centralized in settings.gradle.kts using dependencyResolutionManagement.

How do I add credentials for a private Maven repository?

Use the credentials block and load values from Gradle properties, environment variables, or CI secrets. Do not hard-code secrets in the script.

Does a custom dependency repository also configure Gradle plugins?

Not necessarily. Plugin resolution can require repository configuration under pluginManagement in settings.gradle.kts.

Take Quiz

Mini Project

Description

Create a small Kotlin/JVM Gradle build that resolves normal dependencies from Maven Central and is ready to resolve organization-specific libraries from a custom Maven repository. This mirrors the setup used by many internal applications.

Goal

Configure a build.gradle.kts file with Maven Central, a named custom Maven repository, and one dependency.

Requirements

Requirement 1

Take Quiz

Keep learning

Related questions

View more