v6.0.0-rc.1 | New Components
Pre-releaseOverview
Warning
This is the first release candidate for JDA 6.0.0. The major version bump reflects several breaking changes to the message and modal component APIs. Additional breaking changes may still be introduced before the final stable release of 6.0.0.
This version introduces support for Components Version 2, a significant update to Discord's component system. To accommodate this new API, we’ve made a number of key changes to our component implementation:
-
All components are now immutable
Previously,ActionRow
allowed modification of its contained components. To simplify and modernize the API, this mutability has been removed. -
New top-level component interfaces
TheLayoutComponent
interface (previously only implemented byActionRow
) has been replaced by two new interfaces:
-MessageTopLevelComponent
-ModalTopLevelComponent
This change reflects the increased flexibility introduced in Components V2, where top-level components are no longer restricted to layout containers likeActionRow
. Components such asTextDisplay
andFileDisplay
can now appear directly at the top level. -
Renamed
getId
→getCustomId
The originalgetId
method has been renamed togetCustomId
to avoid confusion with Discord's newgetUniqueId
, which is a numeric, auto-generated identifier. -
Temporary removal of
toData
for components
Some components now require attachments to function properly, complicating serialization. We’ve removed thetoData
method for now and are working on a new, more capable serialization API that will be introduced in a later update.
Big thanks to @freya022 and @DV8FromTheWorld for contributing on this giant feature!
Using Components V2
To use the new components introduced in this release, you must enable the Components V2 feature flag on your message request. This can be done using the useComponentsV2
method on MessageRequest
.
Tip
Enabling this flag comes with certain limitations, so we strongly recommend reviewing the documentation for important details before integrating it into your project.
To get started, check out the new ComponentsV2Example to explore the possibilities of this updated API. You can also see it in action in a demo project by @DV8FromTheWorld: discord-pokedex.

New Components
JDA 6 introduces several new component types as part of the Components V2 system:
-
Container
Displays components inside a visually distinct box — similar to how embeds are styled. -
Thumbnail
Shows a small image next to text. Commonly used as an accessory within aSection
component. -
FileDisplay
Displays a file attachment as a downloadable item. For visual file content (e.g., images), consider usingMediaGallery
instead. -
MediaGallery
Shows multiple images in a gallery layout — similar to a list of image attachments in Discord. -
Section
Displays a block of text content with optional accessories like thumbnails or buttons. -
Separator
Adds vertical spacing between components, helping visually organize content. -
TextDisplay
A simple text component used to display content without relying on thecontent
field of a message.
Note
Components that use files, such as FileDisplay
or MediaGallery
, will automatically attach files as message attachments in your requests.
New Utilities For Components
Several new utilities have been added to simplify working with complex component structures — including traversal, replacement, and deserialization:
-
MessageComponentTree
&ModalComponentTree
A single object that provides the functionality to iterate and replace components easily. -
ComponentReplacer
An interface for removing or replacing components within a tree or collection.
For example, remove a component by unique ID usingbyUniqueId(1, null)
. -
ComponentIterator
&ComponentPathIterator
Tools for recursively iterating through nested components, including child elements like buttons within anActionRow
. -
Components
A utility class used for parsing serialized JSON into JDA's component model.
Migrating To 6.0.0
To help ease the upgrade to JDA 6.0.0, we've provided an OpenRewrite recipe that can automatically refactor parts of your codebase. This will update imports and replace a few method calls with their new equivalents in JDA 6.0.0.
However, not all breaking changes can be handled automatically — for example, code that relied on the mutability of ActionRow
will require manual adjustments.
The OpenRewrite Recipe
Before applying the recipe, make sure you’re using version control (e.g., Git) or back up your project manually. You’ll also need to be using Gradle or Maven to apply the migration.
Gradle
We are using the OpenRewrite Gradle Plugin. Before changing your JDA version in gradle, you can add the rewrite plugin and use the recipe to migrate your code:
plugins {
id("org.openrewrite.rewrite") version "7.11.0"
}
repositories {
mavenCentral()
}
dependencies {
// Your current JDA version before upgrading to 6.0.0
implementation("net.dv8tion:JDA:5.+")
// The current 6.0.0 release version
rewrite("net.dv8tion:JDA:6.0.0-rc.1")
rewrite("org.openrewrite.recipe:rewrite-java-dependencies:1.37.0")
}
rewrite {
activeRecipe("net.dv8tion.MigrateComponentsV2")
}
Once you configured this plugin, you can use the rewriteDryRun
task to generate a git patch in build/reports/rewrite/rewrite.patch
to see what the plugin will do with your source code. To apply the changes, either use this patch or use rewriteRun
.
After migrating your code, you can then update your JDA version (if the rewrite hasn't done it already) and remove the plugin again.
Maven
We are using the OpenRewrite Maven Plugin. Before changing your JDA version in your pom, you can add the rewrite plugin and use the recipe to migrate your code:
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>6.13.0</version>
<configuration>
<activeRecipes>
<recipe>net.dv8tion.MigrateComponentsV2</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-java-dependencies</artifactId>
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>6.0.0-rc.1</version>
</dependency>
</dependencies>
</plugin>
Once you configured this plugin, you can use the rewrite:dryRun
task to generate a git patch in target/site/rewrite/rewrite.patch
to see what the plugin will do with your source code. To apply the changes, either use this patch or use rewrite:run
.
After migrating your code, you can then update your JDA version (if the rewrite hasn't done it already) and remove the plugin again.
The ComponentReplacer
If you previously used LayoutComponent.updateComponents
or changed an action row with the mutable getComponents()
, you will have to migrate your code to the new ComponentReplacer instead.
Before:
List<LayoutComponent> components = message.getComponents();
LayoutComponent.updateComponent(
components,
"my-component-id",
Button.primary("button-id", "Click me").asDisabled()
);
After:
MessageComponentTree components = message.getComponentTree();
// By unique id
ComponentReplacer replacer = ComponentReplacer.byUniqueId(1,
// Pass in a component instance or an updater function
Button.primary("button-id", "Click me")
.withUniqueId(1)
.asDisabled()
);
// Functional style
ComponentReplacer replacer = ComponentReplacer.of(
// The component type to replace
Button.class,
// Filter by predicate
button -> "my-component-id".equals(button.getCustomId()),
// Update to new component with asDisabled
button -> button.asDisabled()
);
// Apply the replacer to a tree and get a new tree instance with the applied changes
MessageComponentTree updated = components.replace(replacer);
Removed Deprecated Features
editCommandById(id)
has been replaced byeditCommandById(type, id)
.guild.kick(user, reason)
is now replaced withguild.kick(user).reason(reason)
.ApplicationEmoji.APPLICATION_EMOJI_CAP
has been renamed toApplicationEmoji.MAX_APPLICATION_EMOJIS
.- The
replyWithPremiumRequired
method and related features have been replaced byButton.premium
and standard reply behavior. For more details, see the Discord Changelog. command.isGuildOnly()
has been replaced withcommand.getContexts().equals(EnumSet.of(InteractionContextType.GUILD))
.command.setGuildOnly(boolean)
is now replaced bycommand.setContexts(InteractionContextType.GUILD)
.StageInstance#getPrivacyLevel
and related features have been removed entirely.GatewayIntent.GUILD_EMOJIS_AND_STICKERS
has been replaced withGatewayIntent.GUILD_EXPRESSIONS
.
Full Changelog: v5.6.1...v6.0.0-rc.1
Installation
Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("net.dv8tion:JDA:6.0.0-rc.1")
}
Maven
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>6.0.0-rc.1</version>
</dependency>