@frinky/boiler
v0.1.3
Published
Butler-like CLI for uploading builds to Steam via SteamCMD
Maintainers
Readme
boiler
boiler is a CLI for uploading game builds to Steam via SteamCMD.
It generates VDF files, guides Steam login + Steam Guard flows, and gives you a repeatable login -> init -> push workflow without manual Steamworks UI steps.
Table of Contents
- Why boiler
- Install
- Simple Usage (Beginner Friendly)
- Command Quick Reference
- Command Details
- Project Config (.boiler.json)
- CI / Automation
- SteamCMD Behavior
- Security
- Development
- License
Why boiler
Uploading with raw SteamCMD usually means:
- hand-writing VDF files
- remembering the right command sequence
- re-checking paths and depot mappings every upload
- dealing with Steam Guard prompts manually
boiler handles this with:
- interactive project setup (
boiler init) - guided login (
boiler login) - one-command upload (
boiler push) - changed-depot detection (skip unchanged depots)
doctorandstatuscommands for preflight and diagnostics
Install
Global install:
npm install -g @frinky/boilerRun without installing:
npx @frinky/boiler --helpSimple Usage (Beginner Friendly)
If this is your first Steam upload, follow this exactly.
1. Log in once
boiler loginWhat happens:
- you enter Steam credentials
- Steam Guard is handled interactively (email/app/mobile prompt)
boilerstores only your username (not your password)
2. Create project config
From your game project folder:
boiler initYou will be prompted for:
- Steam App ID
- one or more Depot IDs
- content root folder(s) (for example
./build) - include/exclude mapping rules
This creates .boiler.json in your project root.
3. Upload your build
boiler pushThat is the full basic flow.
4. Optional: one-off folder override (single depot only)
boiler push ./distUse this only when your config has a single depot.
Command Quick Reference
| Command | What it does |
| --- | --- |
| boiler login | Authenticates with Steam and caches session via SteamCMD |
| boiler init | Creates .boiler.json using an interactive wizard |
| boiler push [folder] | Generates VDF and uploads build |
| boiler status | Shows config/auth/artifact/upload status |
| boiler doctor | Runs preflight checks |
| boiler help [command] | Shows CLI help |
Global options:
| Flag | Description |
| --- | --- |
| -v, --verbose | Extra logging |
| --debug | Debug logging (implies verbose) |
Command Details
boiler login
Interactive login:
boiler loginNon-interactive (CI/automation):
BOILER_USERNAME=buildbot \
BOILER_PASSWORD=super-secret \
boiler login --non-interactiveSupported automation inputs:
--username <name>--password-env <var>--guard-code-env <var>--install-steamcmd--non-interactiveBOILER_USERNAMEBOILER_PASSWORDBOILER_GUARD_CODEBOILER_NON_INTERACTIVE=1
boiler init
Create or refresh project config:
boiler initboiler push [folder]
Upload using .boiler.json:
boiler pushExamples:
# Single-depot folder override
boiler push ./build
# One-off upload without config
boiler push ./build --app 480 --depot 481
# Add a build description
boiler push ./build --desc "v1.2.0 release"
# Set a branch live after upload
boiler push ./build --set-live beta
# Preview VDF output without upload
boiler push ./build --dry-run
# Force all depots (skip changed-depot detection)
boiler push --all-depots
# Strict content hashing for change detection
boiler push --content-hash
# Download SteamCMD from Valve if needed
boiler push --install-steamcmdPush flags:
| Flag | Description |
| --- | --- |
| --app <id> | Steam App ID (overrides config) |
| --depot <id> | Steam Depot ID (overrides config) |
| --desc <text> | Build description shown in Steamworks |
| --set-live <branch> | Sets uploaded build live on a branch |
| --dry-run | Prints generated VDF without uploading |
| --all-depots | Uploads all configured depots |
| --content-hash | Uses strict content hashing (slower, safer) |
| --install-steamcmd | Downloads SteamCMD from Valve if it is missing |
Important behavior:
- If
--descis omitted, a timestamp-based description is generated. - Transient SteamCMD failures are retried up to 3 times with exponential backoff.
- Changed-depot detection uploads only depots with changes unless
--all-depotsis set. - Set
BOILER_CONTENT_HASH=1to enable strict content hashing by environment variable. - For multi-depot configs, folder override is blocked to prevent accidental wrong uploads.
boilerwill not auto-download SteamCMD unless you explicitly pass--install-steamcmd.
boiler status
boiler status
boiler status --jsonShows:
- depot mapping summary
- output/artifact paths
- SteamCMD path detection
- saved username
- cached login state
- last upload details
boiler doctor
boiler doctor
boiler doctor --json
boiler doctor --json --strictChecks:
- project config validity
- depot content roots
- SteamCMD availability
- saved username
- cached Steam login
boiler help [command]
boiler help
boiler help pushboiler (no args)
Running boiler with no args opens an interactive menu for login, init, push, status, and doctor.
Project Config (.boiler.json)
boiler init creates a .boiler.json like this:
{
"appId": 480,
"depots": [
{
"depotId": 481,
"contentRoot": "./build",
"fileMappings": [
{
"localPath": "*",
"depotPath": ".",
"recursive": true
}
],
"fileExclusions": ["*.pdb", "*.map", ".DS_Store", "Thumbs.db"]
}
],
"buildOutput": ".boiler-output",
"setLive": null
}Notes:
- This file is safe to commit.
buildOutputis where generated VDFs and upload artifacts are written.setLiveis used by default forpushunless overridden by--set-live.- Legacy configs with single
fileMappingare still read, but new configs should usefileMappings.
If a depot needs multiple Steam FileMapping entries:
{
"depotId": 481,
"contentRoot": "./build",
"fileMappings": [
{ "localPath": "*", "depotPath": ".", "recursive": true },
{ "localPath": "extras/*.dll", "depotPath": "./bin", "recursive": false }
],
"fileExclusions": ["*.pdb"]
}CI / Automation
Typical CI flow:
boiler doctor --json --strict
boiler login --non-interactive --install-steamcmd
boiler pushRecommended environment variables:
export BOILER_USERNAME=buildbot
export BOILER_PASSWORD=super-secret
export BOILER_NON_INTERACTIVE=1If Steam Guard code entry is required in CI:
export BOILER_GUARD_CODE=123456SteamCMD Behavior
boiler requires SteamCMD to upload builds.
If SteamCMD is not found, boiler stops by default and asks you to install it manually or rerun with --install-steamcmd. If SteamCMD is already installed, boiler checks your PATH, common install locations, and its own managed install directory.
Security
- Passwords are never stored by
boiler. - Only the Steam username is saved in global config.
- SteamCMD handles its own credential caching.
- For automation, use a dedicated Steam account instead of a personal account.
Global config location:
~/.boiler/config.jsonDevelopment
git clone https://github.com/your-username/boiler.git
cd boiler
npm install
npm run build
npm run dev -- --help
npm testLicense
MIT
