Show HN: Solaire – A lightweight framework for creating Discord bots in Node

Show HN: Solaire – A lightweight framework for creating Discord bots in Node

npm version

A lightweight framework with a simple interface for creating Discord bots in Node


Solaire interacts heavily with Discord.js, and many of the objects exposed from the Solaire API will be directly from Discord.js.

Solaire requires that you provide a Discord.js client version >=13.0.0

đź“Ł Simplicity & Limitations đź“Ł

Solaire is very much targetted at developers working on smaller or simpler Discord bots that don’t require some of the more advanced features of existing popular Discord bot frameworks, and just want something that will get their bot up and running quickly. More advanced features may be added in the future, but the guiding principle of the framework will always be simplicity in its API.

If you don’t find Solaire’s feature-set to be advanced enough for your use case, there are other great Discord/Node frameworks to take a look at

Slash Commands

Solaire does not utilize the new Discord slash commands feature, instead utilizing the old-fashioned method of listening to new message events.

Example Bot

Install ·
Example Config ·
Defining Commands ·
Command Configuration ·


npm install solaire-discord


Property Required Type Desc
discordClient Yes Discord.js::Client A Discord.js Client object. This client must have the GUILD_MESSAGES intent enabled for Solaire to work properly.
token Yes string Your bot’s Discord token (see
commandPrelude No string The string that must precede a command’s name in a Discord message for the command to be invoked. Common values are !, ?, ;;, but any string would technically work.
commandCooldown No number The amount of time in milliseconds that a command is un-invokable after being used. This cooldown is per-command.
commands Yes Record See Defining commands and Command configuration

Defining commands

In Solaire, bot commands are defined using a definition string that resembles how you would actually use the command in Discord. For example, a command that is used like !ban @someAnnoyingUser being mean, would be defined using the string ban [...reason].

This string, along with associated configuration for the command, is passed in via your Solaire config’s commands property.

Command Name & Aliases

A command’s name is defined as the first word in your command definition string

You can define aliases for a command by appending the command’s name with |, e.g.

Command Arguments

After your command’s name, you can define any number of arguments that can be passed into your command.

Required Arguments

Required arguments are denoted in the definition string by being wrapped in <>, e.g.

Optional Arguments

Optional arguments are denoted by being wrapped in [], e.g.

When an optional argument is defined, the remaining arguments in the command must also be optional.

Rest Arguments

A “rest” argument is an arg whose value is defined as all remaining words in a message. They are denoted by the arg’s name being preceded with .... e.g.

[...reason] > !ban @someAnnoyingUser being mean ^----- "reason" arg has value "being mean"

A rest argument must be the last argument of a command. When accessing the argument in your execute, guard, etc. functions, the value of the argument will be an array.

Argument Types

An argument’s value can be constrained by defining an explicit type for that argument, denoted in the command definition string by appending the argument’s name with :, e.g.

Defining an argument type has a few benefits

  • It validates that the passed in value is valid
  • It automatically parses the argument and fits it to its type, transforming the value to a more convenient data type for use when processing and executing the command
  • It provides documentation for how our command is supposed to be used

The available argument types are:

Argument Type Validation Resolved JS Type
Int Validates using parseInt Number
Float Validates using parseFloat Number
GuildMember Validates that ID passed in resolves to a member of the message’s server Discord.js::GuildMember
Date Validates using new Date() Date

Command Configuration

Command Execute Function

When your command is invoked, the command’s execute function gets called.

// args.user: Discord.js::GuildMember
// args.reason: string[]

const fullReason = args.reason.join(‘ ‘);`Banning ${args.user.displayName} for ${fullReason}`;

user.ban({ reason: fullReason })

   const bot = Solaire.create({
    commandPrelude: '!',
    commands: {
      'ban  [...reason]': {
        async execute({ args, message }) {
         // message: Discord.js::Message
         // args.user: Discord.js::GuildMember
         // args.reason: string[]
         const fullReason = args.reason.join(' ');
`Banning ${args.user.displayName} for ${fullReason}`;

         user.ban({ reason: fullReason })

> !ban @someAnnoyingUser mean
< Banning Some Annoying User for mean

The payload that gets passed into the execute function contains the following properties

Property Type Desc
args Record The arguments passed into the command
message Discord.js::Message The message that

Join the pack! Join 8000+ others registered users, and get chat, make groups, post updates and make friends around the world!
Read More

Fill your life with experiences so you always have a great story to tellBio: About:

Related Articles

Windows 11 Guide

A guide on setting up your Windows 11 Desktop with all the essential Applications, Tools, and Games to make your experience with Windows 11 great! Note: You can easily convert this markdown file to a PDF in VSCode using this handy extension Markdown PDF. Getting Started Windows 11 Desktop Bypass Windows 11’s TPM, CPU and…

What’s recent in Emacs 28.1?

By Mickey Petersen It’s that time again: there’s a new major version of Emacs and, with it, a treasure trove of new features and changes.Notable features include the formal inclusion of native compilation, a technique that will greatly speed up your Emacs experience.A critical issue surrounding the use of ligatures also fixed; without it, you…