Sunar

Getting started

Learn how to create your first bot using Sunar in just a few steps.

Prerequisites

Create a new app with create-sunar. This will scaffold your project and install all dependencies.

npm create sunar

You'll be prompted for your project name, language (TypeScript or JavaScript), and features (Biome, TSX, TSUP, Prettier, ESLint, etc).

Manual Setup

Install dependencies

Ensure you have Node.js (22.12.0 or newer) installed on your machine. Sunar requires discord.js as a peer dependency.

npm install sunar discord.js

Initialize your bot client

Create a new file, e.g., src/index.js, and set up your Discord bot using Sunar:

src/index.js
import { Client, load } from 'sunar';

const start = async () => {
	const client = new Client({ intents: [] });

	// stores all sunar modules, you can add more
	// directories by passing them after the "signals"
	// with a comma (e.g. signals,buttons,autocompletes)
	await load("src/{commands,signals}/**/*.{js,ts}");

	client.login('YOUR_DISCORD_BOT_TOKEN');
};

start();

To learn more about how load() works and how to customize what gets loaded, see the Load modules guide.

Replace 'YOUR_DISCORD_BOT_TOKEN' with your actual bot token from the Discord Developer Portal.

Add a ready signal

Signals handle Discord events. Let's log when the bot is online:

src/signals/ready.js
import { Signal, Signals, execute } from 'sunar';
import { registerCommands } from 'sunar/registry';

const signal = new Signal(Signals.ClientReady, { once: true });

execute(signal, async (client) => {
	await registerCommands(client.application);
	console.log("Commands registered");

	console.log(`Logged in as ${client.user.tag}`);
});

export { signal };

Avoid registering commands repeatedly in a short time—Discord rate limits apply. Use the --register flag to control registration timing. See Using the --register flag section.

Create your first command

Let's add a simple ping command:

src/commands/ping.js
import { Slash, execute } from 'sunar';

const slash = new Slash({
	name: 'ping',
	description: 'Show client ws ping',
});

execute(slash, (interaction) => {
	interaction.reply({
		content: `Client WS Ping: ${interaction.client.ws.ping}`,
	});
});

export { slash };

Handle interactions

Add the interactionCreate signal to handle command execution:

src/signals/interaction-create.js
import { Signal, execute } from 'sunar';
import { handleInteraction } from 'sunar/handlers';

const signal = new Signal('interactionCreate');

execute(signal, async (interaction) => {
	await handleInteraction(interaction);
});

export { signal };

Make sure to include interaction-create.js, or your commands won't be executed!

For more on interaction handling, see the handle interactions guide.

Test your bot

Run your bot and you should see:

Logged in as MyBot#1234

Try using /ping in your Discord server to verify everything works!

File structure

Here's how your project should look:

ping.js
interaction-create.js
ready.js
index.js

What next?

  • Customize and expand your commands and signals based on your bot's functionality.
  • Dive deeper into command options such as subcommands, options, and permissions to create more complex and versatile interactions.
  • Explore comprehensive features like context menu commands, buttons, modals, and more.

Troubleshooting

How is this guide?

Last updated on