# seedcord guide > The guide to building Discord bots with seedcord. - seedcord has no presence in training data. Read a page before you write code against it. - `seedcord` on npm is the command line tool. A bot installs `@seedcord/gateway` for a websocket connection, or `@seedcord/http` to answer Discord's interactions endpoint. It installs one of the two. - Read the current version of every package from the npm registry. Each one has its own version number. - A command is declared in one file and answered in another, by a handler class carrying a route decorator. seedcord reads those decorators at startup and dispatches every interaction itself. - `seedcord codegen` writes the typed tables for slash commands, user and message context menus, emojis, and plugin keys. Run it after changing any of those. - Never import from a seedcord path ending in `/internal`, like `@seedcord/core/internal`. Those paths wire seedcord's own packages together and change without notice. If the only way to do something is through one, tell the user so they can open an issue at https://github.com/seedcord/seedcord/issues. - The steps for building a bot are at https://preview.seedcord.org/.well-known/agent-skills/seedcord/SKILL.md. - The API reference is at https://seedcord.org/docs, one page per symbol. - The project site is at https://preview.seedcord.org. - [Start here](https://preview.seedcord.org/guide/index.md): Build a Discord bot in TypeScript with seedcord, which types your commands, options, and component ids end to end. - [Gateway or http](https://preview.seedcord.org/guide/gateway-or-http.md): Pick the gateway or http transport for your Discord bot by what each one receives from Discord and where your bot runs. - [Create your Discord application](https://preview.seedcord.org/guide/discord-application.md): Create the application your bot runs as in Discord's developer portal, then get its token and add it to a server. - [Your first bot](https://preview.seedcord.org/guide/first-bot.md): Create a seedcord project with pnpm create seedcord, run it, and try its first slash command in Discord. - [The core object](https://preview.seedcord.org/guide/core.md): Read your config and your plugins from any handler through this.core, and run work while your bot starts and stops. - [Where to go next](https://preview.seedcord.org/guide/where-to-go-next.md): Find what to read once your bot runs, plus the example bots, the API reference, and where to ask for help when you get stuck. - Commands - [Commands](https://preview.seedcord.org/guide/commands.md): Create your first slash command from two files, one that declares it to Discord and one that answers it when someone runs it. - [Options](https://preview.seedcord.org/guide/commands/options.md): Declare options on a slash command and read them back through getters typed from what you declared, with required ones never null. - [Subcommands and groups](https://preview.seedcord.org/guide/commands/subcommands.md): Put related slash commands under one name with subcommands and groups, and see the route each branch gets. - [One handler, several commands](https://preview.seedcord.org/guide/commands/one-handler.md): Answer several slash commands or subcommands from one handler class, and branch on the route that ran. - [Autocomplete](https://preview.seedcord.org/guide/commands/autocomplete.md): Suggest option values from your own data while someone types a slash command, and read the options they already filled in. - [Context menu commands](https://preview.seedcord.org/guide/commands/context-menus.md): Add a right-click command to a user or a message in Discord, and read the user or message someone ran it on. - [Command mentions](https://preview.seedcord.org/guide/commands/mentions.md): Put a clickable mention of a slash command in your bot's messages, built from the commands your bot deployed. - [Deployed commands](https://preview.seedcord.org/guide/commands/deployed.md): Control when your bot sends its commands to Discord and which servers get them, and see why seedcord dev sometimes skips the deploy. - [Why your command has not appeared](https://preview.seedcord.org/guide/commands/missing.md): Find out why Discord doesn't show a command, from its scope and your test servers to dev skips and permissions. - Replying - [Replying](https://preview.seedcord.org/guide/replying.md): Answer an interaction from its handler with reply(), defer(), edit(), and followUp(), and build each reply from components. - **Sending** - [Deferring and follow-ups](https://preview.seedcord.org/guide/replying/more-messages.md): Keep an interaction open past Discord's three-second limit, then send more messages and edit or delete them from the same handler. - [When a reply throws](https://preview.seedcord.org/guide/replying/ack-states.md): Find out which reply methods work in each state Discord tracks for an interaction, and why a reply call throws. - [Files and attachments](https://preview.seedcord.org/guide/replying/files.md): Upload files with a reply and show them in the message through a file, thumbnail, or media gallery component. - [Raw acks](https://preview.seedcord.org/guide/replying/raw-acks.md): Reply through discord.js's own methods on this.event, and see what seedcord stops tracking when you do. - **Throwing** - [Throwing](https://preview.seedcord.org/guide/replying/throwing.md): Refuse a request from a handler by throwing a Notice, so the user sees your reason on a card and your code stops there. - [Faults](https://preview.seedcord.org/guide/replying/faults.md): See how a user still gets an answer when your handler throws an error it doesn't catch, and change the card seedcord shows. - [Reporting faults](https://preview.seedcord.org/guide/replying/reporting.md): Send the errors your bot reports to a Discord channel through a webhook, or write a reporter of your own. - [Tuning error behavior](https://preview.seedcord.org/guide/replying/error-behavior.md): Set what your bot does with an error through the errors block on your config, like the card a fault shows and what it ignores. - **Formatting a message** - [Formatting helpers](https://preview.seedcord.org/guide/replying/formatting.md): Turn raw ids, timestamps, durations, and big numbers into text a user can read with seedcord's formatting helpers. - [Rendering a table](https://preview.seedcord.org/guide/replying/render-table.md): Draw an aligned table into a message with renderTable(), with frames, column caps, emoji widths, and paging past Discord's limit. - Components - [Components](https://preview.seedcord.org/guide/components.md): Build the cards, buttons, and rows your bot sends as classes over the discord.js builders, with your bot color and emojis by name. - **Custom IDs** - [Custom IDs](https://preview.seedcord.org/guide/components/custom-ids.md): Declare what a component's custom id carries with CustomId, so a click arrives with typed values and you skip parsing strings. - [When a custom id goes stale](https://preview.seedcord.org/guide/components/stale.md): Handle a click on a component your bot sent before its custom id changed shape, and choose what that user sees. - **Handling a click** - [Buttons](https://preview.seedcord.org/guide/components/buttons.md): Answer a button click with ButtonHandler, read the values its custom id carries, and rewrite the message the click came from. - [Select menus](https://preview.seedcord.org/guide/components/select-menus.md): Answer a pick from a select menu, including the user, role, and channel menus Discord fills in for you. - [Modals](https://preview.seedcord.org/guide/components/modals.md): Collect text, menu picks, files, and checkboxes from a user with a modal, then read the submission in a modal handler. - [Confirmation prompts](https://preview.seedcord.org/guide/components/confirm.md): Ask a user to confirm before something destructive runs with getConfirmation(), which sends the prompt and waits for the click. - **Pagination** - [Pagination](https://preview.seedcord.org/guide/components/pagination.md): Split a long list into pages with Paginator, and let users move between them with buttons that still work after a restart. - [Sources](https://preview.seedcord.org/guide/components/pagination-sources.md): Decide where a paginator's items come from, whether that's an array you already hold or one page at a time from your database. - [Custom rendering](https://preview.seedcord.org/guide/components/pagination-render.md): Take over a paginator's whole message with render() when the default layout doesn't fit, then put its nav buttons back yourself. - [Paging it yourself](https://preview.seedcord.org/guide/components/pagination-headless.md): Page a message without a Paginator by calling paginate() with a cursor you declare, for when the class doesn't fit. - Checks - [Checks](https://preview.seedcord.org/guide/checks.md): Decide whether a handler runs with gates, middleware, and rate limits, and see the order seedcord runs them in. - **Gates** - [Gates](https://preview.seedcord.org/guide/checks/gates.md): Run checks before your handler with @Gated, so a caller who fails one gets a refusal and never reaches your code. - [Permissions](https://preview.seedcord.org/guide/checks/permissions.md): Check the caller's permissions, your bot's permissions, or the caller's role before a handler runs, and reword each refusal. - [Your own gates](https://preview.seedcord.org/guide/checks/your-own.md): Write a gate of your own with defineGate() when the shipped ones don't fit your rule, and limit it to the handlers it fits. - [Combining gates](https://preview.seedcord.org/guide/checks/combining.md): Combine gates with or() and and() to let a command run when any one gate passes, or to group checks you reuse. - [Effect gates](https://preview.seedcord.org/guide/checks/effect-gates.md): Write a gate that changes something, like spending a credit, with defineEffectGate(), and control when that change happens. - **Middleware** - [Interaction middleware](https://preview.seedcord.org/guide/checks/middleware.md): Run code before and after your interaction handlers with middleware, or stop a dispatch before it reaches them. - [The dispatch context](https://preview.seedcord.org/guide/checks/dispatch-context.md): Pass values from a middleware to the handler, gates, and fault card of the same dispatch through the typed dispatch context. - **Rate limiting** - [Cooldowns](https://preview.seedcord.org/guide/checks/cooldown.md): Limit how often someone can run a command with the Cooldown() gate, choose who shares a window, and keep windows across restarts. - [The rate limiter](https://preview.seedcord.org/guide/checks/rate-limiter.md): Count uses against any key you build with the rate limiter, and write a durable store to keep the counts. - **Inside a handler** - [Permissions in a handler](https://preview.seedcord.org/guide/checks/in-handler-permissions.md): Check permissions inside a handler with assertPermissions() and the gateway helpers, for a member, a role, or your own bot. - [Changing roles](https://preview.seedcord.org/guide/checks/changing-roles.md): Check that your bot can assign a role with hasPermsToAssign(), then build and write a member's new role list with mergeRoles(). - Events - [Your first event handler](https://preview.seedcord.org/guide/events.md): Run code when discord.js emits an event, like a member joining a server, with an event handler class that reads its payload. - [Several events in one class](https://preview.seedcord.org/guide/events/several-events.md): Run one handler class for several discord.js events with this.match(), and get a compile error for any event you forget. - [Event middleware](https://preview.seedcord.org/guide/events/middleware.md): Run code before and after your event handlers with event middleware, or stop an event before it reaches them. - [Handling messages](https://preview.seedcord.org/guide/events/messages.md): Read the text of messages in a gateway event handler, and turn on the Message Content intent that Discord requires for it. - **The bus** - [The bus](https://preview.seedcord.org/guide/events/bus.md): Send your own typed events between parts of your bot with the bus, and subscribe to them from a class or a callback. - [The framework's bus keys](https://preview.seedcord.org/guide/events/default-keys.md): Subscribe to the events seedcord itself publishes on the bus, and see which transport publishes each one. - [Reading the telemetry](https://preview.seedcord.org/guide/events/telemetry.md): Measure how long your bot takes to answer with the telemetry keys on the bus, for every interaction, write, and event. - Plugins - [Plugins](https://preview.seedcord.org/guide/plugins.md): Add your own services to a bot with plugins, which seedcord starts and stops with it, and read them from any handler. - [Typing a plugin](https://preview.seedcord.org/guide/plugins/typing.md): Type the plugins you attached on this.core with seedcord codegen, and see when you need to run codegen again. - [The lifecycle](https://preview.seedcord.org/guide/plugins/lifecycle.md): Control when a plugin starts and stops with init(), ready(), and dispose(), and what happens when one of them fails. - **Mongoose** - [Mongoose](https://preview.seedcord.org/guide/plugins/mongoose.md): Connect a gateway or http bot to MongoDB with the mongoose plugin, which opens and closes the connection with your bot. - [Mongoose services](https://preview.seedcord.org/guide/plugins/mongoose-services.md): Write a service class for each MongoDB collection with the mongoose plugin, and read those services from any handler. - **Kysely and Postgres** - [Kysely and Postgres](https://preview.seedcord.org/guide/plugins/kysely.md): Connect a gateway or http bot to Postgres through Kysely with the kysely plugin, which starts and stops with your bot. - [Your schema](https://preview.seedcord.org/guide/plugins/kysely-schema.md): Type your Postgres tables for the kysely plugin by declaring a schema on KyselyDatabase, and keep it in step with your migrations. - [Kysely services](https://preview.seedcord.org/guide/plugins/kysely-services.md): Write a service class for each Postgres table with the kysely plugin, and read those services from any handler. - [Migrations](https://preview.seedcord.org/guide/plugins/kysely-migrations.md): Create and change your Postgres tables with Kysely migrations in the kysely plugin, and control when they run. - Writing plugins - [Writing a plugin](https://preview.seedcord.org/guide/writing-plugins.md): Write a plugin that your bot starts and stops, give it typed options, and call it from your handlers through this.core. - [Typing what you ship](https://preview.seedcord.org/guide/writing-plugins/typing.md): Make a bot see your plugin's types, give a plugin a type parameter, and read one plugin from another without breaking attach. - [Where it runs](https://preview.seedcord.org/guide/writing-plugins/runtimes.md): Limit a plugin to one transport or runtime so a wrong attach fails to compile, and keep Workers plugins free of server-only imports. - [Loading a bot's files](https://preview.seedcord.org/guide/writing-plugins/files.md): Load a folder of the bot's code or data from a plugin with importFiles and readFiles, in dev, in tests, and in a built bot. - [Reloading in dev](https://preview.seedcord.org/guide/writing-plugins/hot-reload.md): Reload the files your plugin loads when you save them under seedcord dev, and ask for a restart for the ones it reads once. - [Testing and publishing](https://preview.seedcord.org/guide/writing-plugins/publishing.md): Package a plugin so a bot installs it with one copy of @seedcord/core, test it in a local bot with pnpm, then publish it to npm. - Tooling - [Tooling](https://preview.seedcord.org/guide/tooling.md): Point the seedcord CLI at your bot with seedcord.config.ts, and pick the command that runs, builds, or deploys it. - [The dev loop](https://preview.seedcord.org/guide/tooling/dev.md): Run your bot locally with seedcord dev, which reloads a changed handler without restarting the process. - [Hot reload](https://preview.seedcord.org/guide/tooling/hot-reload.md): Swap a saved file into your running bot with seedcord dev, and see which saves still need a full restart. - [Codegen](https://preview.seedcord.org/guide/tooling/codegen.md): Type your commands, emojis, and plugins by running seedcord codegen, and catch a stale generated file in CI. - [The commands CLI](https://preview.seedcord.org/guide/tooling/commands.md): Deploy your commands to Discord, list what it holds, and delete duplicates or whole scopes with seedcord commands, from a terminal or a CI job. - [The dev tunnel](https://preview.seedcord.org/guide/tooling/tunnel.md): Give an http bot a public address through a Cloudflare tunnel that seedcord dev opens while you work on it locally. - [Logging](https://preview.seedcord.org/guide/tooling/logging.md): Log from your handlers, subscribers, and plugins through the logger each one carries, with five levels and named channels. - [Configuring the logger](https://preview.seedcord.org/guide/tooling/logger-config.md): Set where your bot's logs go and how much of them prints, through the logger block on your bot config. - [Linting](https://preview.seedcord.org/guide/tooling/lint.md): Catch bot mistakes in your editor with the shared ESLint config and its seedcord and discord.js rules. - Build & deploy - [How seedcord runs your bot](https://preview.seedcord.org/guide/build.md): Run and build your bot through Vite, so the same Vite plugins, .env files, and data files work in seedcord dev, codegen, and the production build. - [seedcord.config.ts](https://preview.seedcord.org/guide/build/config.md): Tell the seedcord CLI where your bot lives and how to build it with seedcord.config.ts, and look up what each key does and where its paths resolve. - [Vite plugins](https://preview.seedcord.org/guide/build/vite-plugins.md): Add a Vite plugin to your bot so handlers can import YAML, SQL, or any file a plugin can load, in seedcord dev, codegen, and the build alike. - [Environment and config](https://preview.seedcord.org/guide/build/env.md): Keep your bot token and settings in .env files, switch them per environment with ENV=staging, and read them as typed values with envapt. - [Data files](https://preview.seedcord.org/guide/build/data-files.md): Ship JSON, images, and other non-code files with your bot by listing their folders in files, then read them with readFiles in dev and in production. - [A Node or Bun server](https://preview.seedcord.org/guide/build/server.md): Build your bot into one folder you copy to a VPS or a container and start with node, or compile it into a single Bun binary that needs no node_modules. - [Cloudflare Workers](https://preview.seedcord.org/guide/build/workers.md): Run an http bot on Cloudflare Workers, test it locally in workerd with seedcord dev, and deploy the worker that seedcord build writes with cf. - [Your bot as a package](https://preview.seedcord.org/guide/build/package.md): Publish your bot as an npm package that another project installs, imports, and starts, with its plugins typed and its port picked by whoever runs it. - [Inside your own server](https://preview.seedcord.org/guide/build/embed.md): Run an http bot inside a server you already have, like Hono, Next.js, or Express, so one process and one port answer both your app and Discord's interactions.