---
title: Updating to v14
---

## Before you start

Make sure you're using the latest LTS version of Node. To check your Node version, use `node -v` in your terminal or command prompt, and if it's not high enough, update it! There are many resources online to help you with this step based on your host system.

### Various packages are now included in v14

If you previously had `@discordjs/builders`, `@discordjs/formatters`, `@discordjs/rest`, or `discord-api-types` manually installed, it's _highly_ recommended that you uninstall the packages to avoid package version conflicts.

```sh tab="npm"
npm uninstall @discordjs/builders @discordjs/formatters @discordjs/rest discord-api-types
```

```sh tab="yarn"
yarn remove @discordjs/builders @discordjs/formatters @discordjs/rest discord-api-types
```

```sh tab="pnpm"
pnpm remove @discordjs/builders @discordjs/formatters @discordjs/rest discord-api-types
```

## Breaking Changes

### API version

discord.js v14 makes the switch to Discord API v10!

### Common Breakages

### Enum Values

Any areas that used to accept a `string` or `number` type for an enum parameter will now only accept exclusively `number`s.

In addition, the old enums exported by discord.js v13 and lower are replaced with new enums from [discord-api-types](https://discord-api-types.dev/api/discord-api-types-v10).

#### New enum differences

Most of the difference between enums from discord.js and discord-api-types can be summarized as so:

1. Enums are singular, i.e., `ApplicationCommandOptionTypes` -> `ApplicationCommandOptionType`
2. Enums that are prefixed with `Message` no longer have the `Message` prefix, i.e., `MessageButtonStyles` -> `ButtonStyle`
3. Enum values are `PascalCase` rather than `SCREAMING_SNAKE_CASE`, i.e., `.CHAT_INPUT` -> `.ChatInput`

<Callout>
	You might be inclined to use raw `number`s (most commonly referred to as [magic numbers](<https://en.wikipedia.org/wiki/Magic_number_(programming)>)) instead of enum values. This is highly discouraged. Enums provide more readability and are more resistant to changes in the API. Magic numbers can obscure the meaning of your code in many ways, check out this [blog post](https://blog.webdevsimplified.com/2020-02/magic-numbers/) if you want more context on as to why they shouldn't be used.
</Callout>

#### Common enum breakages

Areas like `Client` initialization, JSON slash commands and JSON message components will likely need to be modified to accommodate these changes:

##### Common Client Initialization Changes

```js
const { Client, Intents } = require('discord.js'); // [!code --]
const { Client, GatewayIntentBits, Partials } = require('discord.js'); // [!code ++]

const client = new Client({ intents: [Intents.FLAGS.GUILDS], partials: ['CHANNEL'] }); // [!code --]
const client = new Client({ intents: [GatewayIntentBits.Guilds], partials: [Partials.Channel] }); // [!code ++]
```

##### Common Application Command Data changes

```js
const { ApplicationCommandType, ApplicationCommandOptionType } = require('discord.js'); // [!code ++]

const command = {
	name: 'ping',
	type: 'CHAT_INPUT', // [!code --]
	type: ApplicationCommandType.ChatInput, // [!code ++]
	options: [
		{
			name: 'option',
			description: 'A sample option',
			type: 'STRING', // [!code --]
			type: ApplicationCommandOptionType.String, // [!code ++]
		},
	],
};
```

##### Common Button Data changes

```js
const { ButtonStyle } = require('discord.js'); // [!code ++]

const button = {
	label: 'test',
	style: 'PRIMARY', // [!code --]
	style: ButtonStyle.Primary, // [!code ++]
	customId: '1234',
};
```

### Removal of method-based type guards

#### Channels

Some channel type guard methods that narrowed to one channel type have been removed. Instead compare the `type` property against a [ChannelType](https://discord-api-types.dev/api/discord-api-types-v10/enum/ChannelType) enum member to narrow channels.

```js
const { ChannelType } = require('discord.js'); // [!code ++]

channel.isText(); // [!code --]
channel.type === ChannelType.GuildText; // [!code ++]

channel.isVoice(); // [!code --]
channel.type === ChannelType.GuildVoice; // [!code ++]

channel.isDM(); // [!code --]
channel.type === ChannelType.DM; // [!code ++]
```

### Builders

Builders are no longer returned by the API like they were previously. For example you send the API an `EmbedBuilder` but you receive an `Embed` of the same data from the API. This may affect how your code handles received structures such as components. Refer to [message component changes section](#messagecomponent) for more details.

Added `disableValidators()` and `enableValidators()` as top-level exports which disable or enable validation (enabled by default).

### Consolidation of `create()` & `edit()` parameters

Various `create()` and `edit()` methods on managers and objects have had their parameters consolidated. The changes are below:

- `Guild#edit()` now takes `reason` in the `data` parameter
- `GuildChannel#edit()` now takes `reason` in the `data` parameter
- `GuildEmoji#edit()` now takes `reason` in the `data` parameter
- `Role#edit()` now takes `reason` in the `data` parameter
- `Sticker#edit()` now takes `reason` in the `data` parameter
- `ThreadChannel#edit()` now takes `reason` in the `data` parameter
- `GuildChannelManager#create()` now takes `name` in the `options` parameter
- `GuildChannelManager#createWebhook()` (and other text-based channels) now takes `channel` and `name` in the `options` parameter
- `GuildChannelManager#edit()` now takes `reason` as a part of `data`
- `GuildEmojiManager#edit()` now takes `reason` as a part of `data`
- `GuildManager#create()` now takes `name` as a part of `options`
- `GuildMemberManager#edit()` now takes `reason` as a part of `data`
- `GuildMember#edit()` now takes `reason` as a part of `data`
- `GuildStickerManager#edit()` now takes `reason` as a part of `data`
- `RoleManager#edit()` now takes `reason` as a part of `options`
- `Webhook#edit()` now takes `reason` as a part of `options`
- `GuildEmojiManager#create()` now takes `attachment` and `name` as a part of `options`
- `GuildStickerManager#create()` now takes `file`, `name`, and `tags` as a part of `options`

### Activity

The following properties have been removed as they are not documented by Discord:

- `Activity#id`
- `Activity#platform`
- `Activity#sessionId`
- `Activity#syncId`

### Application

`Application#fetchAssets()` has been removed as it is no longer supported by the API.

### BitField

- BitField constituents now have a `BitField` suffix to avoid naming conflicts with the enum names:

```js
new Permissions(); // [!code --]
new PermissionsBitField(); // [!code ++]

new MessageFlags(); // [!code --]
new MessageFlagsBitField(); // [!code ++]

new ThreadMemberFlags(); // [!code --]
new ThreadMemberFlagsBitField(); // [!code ++]

new UserFlags(); // [!code --]
new UserFlagsBitField(); // [!code ++]

new SystemChannelFlags(); // [!code --]
new SystemChannelFlagsBitField(); // [!code ++]

new ApplicationFlags(); // [!code --]
new ApplicationFlagsBitField(); // [!code ++]

new Intents(); // [!code --]
new IntentsBitField(); // [!code ++]

new ActivityFlags(); // [!code --]
new ActivityFlagsBitField(); // [!code ++]
```

- `#FLAGS` has been renamed to `#Flags`

### CDN

The methods that return CDN URLs have changed. Here is an example on a User:

```js
const url = user.displayAvatarURL({ dynamic: true, format: 'png', size: 1_024 }); // [!code --]
const url = user.displayAvatarURL({ extension: 'png', size: 1_024 }); // [!code ++]
```

Dynamic URLs use `ImageURLOptions` and static URLs use `BaseImageURLOptions`. Since dynamic URLs are returned by default, this option has been renamed to `forceStatic` which forces the return of a static URL. Additionally, `format` has been renamed to `extension`.

### CategoryChannel

`CategoryChannel#children` is no longer a `Collection` of channels the category contains. It is now a manager (`CategoryChannelChildManager`). This also means `CategoryChannel#createChannel()` has been moved to the `CategoryChannelChildManager`.

### Channel

The following type guards have been removed:

- `Channel#isText()`
- `Channel#isVoice()`
- `Channel#isDirectory()`
- `Channel#isDM()`
- `Channel#isGroupDM()`
- `Channel#isCategory()`
- `Channel#isNews()`

Refer to [this section](#channels) for more context.

The base channel class is now `BaseChannel`.

### Client

The `restWsBridgeTimeout` client option has been removed.

### CommandInteractionOptionResolver

`CommandInteractionOptionResolver#getMember()` no longer has a parameter for `required`. See [this pull request](https://github.com/discordjs/discord.js/pull/7188) for more information.

### Constants

- Many constant objects and key arrays are now top-level exports for example:

```js
const { Constants } = require('discord.js'); // [!code --]
const { Colors } = Constants; // [!code --]
const { Colors } = require('discord.js'); // [!code ++]
```

- The refactored constants structures have `PascalCase` member names as opposed to `SCREAMING_SNAKE_CASE` member names.

- Many of the exported constants structures have been replaced and renamed:

```js
Opcodes; // [!code --]
GatewayOpcodes; // [!code ++]

WSEvents; // [!code --]
GatewayDispatchEvents; // [!code ++]

WSCodes; // [!code --]
GatewayCloseCodes; // [!code ++]

InviteScopes; // [!code --]
OAuth2Scopes; // [!code ++]
```

### Events

The `message` and `interaction` events are now removed. Use `messageCreate` and `interactionCreate` instead.

`applicationCommandCreate`, `applicationCommandDelete` and `applicationCommandUpdate` have all been removed. See [this pull request](https://github.com/discordjs/discord.js/pull/6492) for more information.

The `threadMembersUpdate` event now emits the users who were added, the users who were removed, and the thread respectively.

### GuildBanManager

Developers should utilise `deleteMessageSeconds` instead of `days` and `deleteMessageDays`:

```js
<GuildBanManager>.create('123456789', {
 days: 3 // [!code --]
 deleteMessageDays: 3 // [!code --]
 deleteMessageSeconds: 3 * 24 * 60 * 60 // [!code ++]
});
```

`deleteMessageDays` (introduced with version 14) and `days` are both deprecated and will be removed in the future.

### Guild

`Guild#setRolePositions()` and `Guild#setChannelPositions()` have been removed. Use `RoleManager#setPositions()` and `GuildChannelManager#setPositions()` instead respectively.

`Guild#maximumPresences` no longer has a default value of 25,000.

`Guild#me` has been moved to `GuildMemberManager#me`. See [this pull request](https://github.com/discordjs/discord.js/pull/7669) for more information.

### GuildAuditLogs & GuildAuditLogsEntry

`GuildAuditLogs.build()` has been removed as it has been deemed defunct. There is no alternative.

The following properties & methods have been moved to the `GuildAuditLogsEntry` class:

- `GuildAuditLogs.Targets`
- `GuildAuditLogs.actionType()`
- `GuildAuditLogs.targetType()`

### GuildMember

`GuildMember#pending` is now nullable to account for partial guild members. See [this issue](https://github.com/discordjs/discord.js/issues/6546) for more information.

### IntegrationApplication

`IntegrationApplication#summary` has been removed as it is no longer supported by the API.

### Interaction

Whenever an interaction is replied to and one fetches the reply, it could possibly give an `APIMessage` if the guild was not cached. However, interaction replies now always return an `InteractionCallbackResponse` with `withResponse` set to `true`.

The base interaction class is now `BaseInteraction`.

### Invite

`Invite#inviter` is now a getter and resolves structures from the cache.

### MessageAttachment

`MessageAttachment` has now been renamed to `AttachmentBuilder`. // [!code --]

```js
new MessageAttachment(buffer, 'image.png'); // [!code --]
new AttachmentBuilder(buffer, { name: 'image.png' }); // [!code ++]
```

### MessageComponent

- MessageComponents have been renamed as well. They no longer have the `Message` prefix, and now have a `Builder` suffix:

```js
const button = new MessageButton(); // [!code --]
const button = new ButtonBuilder(); // [!code ++]

const selectMenu = new MessageSelectMenu(); // [!code --]
const selectMenu = new StringSelectMenuBuilder(); // [!code ++]

const actionRow = new MessageActionRow(); // [!code --]
const actionRow = new ActionRowBuilder(); // [!code ++]

const textInput = new TextInputComponent(); // [!code --]
const textInput = new TextInputBuilder(); // [!code ++]
```

- Components received from the API are no longer directly mutable. If you wish to mutate a component from the API, use `ComponentBuilder#from`. For example, if you want to make a button mutable:

```js
const editedButton = receivedButton // [!code --]
	.setDisabled(true); // [!code --]
const { ButtonBuilder } = require('discord.js'); // [!code ++]
const editedButton = ButtonBuilder.from(receivedButton) // [!code ++]
	.setDisabled(true); // [!code ++]
```

### MessageManager

`MessageManager#fetch()`'s second parameter has been removed. The `BaseFetchOptions` the second parameter once was is now merged into the first parameter.

```js
messageManager.fetch('1234567890', { cache: false, force: true }); // [!code --]
messageManager.fetch({ message: '1234567890', cache: false, force: true }); // [!code ++]
```

### MessageSelectMenu

- `MessageSelectMenu` has been renamed to `StringSelectMenuBuilder`
- `StringSelectMenuBuilder#addOption()` has been removed. Use `StringSelectMenuBuilder#addOptions()` instead.

### MessageEmbed

- `MessageEmbed` has now been renamed to `EmbedBuilder`.
- `EmbedBuilder#setAuthor()` now accepts a sole `EmbedAuthorOptions` object.
- `EmbedBuilder#setFooter()` now accepts a sole `EmbedFooterOptions` object.
- `EmbedBuilder#addField()` has been removed. Use `EmbedBuilder#addFields()` instead.

```js
new MessageEmbed().addField('Inline field title', 'Some value here', true); // [!code --]
new EmbedBuilder().addFields([ // [!code ++]
 { name: 'one', value: 'one', inline: true }, // [!code ++]
 { name: 'two', value: 'two', inline: true }, // [!code ++]
+]);
```

### Modal

- `Modal` has been renamed as well and now has a `Builder` suffix:

```js
const modal = new Modal(); // [!code --]
const modal = new ModalBuilder(); // [!code ++]
```

### PartialTypes

The `PartialTypes` string array has been removed. Use the `Partials` enum instead.

In addition to this, there is now a new partial: `Partials.ThreadMember`.

### Permissions

Thread permissions `USE_PUBLIC_THREADS` and `USE_PRIVATE_THREADS` have been removed as they are deprecated in the API. Use `CREATE_PUBLIC_THREADS` and `CREATE_PRIVATE_THREADS` respectively.

`ManageEmojisAndStickers` has been deprecated due to API changes. Its replacement is `ManageGuildExpressions`. See [this pull request](https://github.com/discord/discord-api-docs/pull/6017) for more information.

### PermissionOverwritesManager

Overwrites are now keyed by the `PascalCase` permission key rather than the `SCREAMING_SNAKE_CASE` permission key.

### REST Events

#### apiRequest

This REST event has been removed as discord.js now uses [Undici](https://github.com/nodejs/undici) as the underlying request handler. You must now use a [Diagnostics Channel](https://undici.nodejs.org/#/docs/api/DiagnosticsChannel). Here is a simple example:

```js
import diagnosticsChannel from 'node:diagnostics_channel';

diagnosticsChannel.channel('undici:request:create').subscribe((data) => {
	// If you use TypeScript, `data` may be casted as
	// `DiagnosticsChannel.RequestCreateMessage`
	// from Undici to receive type definitions.
	const { request } = data;
	console.log(request.method); // Log the method
	console.log(request.path); // Log the path
	console.log(request.headers); // Log the headers
	console.log(request); // Or just log everything!
});
```

You can find further examples at the [Undici Diagnostics Channel documentation](https://undici.nodejs.org/#/docs/api/DiagnosticsChannel).

#### apiResponse

This REST event has been renamed to `response` and moved to `Client#rest`:

```js
client.on('apiResponse', ...); // [!code --]
client.rest.on('response', ...); // [!code ++]
```

#### invalidRequestWarning

This REST event has been moved to `Client#rest`:

```js
client.on('invalidRequestWarning', ...); // [!code --]
client.rest.on('invalidRequestWarning', ...); // [!code ++]
```

#### rateLimit

This REST event has been renamed to `rateLimited` and moved to `Client#rest`:

```js
client.on('rateLimit', ...); // [!code --]
client.rest.on('rateLimited', ...); // [!code ++]
```

### RoleManager

`Role.comparePositions()` has been removed. Use `RoleManager#comparePositions()` instead.

### Sticker

`Sticker#tags` is now a nullable string (`string | null`). Previously, it was a nullable array of strings (`string[] | null`). See [this pull request](https://github.com/discordjs/discord.js/pull/8010) for more information.

### ThreadChannel

The `MAX` helper used in `ThreadAutoArchiveDuration` has been removed. Discord has since allowed any guild to use any auto archive time which makes this helper redundant.

### ThreadMemberManager

`ThreadMemberManager#fetch()`'s second parameter has been removed. The `BaseFetchOptions` the second parameter once was is now merged into the first parameter. In addition, the boolean helper to specify `cache` has been removed.

Usage is now as follows:

```js
// The second parameter is merged into the first parameter.
threadMemberManager.fetch('1234567890', { cache: false, force: true }); // [!code --]
threadMemberManager.fetch({ member: '1234567890', cache: false, force: true }); // [!code ++]

// The lone boolean has been removed. One must be explicit here.
threadMemberManager.fetch(false); // [!code --]
threadMemberManager.fetch({ cache: false }); // [!code ++]
```

### Util

`Util.removeMentions()` has been removed. To control mentions, you should use `allowedMentions` on `BaseMessageOptions` instead.

`Util.splitMessage()` has been removed. This utility method is something the developer themselves should do.

`Util.resolveAutoArchiveMaxLimit()` has been removed. Discord has since allowed any guild to use any auto archive time which makes this method redundant.

Other functions in `Util` have been moved to top-level exports so you can directly import them from `discord.js`.

```js
import { Util } from 'discord.js'; // [!code --]
Util.escapeMarkdown(message); // [!code --]
import { escapeMarkdown } from 'discord.js'; // [!code ++]
escapeMarkdown(message); // [!code ++]
```

### `.deleted` Field(s) have been removed

You can no longer use the `deleted` property to check if a structure was deleted. See [this issue](https://github.com/discordjs/discord.js/issues/7091) for more information.

### VoiceChannel

`VoiceChannel#editable` has been removed. You should use `GuildChannel#manageable` instead.

### VoiceRegion

`VoiceRegion#vip` has been removed as it is no longer part of the API.

### Webhook

`Webhook#fetchMessage()`'s second parameter no longer allows a boolean to be passed. The `cache` option in `WebhookFetchMessageOptions` should be used instead.

## Features

### ApplicationCommand

NSFW commands are supported.

### Attachment

Added support for voice message metadata fields.

### AutocompleteInteraction

`AutocompleteInteraction#commandGuildId` has been added which is the id of the guild the invoked application command is registered to.

### BaseChannel

Added support for `BaseChannel#flags`.

Store channels have been removed as they are no longer part of the API.

`BaseChannel#url` has been added which is a link to a channel, just like in the client.

Additionally, new typeguards have been added:

- `BaseChannel#isDMBased()`
- `BaseChannel#isTextBased()`
- `BaseChannel#isVoiceBased()`

### BaseInteraction

Added `BaseInteraction#isRepliable()` to check whether a given interaction can be replied to.

### ClientApplication

Added support for role connection metadata.

### Collection

- Added `Collection#merge()` and `Collection#combineEntries()`.
- New type: `ReadonlyCollection` which indicates an immutable `Collection`.

### Collector

A new `ignore` event has been added which is emitted whenever an element is not collected by the collector.

Component collector options now use the `ComponentType` enum values:

```js
const { ComponentType } = require('discord.js'); // [!code ++]

const collector = interaction.channel.createMessageComponentCollector({
	filter: collectorFilter,
	componentType: 'BUTTON', // [!code --]
	componentType: ComponentType.Button, // [!code ++]
	time: 20_000,
});
```

### CommandInteraction

`CommandInteraction#commandGuildId` has been added which is the id of the guild the invoked application command is registered to.

### CommandInteractionOptionResolver

`CommandInteractionOptionResolver#getChannel()` now has a third parameter which narrows the channel type.

### Events

Added support for `guildAuditLogEntryCreate` event.

### ForumChannel

Added support for forum channels.

Added support for `ForumChannel#defaultForumLayout`.

### Guild

Added `Guild#setMFALevel()` which sets the guild's MFA level.

Added `Guild#maxVideoChannelUsers` which indicates the maximum number of video channel users.

Added `Guild#maxStageVideoChannelUsers` which indicates the maximum number of video channel users for stage channels.

Added `Guild#disableInvites()` which disables the guild's invites.

Added support for the `after` parameter in `Guild#fetchAuditLogs()`.

### GuildChannelManager

`videoQualityMode` may be used whilst creating a channel to initially set the camera video quality mode.

### GuildEmojiManager

Added `GuildEmojiManager#delete()` and `GuildEmojiManager#edit()` for managing existing guild emojis.

### GuildForumThreadManager

Added `GuildForumThreadManager` as manager for threads in forum channels.

### GuildMember

Added support for `GuildMember#flags`.

### GuildMembersChunk

This object now supports the `GuildMembersChunk#notFound` property.

### GuildMemberManager

Added `GuildMemberManager#fetchMe()` to fetch the client user in the guild.

Added `GuildMemberManager#addRole()` and `GuildMemberManager#removeRole()`. These methods allow a single addition or removal of a role respectively to a guild member, even if uncached.

### GuildTextThreadManager

Added `GuildTextThreadManager` as manager for threads in text channels and announcement channels.

### Message

`Message#position` has been added as an approximate position in a thread.

Added support for role subscription data.

### MessageReaction

Added `MessageReaction#react()` to make the client user react with the reaction the class belongs to.

### Role

Added support for role subscriptions.

Added support for `Role#tags#guildConnections`.

### StageChannel

Stage channels now allow messages to be sent in them, much like voice channels.

### Sticker

Added support for GIF stickers.

### ThreadMemberManager

The new `withMember` options returns the associated guild member with the thread member.

When fetching multiple thread members alongside `withMember`, paginated results will be returned. The `after` and `limit` option are supported in this scenario.

### Webhook

Added `Webhook#applicationId`.

Added the `threadName` property in `Webhook#send()` options which allows a webhook to create a post in a forum channel.

### WebSocketManager

discord.js uses `@discordjs/ws` internally
