Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/coah80/yoink/llms.txt

Use this file to discover all available pages before exploring further.

Yoink ships as a single Go binary that bundles both the REST API and the Svelte frontend. There is no Docker image or package registry — you build it yourself from the source repository. This page walks through every step from a fresh clone to a running server.

Build overview

The Makefile at the root of the repository defines all build targets. The version string is automatically derived from Git tags at build time and injected into the binary via linker flags:
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
LDFLAGS = -ldflags "-s -w -X github.com/coah80/yoink/internal/config.Version=$(VERSION)"
The -s -w flags strip the symbol table and DWARF debug information, producing a smaller binary. If no Git tags exist, the version falls back to "dev".

Build steps

1

Clone the repository

git clone https://github.com/coah80/yoink.git
cd yoink
2

Install system dependencies

Yoink requires yt-dlp and ffmpeg at runtime. Install them before starting the server so the startup dependency check passes.
# Debian / Ubuntu
apt install ffmpeg
pip install yt-dlp

# macOS
brew install ffmpeg yt-dlp

# Optional: image gallery support
pip install gallery-dl

# Optional: local transcription
pip install openai-whisper
3

Configure your environment

Copy the example environment file and edit it with your values. The server loads .env automatically on startup via godotenv.
cp .env.example .env
$EDITOR .env
At minimum, review PORT (defaults to 3001) and BOT_SECRET if you plan to use the Discord bot. See the Environment Variables page for the full reference.
4

Build the server binary

make build
This runs:
go build -ldflags "-s -w -X github.com/coah80/yoink/internal/config.Version=$(VERSION)" -o yoink ./cmd/yoink
The output is a single yoink binary in the current directory.
5

Run the server

./yoink
On startup, Yoink will:
  • Print a startup banner showing the version
  • Check all required and optional dependencies (yt-dlp, ffmpeg, ffprobe, gallery-dl, python3 + whisper)
  • Create all temp directories under /var/tmp/yoink if they don’t exist
  • Begin refreshing YouTube session tokens in the background
  • Start listening on :3001 (or your configured PORT)
The server serves the REST API on all routes and the compiled Svelte frontend from a ./public/ directory located next to the binary.

Available Makefile targets

TargetCommandOutput
make buildgo build … ./cmd/yoink./yoink
make botgo build … ./cmd/bot./yoink-bot
make rungo run … ./cmd/yoink(runs in place, no binary)
make linuxCross-compile for Linux amd64./yoink-linux
make linux-botCross-compile bot for Linux amd64./yoink-bot-linux
make windowsCross-compile for Windows amd64./yoink.exe
make cleanRemove all build outputs

Development mode

For local development, skip the build step entirely and use make run:
make run
This calls go run ./cmd/yoink with the same LDFLAGS, so the version is still injected. Changes require a restart — there is no hot-reload.

Cross-compilation

If you are building on macOS or Windows and targeting a Linux server, use the cross-compilation targets.
Build a Linux binary from any host platform:
make linux
This sets GOOS=linux GOARCH=amd64 and outputs yoink-linux. Copy it to your server along with the public/ directory:
scp yoink-linux user@your-server:/opt/yoink/yoink
scp -r frontend/public user@your-server:/opt/yoink/public

Building the Discord bot

The Discord bot is a separate binary built from ./cmd/bot. It connects to the Yoink API over HTTP rather than embedding the media logic itself.
make bot          # local binary: ./yoink-bot
make linux-bot    # Linux amd64:  ./yoink-bot-linux
The bot binary requires its own set of environment variables (DISCORD_TOKEN, DISCORD_APP_ID, etc.) and is configured independently from the main server.

Production deployment

For production, run Yoink behind a reverse proxy such as nginx or Caddy to handle TLS termination, compression, and access logging. Yoink itself speaks plain HTTP.
A minimal systemd unit file to keep Yoink running:
[Unit]
Description=Yoink media server
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/yoink
EnvironmentFile=/opt/yoink/.env
ExecStart=/opt/yoink/yoink
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
The public/ directory must be located in the same directory as the yoink binary. The server resolves it as filepath.Join(filepath.Dir(os.Args[0]), "public") at runtime. If the directory is missing or not found, the frontend will not be served — only the API will respond.

Build docs developers (and LLMs) love