Kotlin Multiplatform · Headless rendering

Basemap tiles.
No map view.

Rentile turns a supported map style and a list of XYZ coordinates into PNG bytes. It runs in shared Kotlin code, so previews, exports, background jobs, and native services can render a basemap without opening a screen or managing a graphics loop.

ONE RENDERING JOB
  1. 01 Read and check the style
  2. 02 Gather the required resources
  3. 03 Draw tiles on the CPU
  4. 04 Return PNG bytes
Android arm64 Android x86_64 iOS arm64 iOS Simulator arm64 Linux x64 Linux arm64

A focused rendering dependency

Use the map. Skip the map UI.

Full map SDKs are built around an interactive view. Rentile is for the other jobs: when all you need is a predictable image for known coordinates.

01

Made for background work

No Android View, UIKit view, display server, or SDK-owned render loop is required.

02

One API across platforms

Prepare styles and request tiles from common Kotlin on Android, iOS, and Linux.

03

PNG is the boundary

Every successful tile comes back as encoded PNG bytes, ready to store or pass on.

04

Failures are explicit

Unsupported styles and resource problems fail with typed, redacted diagnostics.

Add it once

A common-code dependency

Declare Rentile in commonMain. Gradle selects the right native artifact for each target in your project.

build.gradle.kts commonMain
kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation(
                "com.rohittp.rentile:kmp:<version>"
            )
        }
    }
}

The everyday flow

Prepare. Inspect. Render.

Resource access finishes before drawing begins. That gives your app a chance to check its own output cache before spending time rendering a tile.

1

Prepare the style

Rentile checks the style against its versioned compatibility profile.

2

Prepare a batch

Required resources are fetched or read from the raw-resource cache.

3

Render what you need

Use the content keys to skip cached outputs, then render the remaining tiles.

Common Kotlin

The API follows the work.

Your app supplies transport and raw storage. Rentile handles preparation, bounded work, CPU drawing, and PNG encoding behind one closeable renderer.

AppResourceTransport and AppRawResourceStore below are adapters implemented by your app.

Configure the host adapters
Render one tilesuspend
val rasterizer = Rentile.create(
    RentileConfiguration(
        transport = AppResourceTransport(),
        rawResourceStore = AppRawResourceStore(),
    )
)

try {
    val style = rasterizer.prepare(
        StyleInput.Remote("https://example.com/style.json")
    )
    rasterizer.prepareBatch(
        style,
        listOf(TileId(z = 12, x = 2203, y = 1345)),
    ).use { batch ->
        val result = rasterizer.render(batch)
        savePng(result.tiles.single().pngBytes)
    }
} finally {
    rasterizer.close()
    rasterizer.awaitClosed()
}

A clear hand-off

You stay in control of app policy.

Rentile owns the rendering machinery. Your app keeps the decisions that depend on product context, network policy, and user experience.

Rentile handles

  • Style validation and diagnostics
  • Resource planning and raw-resource caching
  • Bounded, cancellable rendering work
  • CPU drawing and PNG encoding
  • Stable output content keys

Your app decides

  • Which tiles to request and in what order
  • Where rendered PNGs are stored
  • When to retry, fall back, or stop
  • How credentials and HTTP are provided
  • How tiles appear in the final experience

Is Rentile a fit?

Choose it for rendered assets, not interaction.

A good fit

  • Exporting map frames or previews
  • Generating tiles in background jobs
  • Rendering in a native Linux process
  • Sharing one rendering boundary across Android and iOS

Use a full map SDK when you need

  • Pan, zoom, gestures, or an interactive camera
  • Labels, glyph shaping, or live feature state
  • Globe, terrain, fog, sky, or animated layers
  • An on-screen map managed by the renderer

Integration guide

Ready to look at the API?

Read the KMP guide