Skip to content

v6.0.0-rc.1 | New Components

Pre-release
Pre-release
Compare
Choose a tag to compare
@MinnDevelopment MinnDevelopment released this 20 Jul 14:51
· 37 commits to master since this release
8bc17a4

Overview

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
    The LayoutComponent interface (previously only implemented by ActionRow) 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 like ActionRow. Components such as TextDisplay and FileDisplay can now appear directly at the top level.

  • Renamed getIdgetCustomId
    The original getId method has been renamed to getCustomId to avoid confusion with Discord's new getUniqueId, 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 the toData 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.

pokemon-card

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 a Section component.

  • FileDisplay
    Displays a file attachment as a downloadable item. For visual file content (e.g., images), consider using MediaGallery 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 the content 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:

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 by editCommandById(type, id).
  • guild.kick(user, reason) is now replaced with guild.kick(user).reason(reason).
  • ApplicationEmoji.APPLICATION_EMOJI_CAP has been renamed to ApplicationEmoji.MAX_APPLICATION_EMOJIS.
  • The replyWithPremiumRequired method and related features have been replaced by Button.premium and standard reply behavior. For more details, see the Discord Changelog.
  • command.isGuildOnly() has been replaced with command.getContexts().equals(EnumSet.of(InteractionContextType.GUILD)).
  • command.setGuildOnly(boolean) is now replaced by command.setContexts(InteractionContextType.GUILD).
  • StageInstance#getPrivacyLevel and related features have been removed entirely.
  • GatewayIntent.GUILD_EMOJIS_AND_STICKERS has been replaced with GatewayIntent.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>