Skip to main content
This guide will walk you through creating and deploying your first Discord bot with flora.

Prerequisites

Before you begin, make sure you have:

Create Your First Bot

1

Create a new project

Create a new directory for your bot and initialize a package.json:
mkdir my-flora-bot
cd my-flora-bot
npm init -y
2

Install the flora SDK

Add the flora SDK as a dev dependency:
npm install -D @uwu/flora-sdk
3

Create your bot script

Create a file called src/main.ts with a simple ping command:
src/main.ts
const ping = prefix({
  name: 'ping',
  description: 'Respond with pong',
  run: async (ctx) => {
    await ctx.reply('pong!')
  }
})

createBot({
  prefix: '!',
  commands: [ping]
})
No imports needed! All flora SDK functions are available globally in the runtime.
4

Add a TypeScript config

Create a tsconfig.json to get type checking:
tsconfig.json
{
  "extends": "@uwu/flora-sdk/tsconfig",
  "compilerOptions": {
    "outDir": "dist"
  },
  "include": ["src/**/*"]
}
5

Deploy to flora

Use the flora CLI to deploy your bot to a guild:
flora deploy --guild-id YOUR_GUILD_ID
The CLI will bundle your TypeScript code and deploy it to the runtime.
6

Test your bot

In your Discord server, type !ping and your bot should respond with “pong!”

Add More Features

Let’s enhance your bot with a slash command and KV storage:
src/main.ts
const ping = prefix({
  name: 'ping',
  description: 'Respond with pong',
  run: async (ctx) => {
    await ctx.reply('pong!')
  }
})

const hello = slash({
  name: 'hello',
  description: 'Say hello',
  options: [
    {
      name: 'name',
      description: 'Who to greet',
      type: 'string',
      required: false
    }
  ],
  run: async (ctx) => {
    const name = (ctx.options.name as string) || 'world'
    await ctx.reply({
      content: `Hello, ${name}!`,
      ephemeral: true
    })
  }
})

const counter = slash({
  name: 'counter',
  description: 'A simple counter using KV storage',
  subcommands: [
    {
      name: 'get',
      description: 'Get current count',
      run: async (ctx) => {
        const store = kv.store('counters')
        const count = await store.get('main')
        await ctx.reply(`Current count: ${count || 0}`)
      }
    },
    {
      name: 'increment',
      description: 'Increment the counter',
      run: async (ctx) => {
        const store = kv.store('counters')
        const current = parseInt(await store.get('main') || '0', 10)
        const newCount = current + 1
        await store.set('main', String(newCount))
        await ctx.reply(`Count is now: ${newCount}`)
      }
    }
  ]
})

createBot({
  prefix: '!',
  commands: [ping],
  slashCommands: [hello, counter]
})
Deploy the updated bot:
flora deploy --guild-id YOUR_GUILD_ID

What You’ve Learned

Commands

Create prefix and slash commands with options and subcommands

KV Storage

Store and retrieve data with the built-in KV store

Events

Listen to Discord events like messages and reactions

Embeds

Create rich embeds with colors, fields, and images

Next Steps

1

Explore the SDK

Learn about all available SDK features in the SDK Guide
2

Add event handlers

React to Discord events with the Events API
3

Schedule tasks

Run periodic tasks with Cron Jobs
4

Deploy to production

Set up your own flora runtime with the Installation Guide

Build docs developers (and LLMs) love