> ## Documentation Index
> Fetch the complete documentation index at: https://build.thamani.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Sharing Resources in Multimodule

> An effective way to share resources throughout your app

<Card title="Maverick Mambo" icon="https://mintcdn.com/halo-c614fc4d/n1cCDjQImiwl-ZA3/images/authors/mambo.png?fit=max&auto=format&n=n1cCDjQImiwl-ZA3&q=85&s=08273d91c4d009986a2472edd13b0aa4" horizontal width="1000" height="1000" data-path="images/authors/mambo.png">
  Pathfinder @ Thamani
</Card>

<img className="block" src="https://mintcdn.com/halo-c614fc4d/CHVq42W9x6F6NoUm/images/engineering/2026/resources.svg?fit=max&auto=format&n=CHVq42W9x6F6NoUm&q=85&s=46d11d8a5fdf3adeca02f732a6018bcb" alt="Hero Light" width="2064" height="1104" data-path="images/engineering/2026/resources.svg" />

> Resources should be central and feature agnostic

Every Android application has resources — images, videos, animation files, you name it.
Once you start modularising an application, sharing those resources gets tricky.

# The Problem

Every new `feature` module comes with its own set of resources.
Sometimes a resource is needed in more than one module, so we duplicate it. Do this enough times and you end up with something like:

<Columns cols={2}>
  <Card>
    <span className="text-blue-500 font-bold">Example</span>

    <Tree>
      <Tree.Folder name="project" defaultOpen>
        <Tree.Folder name="features" defaultOpen>
          <Tree.Folder name="featureA" defaultOpen>
            <Tree.Folder name="res" defaultOpen>
              <Tree.Folder name="drawable" defaultOpen>
                <Tree.File name="my_image.png" />
              </Tree.Folder>
            </Tree.Folder>
          </Tree.Folder>

          <Tree.Folder name="featureB" defaultOpen>
            <Tree.Folder name="res" defaultOpen>
              <Tree.Folder name="drawable" defaultOpen>
                <Tree.File name="my_image.png" />
              </Tree.Folder>
            </Tree.Folder>
          </Tree.Folder>
        </Tree.Folder>
      </Tree.Folder>
    </Tree>
  </Card>

  <Card>
    <span className="text-red-500 font-bold">Problems</span>

    * duplicated resources
    * increased application size
    * harder to maintain (*an update to
      the image requires you to update it in all modules its used*)
  </Card>
</Columns>

<Danger>Although tempting, **AVOID** feature interdependency, featureA shouldn't know about featureB</Danger>

# The Shared `resources` Module

Create a single module, put all your shared resources inside it, and have every feature module depend on it.

> This solves all the problems above.

<Steps>
  <Step title="create a new module">
    We will introduce a new module called `resources`

    <Card>
      <Tree>
        <Tree.Folder name="app" defaultOpen>
          <Tree.Folder name="features" defaultOpen>
            <Tree.Folder name="featureA">
              <Tree.Folder name="res">
                <Tree.Folder name="drawable">
                  <Tree.File name="my_image.png" />
                </Tree.Folder>
              </Tree.Folder>
            </Tree.Folder>

            <Tree.Folder name="featureB">
              <Tree.Folder name="res">
                <Tree.Folder name="drawable">
                  <Tree.File name="my_image.png" />
                </Tree.Folder>
              </Tree.Folder>
            </Tree.Folder>
          </Tree.Folder>

          <Tree.Folder name="resources (your new module)" defaultOpen />
        </Tree.Folder>
      </Tree>
    </Card>

    <Note>Keep this module lean. It shouldn't need many dependencies</Note>
  </Step>

  <Step title="add all your resources into the new module">
    <Card>
      <Tree>
        <Tree.Folder name="app" defaultOpen>
          <Tree.Folder name="resources" defaultOpen>
            <Tree.Folder name="res" defaultOpen>
              <Tree.Folder name="drawable" defaultOpen>
                <Tree.File name="my_image.png" />
              </Tree.Folder>
            </Tree.Folder>
          </Tree.Folder>
        </Tree.Folder>
      </Tree>
    </Card>
  </Step>

  <Step title="add the resources module into each feature ">
    Add the resources module as a dependency in each feature

    ```kotlin build.gradle.kts icon="kotlin" theme={null}
    implementation(project("resources"))
    ```

    <Note>If you're going to repeat this for each module, you could create a convention plugin for it</Note>
  </Step>

  <Step title="using the resources">
    Import the `R` class from your new module and use the resources as usual

    ```kotlin theme={null}

    import {your.new.module.path}.R

    ...

    @Composable
    fun Composable(){
        val stringId = R.string.title            // for strings
        val drawableId = R.drawable.my_image    // for images
        val rawFileId = R.raw.raw_file          // for raw files
        ... and so forth
    }
    ```
  </Step>
</Steps>

You now have one module for all your resources, shared throughout the app.

> But there's always more 😉

# The Thamani Way

At Thamani, we think about developer experience the same way we think about user experience — if something feels
off, it's worth fixing. The shared resources module worked, but using it didn't feel right.

The problem was the `R` class. You'd import it, autocomplete would show you two options, and you'd have to pause
and think: is this `R` from my feature module or from the shared resources module? That small friction added up
across the codebase.

So we wrapped the shared `R` class in a helper that makes the source obvious at a glance:

```kotlin theme={null}

internal typealias ThamaniResourcesRaw = R.raw
internal typealias ThamaniResourcesString = R.string
internal typealias ThamaniResourcesDrawable = R.drawable
...

object ThamaniResource {
    typealias Raw = ThamaniResourcesRaw
    typealias String = ThamaniResourcesString
    typealias Drawable = ThamaniResourcesDrawable
    ...
}

```

Now instead of guessing which `R` you're looking at, you write this:

```kotlin theme={null}

@Composable
fun Composable(){
    val stringId = ThamaniResource.String.title            // for strings
    val drawableId = ThamaniResource.Drawable.my_image    // for images
    val rawFileId = ThamaniResource.Raw.raw_file           // for raw files
    ... and so forth
}
```

When you read `ThamaniResource.Drawable.my_image`, you know exactly where it lives. No second-guessing.

Small details like this are what turn a working codebase into one that's actually pleasant to work in — and at
Thamani, that matters to us just as much as the experience our users get.
