Library / SDK
kordlib/kord avatar
kordlib/kord

Kord is a coroutine based Discord API wrapper written entirely in Kotlin

Idiomatic Kotlin Wrapper for The Discord API

1,064 stars94 forksKotlinMIT

At a glance

What is it?
Kord is a modular, coroutine based implementation of the Discord API written entirely in Kotlin, split into separate artifacts for the gateway, the REST API, the caching abstraction and voice. It targets Kotlin/JVM and Kotlin/JS, has no Native support yet, and its version numbering is still pre-1.0, which tells you how the project sees its own stability.
Who is it for?
Kord suits a Kotlin team writing a Discord bot or integration that wants coroutines instead of blocking threads or a reactive library with its own learning curve, and that wants the low level gateway and REST calls available when the high level abstraction does not fit. It is the wrong tool for a project that needs Native targets, for multi process sharding, and for anything that needs a stable API surface today.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 30 days ago.
What is it written in?
Mainly Kotlin, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Written from the ground up rather than wrapped

Kord is described as a coroutine-based, modularized implementation of the Discord API, written 100% in Kotlin.

The reason it exists is stated in the project documentation and it is a specific complaint about the alternatives. Kord was created as an answer to the frustrations of writing Discord bots with other JVM libraries, which either use thread-blocking code or offer verbose and scope restrictive reactive systems. The bet is that an API written from the ground up in Kotlin with coroutines gives the best of both worlds, the conciseness of imperative code with the concurrency of reactive code.

There is a second motive in the same paragraph, and it is the one that shapes the module structure. The authors wanted to give the user full access to lower level APIs, because sometimes you have to do unconventional things, and they wanted to allow that in a safe and supported way. So Kord is not only a friendly layer over Discord, it is a way of reaching the raw gateway and REST calls when the friendly layer is in the way.

The status table shows how far that has gone. The Discord Gateway, the Discord REST API, the high level abstraction with caching, and Discord Voice are all marked done. Support for multiple processes is not, and is tracked as issue 7. The current position is stated precisely: Kord should provide a full mapping of the non-voice API on Kotlin/JVM and Kotlin/JS, and an experimental mapping of the Voice API on Kotlin/JVM.

The project is MIT licensed, published on Maven Central under the `dev.kord` group, supported by JetBrains through their open source support programme, and the last push was on 2026-09-23.

The module split is a layering decision

Six modules are published, and the table of them is the clearest description of the architecture in the repository.

| Module | Artifact | JVM | JS | Native | | --- | --- | --- | --- | --- | | common | kord-common | yes | yes | no | | rest | kord-rest | yes | yes | no | | gateway | kord-gateway | yes | yes | no | | core | kord-core | yes | yes | no | | voice | kord-voice | yes | no | no | | core-voice | kord-core-voice | yes | no | no |

The naming makes the shape clear. `common` holds the types shared by everything else. `rest` and `gateway` are the two protocol layers, the HTTP API and the websocket gateway. `core` is the layer that sits on top of them and adds the high level abstraction with caching. The two voice modules sit alongside `core` rather than under it, with `kord-voice` for the protocol and `kord-core-voice` for the high level voice API.

So there are two axes of choice. You can pick the raw protocol modules and write your own state handling, or you can take `core` and get caching for free. And separately, you can add voice or leave it out. A project that only needs a bot that reacts to messages does not need the voice artifacts, and a project that needs to be exactly in control of cache invalidation can take `rest` and `gateway` alone.

Two footnotes in the table matter at install time. The artifacts only support Gradle version 5.3 or higher, and for older Gradle versions and for Maven you should append `-jvm` to the artifact name. Native support is tracked in issue 69, and Voice on JS is also tracked there.

The repository layout matches the module structure, with a directory for each of `common/`, `rest/`, `gateway/`, `core/`, `core-voice/` and `voice/`, plus `bom/` for a bill of materials, `ksp-annotations/` and `ksp-processors/` for annotation processing, `test-kit/`, `samples/`, `buildSrc/` and an `inspections/` directory for custom static analysis, with `qodana.yaml` for the JetBrains code quality tool.

Adding it to a Gradle or Maven build

The installation section tells you to replace `{version}` with the latest version number on Maven Central, and the Gradle snippet is short.

kotlin
repositories {
    mavenCentral()
    maven("https://snapshots.kord.dev")
}

dependencies {
    implementation("dev.kord:kord-core:{version}")
}

The Groovy equivalent is the same thing with different syntax, and the snapshot repository is declared as a `maven { url "https://snapshots.kord.dev/" }` block.

For Maven the repository has to be declared with releases disabled and snapshots enabled, because the snapshot repository only serves snapshots.

xml
<repository>
    <id>snapshots-repo</id>
    <url>https://snapshots.kord.dev</url>
    <releases>
        <enabled>false</enabled>
    </releases>
    <snapshots>
        <enabled>true</enabled>
    </snapshots>
</repository>

And the dependency for Maven carries the `-jvm` suffix, as the footnote requires.

xml
<dependency>
    <groupId>dev.kord</groupId>
    <artifactId>kord-core-jvm</artifactId>
    <version>{version}</version>
</dependency>

Two things a reader should notice. The `-jvm` suffix on the Maven coordinate is not a variant in the usual Gradle sense, it is a separate published artifact for Maven and older Gradle users, which means the coordinates differ by build tool. And the Gradle snippet points at the snapshot repository unconditionally, so a project that only wants released versions still has the repository configured, which is worth removing if you care about where your dependencies can come from.

Snapshot versions encode the branch they came from

The versioning convention for snapshot builds is unusual enough to be worth reading, because it lets you point a build at a branch and get that branch's code.

For snapshots you replace `{version}` with `{branch}-SNAPSHOT`. The documentation gives the example `feature-amazing-thing-SNAPSHOT` for the branch `feature/amazing-thing`, so the branch name is transformed into a Maven version string with the slashes replaced.

For snapshots of the main branch, the rule is different. You replace `{version}` with `{nextPlannedVersion}-SNAPSHOT`, and the value of `nextPlannedVersion` lives in `gradle.properties` in the repository. The idea is that the main branch always publishes a snapshot labelled with the version it is going to become, so a build pinned to that snapshot is following the next release rather than some arbitrary commit.

That is a genuinely useful convention for a library that publishes continuously, and it is also the kind of thing that only makes sense if you read the documentation. A user who writes `dev.kord:kord-core:0.19.0-SNAPSHOT` from habit will be waiting for a version that does not exist.

The released versions themselves are still in the 0.x range. The most recent are 0.18.1, published on 2026-03-14 and titled for its Components V2 fixes, 0.18.0 on 2026-03-03 for Components V2 and more, and 0.17.0 on 2025-09-23, which covered dependency updates and a kotlinx.datetime migration.

That migration is worth a second look, because it is the kind of change that breaks code. Moving a library onto kotlinx.datetime means the date and time types on the public API change, so a Kord upgrade can require source changes in your bot even when you did not touch anything Discord related.

The high level layer caches, and the protocol layer does not

The most interesting question about Kord is what the `core` module actually gives you over `rest` and `gateway`, and the answer is caching plus a domain model.

The status table names it as high level abstraction plus caching. So `core` is the layer where a Discord entity, a guild, a channel, a message, is a first class object with behaviour, rather than a data class you build yourself from a REST response every time you need one. The caching is what stops your bot from making a REST call for every message it reacts to.

That layer is also where the ergonomic promise lives, the conciseness of imperative code. A bot written against `core` reads as a sequence of ordinary calls, and the coroutines underneath it suspend instead of blocking, which is the point of the whole design. A bot written against `gateway` directly is closer to the protocol, which is what you want when you need a behaviour the abstraction does not model, and which is why the library deliberately exposes that layer rather than hiding it.

The choice therefore mirrors a common trade in library design. Take the abstraction and get less code and better performance for the common case. Take the protocol and get exact control, at the cost of writing the state handling yourself.

The voice side is where the project is least complete. The voice API is described as an experimental mapping on Kotlin/JVM only, with the Kotlin/JS support tracked in issue 69 along with Native. So the module matrix is not uniform, and a project that assumes every module compiles on every target will hit the table in the README and discover it does not.

Where Kord is the wrong tool

The limits here are mostly about scope and maturity rather than design, and they are visible in the documentation rather than hidden.

The first is version 0.x. Kord is at 0.18.x, which by the usual convention of a 0.x line means the API can still change between minor versions. The kotlinx.datetime migration in 0.17.0 is a concrete instance of that, and a project that upgrades on every release will feel it. A team that needs a stable surface across years has to pin versions and absorb those changes on their own schedule.

The second is the two unimplemented items in the status table. Support for multiple processes is not done and is tracked as issue 7, which means sharding a bot across several processes is not something the library supports today. And Native support is not there either, with the whole Native column of the module table empty. A project targeting Kotlin/Native, or one that needs a sharded bot, has to look elsewhere or wait.

The third is Discord itself. A library that wraps an API is coupled to that API's release cycle, and the Components V2 work in 0.18.0 is evidence of exactly that coupling. The library's job ends at the API boundary, so anything Discord does not expose is out of reach, and the two lower level modules exist precisely because the authors expected people to need to go past the abstraction.

The alternative approach is worth naming honestly, and it is not another library. A bot that is small enough to fit in one file can be written against the raw websocket and HTTP API directly, with a JSON parser and a websocket client, and get complete control with no abstraction to fight. The trade is that you write the reconnect logic, the rate limit handling, the event dispatch and the state management yourself. Kord is the version of that work already done, and the question is whether you want it, and the answer depends on how much of your bot is Discord plumbing rather than your own logic.

Editorial conclusion

Kord suits a Kotlin team writing a Discord bot or integration that wants coroutines instead of blocking threads or a reactive library with its own learning curve, and that wants the low level gateway and REST calls available when the high level abstraction does not fit. It is the wrong tool for a project that needs Native targets, for multi process sharding, and for anything that needs a stable API surface today. Check first which artifacts you actually need, since the voice modules are JVM only, and read the module support table before assuming the same code compiles on JVM and JS.

Frequently asked questions

What is Kord and why was it written?

Kord is a coroutine-based, modularized implementation of the Discord API written entirely in Kotlin. It was created as an answer to the frustrations of other JVM libraries for Discord bots, which either use thread-blocking code or offer verbose, scope restrictive reactive systems, and it also aims to give users supported access to the lower level gateway and REST APIs.

Which platforms does Kord support?

The common, rest, gateway and core modules support Kotlin/JVM and Kotlin/JS, while the voice and core-voice modules are JVM only, and no module has Native support yet. The module table in the README marks Native support as an open item in issue 69, and the Voice on JS request is tracked there too.

How do I add Kord to a Maven build?

Declare the snapshot repository with releases disabled and snapshots enabled, and use the artifact with the `-jvm` suffix, for example `dev.kord:kord-core-jvm`, because the plain artifact names only support Gradle 5.3 or higher. The Gradle coordinates have no suffix and come from `dev.kord:kord-core`.

How do Kord snapshot versions work?

A snapshot for a feature branch is named `{branch}-SNAPSHOT`, for example `feature-amazing-thing-SNAPSHOT` for the branch `feature/amazing-thing`. A snapshot of the main branch uses `{nextPlannedVersion}-SNAPSHOT`, where the planned version is read from `gradle.properties` in the repository.

Official sources

  1. Issues
  2. kordlib/kord on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kordlib-kord.svg)](https://hysenlabs.com/projects/kordlib-kord)

Was this useful?