REPLbot is a Discord bot that allows you to control a REPL or shell from a Discord chat. It comes with a few REPLs (Go 🥳, Java, NodeJS, PHP, Python, Ruby, Scala, Kotlin, C++, Ubuntu, Debian, Alpine, Arch Linux, Amazon Linux, CentOS & Fedora), but you can easily make or bring your own.
I thought it might be a fun way to collaboratively dabble with a REPL in a team. Yes, I could have gone for a terminal in a browser, but there's nothing like having it right there in Discord. Mainly I did it because it was fun though. 😄
I use tmux and the tmux capture-pane command to run most of the show. It's simple, but effective. In the first
iteration I tried using a pseudo terminal (pty) directly, but with all the escape sequences and commands, it was getting
kinda tiresome, and I was spending time with stuff that I didn't want to spend time with (though I learned a lot!).
And tmux does its job so well.
The actual REPLs are just simple scripts (see script.d folder), so they could be anything you like. I highly recommend using Docker to provide somewhat of an isolation, though you'll probably still need to trust the people using the bot if you give them an entire REPL.
![]() |
![]() |
![]() |
| Scala, split mode (Discord) | Ubuntu running `htop` (Discord) | C++, channel mode (Discord) |
![]() |
![]() |
|
| Blinking cursors, choo choo 🚂 (Slack) | Custom shells, multiple sessions (Slack) |
After installing REPLbot, you may use it by tagging @replbot in Discord. For the most part it
should be pretty self-explanatory:
To start a session with the default settings, simply say @replbot java to start a Java REPL. There are a few advanced arguments
you can use when starting a session.
REPLbot can run more or less arbitrary scripts and interact with them -- they don't really have to be REPLs. Any interactive
script is perfectly fine, whether it's a REPL or a Shell or even a game. By default, REPLbot ships with a few REPLs.
To extend the REPLs you can run, simple add more scripts in the script-dir folder (see config.yml).
Here's a super simple example script:
#!/bin/sh
# Scripts are executed as "./script run <id>" to start the REPL, and as "./script kill <id>"
# to stop it. Not all scripts need the "kill" behavior, if they exit properly on SIGTERM.
case "$1" in
run)
while true; do
echo -n "Enter name: "
read name
echo "Hello $name!"
done
;;
*) ;;
esacIn all likelihood, you'll want more isolation by running REPLs as Docker containers. Here's the PHP REPL script that REPLbot ships with (not shortened):
#!/bin/sh
# REPLbot script to run a PHP REPL.
#
# Scripts are executed as "./script run <id>" to start the REPL,
# and as "./script kill <id>" to stop it.
DIR="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 && pwd -P)"
case "$1" in
run) docker run --rm --name "$2" -it php ;;
kill) "$DIR"/helpers/docker-kill "$2" ;;
*) echo "Syntax: $0 (run|kill) ID"; exit 1 ;;
esacWhen a session is started, you can get a list of available commands by typing !help (or !h). To exit a session at any
point in time, type !exit (or !q).
Sessions can be recorded using asciinema, and can even be automatically uploaded to either asciinema.org
or your private asciinema-server (see install instructions).
After a session exits, the recording is then attached to chat as a ZIP file and optionally as a link to the asciinema server.
This behavior can be controlled by the default-record and upload-recording option in the config.yml
file, as well as the record/norecord option when starting a session.
Here's the asciinema.org link of the example I recorded, as well as the ZIP archive with the recording.
Entering commands via Slack or Discord can be quite cumbersome, so REPLbot provides a web-based terminal (powered by the amazingly awesome ttyd). If enabled, a unique link is created for each session, which provides a read-only or writable web terminal.
This behavior can be controlled by the default-web option in the config.yml file, as well
as the web/noweb option when starting a session. While a session is running, it can be toggled using the !web
command.
You can share your local terminal window in Slack or Discord using the share feature. It's quite cool, although it's
really got nothing to do with REPLs 🤷. It also has to be specifically configured in the config.yml
file using the share-host option, since it needs direct communication between the client and REPLbot.
You can specify if you want the session to be started in the main channel (channel), in a thread (thread),
or in split mode (split) using both channel and thread. Split mode is the default because it is the cleanest to use:
it'll use a thread for command input and the main channel to display the terminal.
You can set the terminal window size when you start a session by using the keywords tiny (60x15), small (80x24),
medium (100x30), and large (120x38). The default is small. You may also resize the terminal while the session is
running using the !resize command.
When starting a session, you can choose whether to trim empty space from the terminal session (trim), or
whether to show the entire terminal window as it would appear in a terminal emulator (full). The default is full,
as trim mode can get awkward when the terminal is expanded and the collapsed again.
Please check out the releases page for binaries and packages.
Requirements:
- A modern Linux system (Ubuntu 20.04+, Debian 11+, or equivalent)
- Go 1.23+ for building from source
- tmux >= 2.9 is required
- docker for almost all scripts REPLbot ships with
- asciinema if you'd like to record sessions
- ttyd if you'd like to use the web terminal feature
Creating a REPLbot Discord app:
- Create a Discord app
- In the "Bot" section, click "Add Bot" and disable "Public Bot"
- Under "Privileged Gateway Intents", enable "Message Content Intent" (required for 2025)
- In the "OAuth2 > URL Generator" section:
- Select scopes: "bot" and "applications.commands"
- Select bot permissions: "Send Messages", "Read Message History", "Use Slash Commands", "Create Public Threads", "Create Private Threads", "Send Messages in Threads", "Manage Threads", "Manage Messages", "Embed Links", "Attach Files"
- Copy the generated OAuth2 URL and navigate to it in the browser to authorize the app
- In the "Bot" section, copy the token (starts with a long string of characters)
Installing replbot:
- Make sure
tmuxanddockerare installed. Then install REPLbot using any of the methods below. - Edit your config file to add your Discord bot token (location depends on installation method).
- Review the scripts in the script.d folder, and make sure that you have Docker installed if you'd like to use them.
- If you're running REPLbot as non-root user, be sure to add your user to the
dockergroup:sudo usermod -G docker -a $USER(then logout and login again). - Then just run it with
replbotor your chosen method.
Build from Source (recommended):
# Install dependencies
sudo apt update
sudo apt install tmux docker.io asciinema
# Clone and build (requires Go 1.23+)
git clone https://github.com/runbgp/replbot.git
cd replbot
go build -o replbot ./cmd/replbot
# Copy config files and set up
mkdir -p ~/.config/replbot
cp config/config.yml ~/.config/replbot/
cp -r config/script.d ~/.config/replbot/
# Edit config to add your Discord bot token
nano ~/.config/replbot/config.yml
# Add your user to docker group (logout/login required after this)
sudo usermod -G docker -a $USER
# Run replbot
./replbotGo Install:
# Be sure "tmux" and "docker" are installed
sudo apt install tmux docker.io asciinema
# Requires Go 1.23+
go install github.com/runbgp/replbot@latest
# Set up config directory and files manually
mkdir -p ~/.config/replbot
# Download config files from the repository
wget -O ~/.config/replbot/config.yml https://raw.githubusercontent.com/runbgp/replbot/main/config/config.yml
# Download scripts directory (you'll need to get these from the repository)
# Edit config to add your Discord bot token
nano ~/.config/replbot/config.ymlDocker:
# Clone repository for config files
git clone https://github.com/runbgp/replbot.git
cd replbot
# Edit config
cp config/config.yml config/my-config.yml
nano config/my-config.yml # Add your bot token
# Run with Docker
docker run -it --rm \
-v $(pwd)/config:/etc/replbot \
-v ~/.asciinema:/root/.config/asciinema \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 31001:31001 \
-p 31002:31002 \
golang:1.25 sh -c "cd /etc/replbot && go build -o replbot ./cmd/replbot && ./replbot"Building replbot is simple. Here's how you do it:
# Requires Go 1.25+
go build -o replbot ./cmd/replbotTo build releases, I use GoReleaser. If you have that installed, you can run make build or
make build-snapshot.
Alternatively, you can use Docker for building:
docker run --rm -v $(pwd):/app -w /app golang:1.25 go build -o replbot ./cmd/replbotI welcome any and all contributions. Just create a PR or an issue.
Made with ❤️ by Philipp C. Heckel, distributed under the Apache License 2.0.
Third party tools/libraries:
- tmux (ISC) is used to run most of the show
- docker is used for almost all scripts REPLbot ships with
- asciinema (GPLv3) is used to record sessions
- ttyd (MIT) is used to run the web terminal
- github.com/urfave/cli/v2 (MIT) is used to drive the CLI
- discord-go (BSD-3) is used for Discord communication
- gliderlabs/ssh (BSD-3) is used for remote port forwarding for terminal sharing
- stretchr/testify (MIT) is used in most of the tests
Code and posts that helped:
- tmux sharing across hosts, thanks to QuAzI














