Skip to content

Transitive resources for Kotlin

Embed static resources in your Kotlin JS or multiplatform libraries.

View repository • Learn more about us • Kotlin Slack • Join our Discord • Mastodon • Bluesky

Welcome!

In the JVM ecosystem, any file created in src/main/resources is included in the generated JAR. When a module depends on another one, it automatically gets access to all its static resources.

However, the Kotlin Gradle plugin does not implement this behavior for other platforms. If you're creating a KotlinJS library and want to include a font or a TailwindCSS configuration file? Tough luck.

This project introduces two Gradle plugins that embed any file in a library module and access it in any project that depends on it. You can use it to share files in a large multi-module project, and the files will also be embedded when publishing to MavenCentral or any other Maven registry.

On the library side

If you are creating a library and want to embed static resources, add the producer plugin:

// build.gradle.kts
plugins {
    kotlin("multiplatform") version "<add the version here>"
    id("dev.opensavvy.resources.producer") version "<add the version here>" //(1)!
}

kotlin {
    js {
        // …
    }
}
  1. See the list of versions.

That's it! Any files placed in src/jsMain/resources will be available to any project that uses the consumer plugin. This also works if you publish your library to a Maven or Ivy repository.

On the consumer side

The Kotlin Gradle Plugin doesn't access the embedded files by itself. To do so, use the consumer plugin:

// build.gradle.kts
plugins {
    kotlin("multiplatform") version "<add the version here>"
    id("dev.opensavvy.resources.consumer") version "<add the version here>" //(1)!
}

kotlin {
    js {
        // …
    }
}
  1. See the list of versions.

The plugin doesn't extract the resources automatically from your other dependencies: you should explicitly declare from which library you want to extract dependencies.

For example, to extract all resources from a project called :lib:

kotlin {
    js {
        // …
    }

    sourceSets.jsMain.dependencies {
        implementation(project(":lib")) //(1)!
    }
}

dependencies {
    commonConsumedResources(project(":lib")) //(2)!
}
  1. This is a regular dependency on the source code. This is not necessary: if you remove this line, you depend only on that library's static files and not its code.
  2. Declares a dependency on the static files of the project :lib. Instead of commonConsumedResources, you can also depend only on a single platform, for example with jsConsumedResources.

To extract resources from an external library, use the same system:

kotlin {
    js {
        // …
    }

    sourceSets.jsMain.dependencies {
        implementation("foo:bar:1.0") //(1)!
    }
}

dependencies {
    commonConsumedResources("foo:bar:1.0") //(2)!
}
  1. This is a regular dependency on the library foo:bar:1.0. This is not necessary: if you remove this line, you depend only on that library's static files and not its code.
  2. Declares a dependency on the static files of the library foo:bar:1.0. Instead of commonConsumedResources, you can also depend only on a single platform, for example with jsConsumedResources.

The resources will automatically be copied as if they were present in your src/commonMain/resources/imported folder. Therefore, if you depend on a library which has a file index.css, you can access it as imported/index.css. The name of the directory is configurable.


Please report any issues you may have and star the project!