Skip to main content

@arcscord/components

Arcscord includes typed helpers for Discord Components V2 messages and re-exports them from its main arcscord entry point. The same API is published separately as @arcscord/components for Discord.js projects that do not need the framework.

Using Components V2 with Arcscord

Install Arcscord normally; @arcscord/components is already included as a dependency and does not need to be installed separately:

pnpm add arcscord discord.js
import {
accessory,
actionRow,
button,
container,
section,
separator,
thumbnail,
v2Message,
} from "arcscord";

await ctx.reply(v2Message(
container(
{ accentColor: 0x5865F2 },
"## Support",
section(
"Open a support request.",
accessory(thumbnail({ media: { url: "https://example.com/support.png" } })),
),
separator({ divider: true, spacing: "large" }),
actionRow(button({
customId: "support",
label: "Open",
style: "primary",
})),
),
));

Standalone usage with Discord.js

Install the dedicated package when using the helpers without Arcscord:

pnpm add @arcscord/components discord.js
import { ButtonBuilder, ButtonStyle } from "discord.js";
import {
accessory,
actionRow,
container,
section,
separator,
thumbnail,
v2Message,
} from "@arcscord/components";

await interaction.reply(v2Message(
container(
{ accentColor: 0x5865F2 },
"## Support",
section(
"Open a support request.",
accessory(thumbnail({ media: { url: "https://example.com/support.png" } })),
),
separator({ divider: true, spacing: "large" }),
actionRow(
new ButtonBuilder()
.setCustomId("support")
.setLabel("Open")
.setStyle(ButtonStyle.Primary),
),
),
));

No Arcscord client, context, manager, or error package is required in this standalone example. v2Message enables MessageFlags.IsComponentsV2 and returns a payload accepted directly by Discord.js reply and edit methods.

Runtime validation

All helpers serialize, normalize, and validate their output recursively before returning it. This covers component fields, nesting, action-row and gallery cardinalities, media URL protocols, the 40-component message limit, and unique component/custom IDs.

Component discriminator failures use neutral rules: unexpected-component-type for a value outside the accepted set and component-placement for a known Discord component at an invalid nesting location.

The package also exports validators including validateButton, validateSelectMenu, validateSection, validateContainer, and validateV2Message. They accept the same flexible inputs as the helpers and return newly constructed canonical Discord.js camelCase data. Standalone validators throw MessageComponentValidationError with structured rule, path, componentType, and details properties.

The arcscord entry point directly re-exports the same helpers and validators, including their documentation and direct MessageComponentValidationError behavior. When the error crosses an Arcscord command, component, event, or middleware execution boundary, it is converted into an ArcscordError with code MESSAGE_COMPONENT_VALIDATION_FAILED. The public normalizeArcscordError(error) helper performs the same conversion explicitly; the standalone package remains independent from Arcscord's error packages.

Input interoperability

Every valid nesting point accepts Discord.js component data, official Discord.js builders, and raw API*Component objects from discord-api-types. Strings are shorthand for text displays. The package recursively converts builders and snake_case API objects into the same camelCase Discord.js component data returned by the simple helpers.

The container() helper constructs a new container from options and children. Complete container builders/data can be passed directly to v2Message() or normalized explicitly with validateContainer().

actionRow follows Discord's message-row constraints: pass one to five buttons, or exactly one string, user, role, mentionable, or channel select menu. Each component may be Discord.js data, an official builder, or a raw API object.

For the full option tables, nesting rules, and examples, see the Components V2 guide.

Compatible API surface

The arcscord package exposes the same function objects, helpers, validators, compatibility types, inputs, outputs, and direct validation errors. Error adaptation happens at Arcscord's execution boundary rather than by wrapping every export.