On This Page

Start a Bot

Send !ping and receive Pong! from a bot

Before starting, create a Fluxer bot, copy its token when Fluxer shows it and add the bot to a community. Fluxer shows a token only once, and the project below has a file for it. Fluxerly is tested against Node.js 24.15 or newer

Generate the Project

The generator writes into the terminal's current folder. Start in a new folder for the bot:

mkdir my-bot
cd my-bot
npx @neontechspace/fluxerly initpnpm dlx @neontechspace/fluxerly initbunx @neontechspace/fluxerly init

Adding --template js, --template ts or --template effect skips the question. The JavaScript and TypeScript templates write the bot shown below. The Effect template writes the Effect starter bot instead. Each template includes a test and an AGENTS.md file, and creates a .env file with an empty token value unless that file already exists. The command then installs the dependencies and prints the remaining steps, or prints installation instructions when installation is skipped or fails

The folder may already hold the .env and .gitignore that the manual setup describes. The command keeps the .env and its token, adds node_modules and .env to the .gitignore when they are missing and leaves the rest of that file as it is. When any other file that the command writes already exists, such as package.json or bot.js, it stops without writing anything

Then set FLUXER_BOT_TOKEN in .env to the token. Check the bot with npm test, pnpm test or bun run test, which runs it against an in-memory Fluxer without the token or a network. Start it with npm start, pnpm start or bun run start and continue with Try it

Set Up the Project by Hand

These steps create the same bot without the generator

1. Install the SDK

Open a terminal in the bot's folder. Create a package.json file in that folder:

{
    "type": "module"
}

This lets the bot use import in Node.js

npm install @neontechspace/fluxerlypnpm add @neontechspace/fluxerlybun add @neontechspace/fluxerly

When a coding agent helps write the bot, copy the SDK's rules for it into the project's AGENTS.md, which many coding agent tools read automatically. Run the same command again after updating the SDK

npx --no fluxerly agentspnpm exec fluxerly agentsbunx --no-install fluxerly agents

2. Save the Token

Save the token in a file named .env in the bot's folder:

.env
FLUXER_BOT_TOKEN=paste-the-token-here

Check that the file is named exactly .env. Some editors, such as Notepad, add .txt when saving, and Node.js cannot find .env.txt

Keep that file out of version control by adding this line to .gitignore:

.gitignore
.env

3. Create the Bot

Save this as bot.js. The bot reads its token from FLUXER_BOT_TOKEN in the process environment, so the token never appears in the file

import { defineBot, runBot } from "@neontechspace/fluxerly"

// The bot's options without its token, so its test can run them through createTestBot without a token or a network
export const bot = defineBot({
    commands: {
        prefix: "!",
        commands: {
            // Returning the reply reports a failed send to the log
            ping: { execute: ({ reply }) => reply("Pong!") },
        },
    },
})

// Running this file starts the bot, while importing it from a test does not.
// A failure that stops the bot, such as a rejected token, is logged and sets a failing exit code
if (import.meta.main) await runBot({ token: process.env.FLUXER_BOT_TOKEN, ...bot })
import { defineBot, runBot } from "@neontechspace/fluxerly"

// The bot's options without its token, so its test can run them through createTestBot without a token or a network
export const bot = defineBot({
    commands: {
        prefix: "!",
        commands: {
            // Returning the reply reports a failed send to the log
            ping: { execute: ({ reply }) => reply("Pong!") },
        },
    },
})

// Running this file starts the bot, while importing it from a test does not.
// A failure that stops the bot, such as a rejected token, is logged and sets a failing exit code
if (import.meta.main) await runBot({ token: process.env.FLUXER_BOT_TOKEN, ...bot })

The file exports the bot's options as bot. The defineBot function returns them unchanged and keeps the types of command arguments for TypeScript and editors. Running the file starts the bot with these options and the token, while a test can import bot without starting it. Testing a bot shows the test that the generator writes

4. Start It

Start the bot with the token's .env file:

node --env-file=.env bot.jsnode --env-file=.env bot.ts

When FLUXER_BOT_TOKEN is already set in the terminal, run the file without --env-file=.env

Set the Variable in the Terminal Instead

In bash or zsh, run export FLUXER_BOT_TOKEN="paste-the-token-here", then start the bot with node bot.js in the same terminal. In PowerShell, run $env:FLUXER_BOT_TOKEN = "paste-the-token-here", then node bot.js

The variable lasts until the terminal closes. The typed command can stay in the shell's history, so prefer .env on shared machines

Try It

Once the bot is online, the terminal shows a line such as Connected to Fluxer as MyBot in 1 community. If it says instead that the bot is not in any community yet, open the link in that line to invite it

Type !ping in a channel the bot can read and reply to. It should answer Pong!

The SDK skips messages from bots by default. The commands option routes a message that starts with the ! prefix and a command name, such as !ping, to that command, and the bot ignores every other message

Press Ctrl+C to stop the bot. The SDK then stops the commands, closes the connection and finishes its cleanup before the program ends

Keep Going

Change ping or Pong! to customize the command or reply. Then choose a task:

The client's message methods link to the full API reference for exact inputs and return values

If the Bot Does Not Reply

Check that FLUXER_BOT_TOKEN is set and that the bot can view the channel and send messages. Without a token, the bot stops at once with an error whose hint points to an unset environment variable. When Node.js prints .env: not found, the terminal is not in the bot's folder or the file is saved as .env.txt. Keep the terminal running when trying !ping. When a reply fails, the terminal shows a log line with the reason and a hint, such as a missing permission. Outside a terminal, such as in an editor's run panel, log lines are JSON. Add FLUXERLY_LOG_FORMAT=pretty to .env for readable lines there. A reply can fail after Fluxer has already posted it, for example when the response is lost, so do not send it again blindly

The troubleshooting guide helps tell command, connection and request failures apart. Never share a bot token or private message contents

What Happens When Something Fails?

Requests such as reply return expected failures in a Result, which is either a success or a failure. Unexpected SDK faults can still reject the Promise

The command returns the reply's Result, so the SDK logs a failed reply and the bot keeps running

A failure that stops the whole bot, such as a rejected token, is logged once, and the process ends with exit code 1 so a shell or process manager can tell it from a normal stop. A missing token is logged with a hint and also ends the process with exit code 1, before the bot connects. The core concepts page explains Results in more detail

Using TypeScript or Effect?

Choose TypeScript above to save this example as bot.ts. The code is the same, and Node.js runs it directly, without a compilation step, and removes the types without checking them

A generated TypeScript or Effect project needs no further setup to typecheck. It installs TypeScript 7 and the Node.js types, writes the tsconfig.json below and adds a check script that runs the compiler, as npm run check, pnpm run check or bun run check. To typecheck a project set up by hand, install the Node.js types, which the SDK's types use for values such as the AbortSignal passed to handlers:

npm install --save-dev @types/nodepnpm add --save-dev @types/nodebun add --dev @types/node

Install typescript@7 the same way, as another development dependency. Then add a tsconfig.json next to the bot:

{
    "compilerOptions": {
        "target": "ES2024",
        "module": "NodeNext",
        "types": ["node"],
        "strict": true,
        "noEmit": true,
        "allowImportingTsExtensions": true,
        "verbatimModuleSyntax": true,
        "erasableSyntaxOnly": true
    }
}

TypeScript only checks the code and writes no output, because Node.js removes the types itself. The last three settings keep the code in a form Node.js can run directly: Imports of other files may use their .ts extension, type-only imports need import type, and TypeScript features that generate code, such as enum, are reported. Run the check with npm exec tsc, pnpm exec tsc or bun run tsc

JavaScript can also use editor inference and optional // @ts-check without changing file extensions or adding a build step. Neither a compiler nor checked JavaScript is required to run the bot

The default API works with JavaScript and TypeScript. Effect is optional: The Effect learning path introduces the native API and shows which Effect version to install