KLite developer documentation

Build KLite plugins without the client source.

Download a standalone IntelliJ and Gradle starter, compile only against the approved public SDK, and hot reload the resulting plugin JAR in the installed KLite client.

Standalone development kit

Set up IntelliJ in four steps

The starter produces the same external-plugin JAR format used by the Marketplace, so local testing and review use the same artifact structure.

1. Extract and open

Extract the starter ZIP, open its folder in IntelliJ, and import it as a Gradle project using JDK 11.

2. Rename the starter

Set the plugin ID, display name, version, author, Java package, entry class, and descriptor metadata.

3. Enable local plugins

In KLite Core settings, enable Plugin development → Enable development plugins.

4. Build and reload

Run installDevPlugin. KLite watches %USERPROFILE%\.runelite\klite-dev-plugins and reloads the newest JAR automatically.

SDK Public compile surface only RuneLite API types, plugin lifecycle contracts, configuration annotations, KLite client API DTOs, automation contracts, and walker contracts. libs/KLite-Plugin-SDK.jar
BUILD Production-shaped plugin JAR The build verifies that RuneLite, KLite, Guice, and injection runtime classes were not bundled into the submitted plugin. .\gradlew.bat installDevPlugin
RUNTIME Installed KLite is the test client The local development loader safely stops the previous plugin instance, closes its class loader, and starts the newest build. ~/.runelite/klite-dev-plugins

Choose the correct API

Match the API area to the job

Most plugins begin with the Client API. Add the automation runtime for multi-step work and the walker when the player must travel.

How to read KLite return typesCompletableFuture, Optional, snapshots, interaction results, lists, and coordinates
CompletableFuture<T>

The operation completes asynchronously. Chain work with thenApply, thenCompose, or thenAccept rather than blocking the client thread.

Optional<T>

The requested object may not currently exist. Handle the empty case instead of calling get() without checking.

*Snapshot

A read-only point-in-time view. Request a new snapshot before making a decision that depends on current state.

KLiteInteractionResult

The outcome of a requested action. Check it before assuming a click, withdrawal, selection, or interaction succeeded.

List<T>

A collection of current matches. An empty list is valid and simply means nothing matched at that moment.

WorldPoint

A world coordinate with X, Y, and plane. The correct plane matters for objects, ground items, and walking destinations.

Minimal example

Read inventory state without blocking

Check for coins and continue only after the asynchronous result is available.

KLiteClientApi api = /* injected API */;

api.inventoryContains(995)
    .thenAccept(hasCoins -> {
        if (hasCoins) {
            // Continue the workflow.
        }
    });

Grand Exchange automation

Search and place verified offers

The high-level Grand Exchange API searches the live tradeable-item catalogue and completes buy or sell offers only after KLite verifies the requested item, quantity, price, slot, and offer state.

searchGrandExchangeItems(query)

Returns matching tradeable items with their item ID, display name, and current guide price.

placeGrandExchangeBuyOffer(slot, itemName, quantity, priceEach)

Creates an exact-name buy offer in the requested zero-based Grand Exchange slot.

placeGrandExchangeSellOffer(inventorySlot, quantity, priceEach)

Offers the item in the requested zero-based inventory slot using the first empty Grand Exchange slot.

Transaction requirements

Open the Grand Exchange first

These calls fail closed when the Grand Exchange is not open, an exact item cannot be found, a slot is unavailable, or the final offer does not match. Chain the returned future and inspect the interaction result.

KLiteClientApi api = /* injected API */;

api.searchGrandExchangeItems("Coal")
    .thenCompose(matches -> {
        boolean exactMatch = matches.stream()
            .anyMatch(item -> item.getName().equalsIgnoreCase("Coal"));
        if (!exactMatch) {
            return CompletableFuture.failedFuture(
                new IllegalStateException("Coal is not tradeable"));
        }
        return api.placeGrandExchangeBuyOffer(0, "Coal", 1_000, 180);
    })
    .thenAccept(result -> {
        if (!result.isDispatched()) {
            // Report or recover from the rejected transaction.
        }
    });

api.placeGrandExchangeSellOffer(12, 250, 175)
    .thenAccept(result -> {
        // Inventory slot 12, quantity 250, 175 coins each.
    });

Searchable Java reference

Types and callable methods

The default view shows callable Client API types. Select another area or disable the callable-method filter to inspect snapshots, requests, results, and enums.