---
title: Publish
description: Publish your commands to Discord
---

:::tip 
`sern commands publish` was experimental and we've decided to move on from it. 
This cli command only works with version 3 of `@sern/handler` in an integrated fashion,
use the new service `Publisher`, officially maintained.
:::

```sh
Usage: sern commands publish [options] [path]

New way to manage your slash commands

Arguments:
  path                          path with respect to current working directory that will locate all published files

Options:
  -i, --import [scriptPath...]  Prerequire a script to load into publisher
  -t, --token [token]
  -h, --help                    display help for command
```

## Introduction

The publish command is a way to publish slash commands to Discord. It uses the [`PUT`](https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands) route to overwrite existing commands.

Wherever your commands directory is located, publish will override the existing application commands on Discord. Existing commands do not count towards the command limit creation daily.

The publish command automatically reads your `.env` file in the working directory. If you do not have a `.env` file, you can pass in the `--token` and `--appId` flags.

:::caution
CLI arguments, if specified, take precedence over `.env` file.
:::

Your `.env` file should look like this:

```sh title=".env"
DISCORD_TOKEN=<YOUR_TOKEN>
APPLICATION_ID=<YOUR_APPLICATION_ID>
NODE_ENV=<production|development>
```

## Usage

:::caution
CommonJS and JavaScript users need to compile first, then run `sern publish` on the `dist` output
:::

![usage](~/assets/docs/sern-publish.gif)

## Features

- Automatically syncs API with your command base
- Generates a JSON file of output (`.sern/command-data-remote.json`)
- Supports publishing direct ESM TypeScript files
- Prerequire scripts are supported
- Supports a configuration that is the same as the original publish plugin
- Each command file can have an extra config that follows `ValidPublishOptions`
  - This can be a function or a `PublishConfig` object

## Config

```ts {13-15}
type ValidMemberPermissions =
    | PermissionFlagBits  // discord.js enum
    | PermissionFlagBits[]  // array of discord.js enum
    | string // must be a stringified number (such as "8" for ADMINISTRATOR)
    | bigint

interface PublishConfig {
    guildIds?: string[];
    dmPermission?: boolean;
    defaultMemberPermissions: ValidMemberPermissions;
}

type ValidPublishOptions =
    | PublishConfig
    | (absPath: string, module: CommandModule) => PublishConfig
```

## Prerequiring

Is there a [service](/v3/guide/walkthrough/services) that is required at the top level of a command?

Create an ES6 script anywhere, such as:

```ts title="scripts/prerequire.mjs"
import { makeDependencies, single, Service } from "@sern/handler";
import { Client } from "discord.js";

await makeDependencies({
  build: (root) =>
    root.add({ "@sern/client": single(() => new Client(...options)) }),
});

await Service("@sern/client").login();
```

This will create a container for publishing.

:::danger
As of 0.6.0, the `client` is required, or this will crash.
:::

## Example

This example will publish a ping command to a specific guild: `889026545715400705`.

### Script

```sh
sern commands publish -i ./scripts/prerequire.mjs
```

### Command

```ts title=src/commands/ping.ts {5-7}
import { commandModule, Service, CommandType } from '@sern/handler'

const client = Service('@sern/client');

export const config = {
    guildIds: ["889026545715400705"]
}

export default commandModule( {
    type: CommandType.Slash
    description: `${client.user.username}'s ping`,
    execute: (ctx) => {
        ctx.reply('pong')
    }
})
```
