itch.io Publish (butler)
Get a build onto an itch.io page and keep it updated. The page is created in the browser; all
uploads go through butler, itch.io's command-line tool, with one command you'll use
forever: butler push. butler diffs against the previous build and uploads only what
changed. Deep CI/CD and flag detail lives in references/butler-ci.md.
When to use
- Use when creating/updating an itch.io project page, installing or logging in to butler,
uploading a build with
butler push, choosing channel names, versioning uploads, or
shipping a jam/demo/release build to itch.io.
- Triggers:
butler push, butler login, channels, .itch.toml, "publish on itch",
"upload to itch".
When not to use: publishing on Steam (use steam-publish); jam scope/planning (use
game-jam — this skill is only the upload mechanics); building the game itself (engine
skills).
Core workflow
- Create the project page at
itch.io/game/new. Set the Kind of project: keep
Downloadable for native builds, or choose HTML for a browser-playable game (this is
required for web builds — see Pitfalls). Set pricing/visibility (Draft until ready).
- Install butler and log in. Download from
itchio.itch.io/butler, add it to PATH,
then butler login (opens a browser to authorize). Verify with butler version. For
CI, use BUTLER_API_KEY instead — see the reference.
- Prepare a portable build folder — the exact files a player runs, nothing extra. Push a
folder (or a single
.zip of that folder), not an installer and not a
pre-compressed archive of archives (hurts patching; see Pitfalls).
- Push to a channel:
butler push <dir> <user>/<game>:<channel>. The channel name
determines the platform tag (see Patterns). The first push uploads everything; later
pushes to the same channel upload only the diff.
- Set platform/HTML tags on the Edit game page if a channel wasn't auto-tagged
correctly, then Save. For browser games also flip the page to HTML and tag the
channel playable in browser.
- Version your builds (optional but recommended):
--userversion 1.2.0 or
--userversion-file build.txt so you control the version string players and the update
API see.
- Update later by pushing to the same channel again. Use
butler status <user>/<game>
to see channels/builds and butler push-preview to see what a push would change before
sending it.
Patterns
1. The one command you need — butler push
# butler push <directory-or-zip> <user>/<game>:<channel>
butler push ./build/windows leafy/my-game:windows
butler push ./build/mac leafy/my-game:osx
butler push ./build/linux leafy/my-game:linux
butler push ./web leafy/my-game:html # browser build (also set page Kind = HTML)
2. Channel naming controls the platform tag (kebab-case, lowercase)
Substring in channel name -> auto-applied tag:
win / windows -> Windows linux -> Linux
mac / osx -> macOS android -> Android
Multiple platforms in one channel are allowed: e.g. a Java jar:
butler push ./jar leafy/my-game:win-linux-mac
Convention: lowercase words separated by dashes (windows-beta, osx-demo, soundtrack).
Tags are only the INITIAL guess — fix them anytime on the Edit game page (then Save).
3. Version, verify, and preview
butler version # print version; confirms install + PATH
butler login # authorize this machine (opens browser)
# Set an explicit version string instead of itch's auto-incrementing integer:
butler push ./build leafy/my-game:windows --userversion 1.2.0
butler push ./build leafy/my-game:windows --userversion-file build_number.txt
butler status leafy/my-game # list channels + latest builds/versions
butler push-preview ./build leafy/my-game:windows # NEW/MODIFIED/DELETED/SAME, uploads nothing
4. First-time, hidden, and filtered pushes
# Hide a brand-new channel from the page until you're ready (NEW channels only):
butler push ./build leafy/my-game:windows-beta --hidden
# Exclude files from the upload without copying the folder (--ignore is repeatable):
butler push ./build leafy/my-game:windows --ignore '*.pdb' --ignore '*.dSYM'
# Preview exactly what would be sent, without sending it:
butler push ./build leafy/my-game:windows --dry-run
Pitfalls
- Pushing an installer. itch.io patches portable builds; an installer (
.exe/.msi)
defeats patching and the itch app's auto-update, and may need admin rights players don't
have. Push the extracted, runnable folder instead.
- Pre-compressed builds. Pushing a heavily compressed archive (or an archive of archives)
makes patches huge — a tiny change rewrites the whole compressed blob. Push uncompressed
files; itch.io compresses on its side.
- A folder containing only one
.zip. butler auto-unzips it and pushes the contents
(to avoid a "zip in a zip"). Pass --no-auto-unzip only if you truly want the zip uploaded
as one opaque file.
- HTML5 game shows as a download. Two switches are required: set the page Kind to
HTML and tag the channel playable in browser on the Edit game page after the first
push — neither happens automatically from the channel name.
--hidden on an existing channel errors. It only applies when the push creates a new
channel. Unhide later from Edit game.
- Channel typos make duplicate slots.
windows and win-final are different channels and
create separate downloads. Decide your channel names up front and reuse them.
- 30 GB cap. itch.io rejects builds whose total uncompressed size exceeds 30 GB.
- Secrets in CI logs. A
BUTLER_API_KEY printed in a public log is compromised — revoke
it immediately on the API keys page. See the reference for safe CI usage.
References
- For CI/CD (GitHub Actions/GitLab) with
BUTLER_API_KEY, automated install via broth, the
full flag list, and the update-check API, read references/butler-ci.md.
- Primary docs: the butler manual —
itch.io/docs/butler (installing, login, pushing).
Related skills
steam-publish — the same game on Steam via SteamPipe (often shipped alongside itch.io).
game-jam — most jams are hosted on itch.io; this skill handles the upload step.
prototype-fast — share an early prototype on a Draft/restricted itch page for playtesting.
1---2name: itch-publish3description: Publish and update a game on itch.io: create the project page and upload builds with the butler CLI (butler push) to named channels. Use for itch.io publishing, butler push, channel naming for Windows/macOS/Linux/HTML5, versioning uploads, or shipping a jam or release build to itch.io.4---5
6# itch.io Publish (butler)
7
8Get a build onto an itch.io page and keep it updated. The page is created in the browser; all
9uploads go through **butler**, itch.io's command-line tool, with one command you'll use
10forever: `butler push`. butler diffs against the previous build and uploads only what
11changed. Deep CI/CD and flag detail lives in `references/butler-ci.md`.
12
13## When to use
14
15- Use when creating/updating an itch.io project page, installing or logging in to butler,
16 uploading a build with `butler push`, choosing channel names, versioning uploads, or
17 shipping a jam/demo/release build to itch.io.
18- Triggers: `butler push`, `butler login`, channels, `.itch.toml`, "publish on itch",
19 "upload to itch".
20
21**When *not* to use:** publishing on Steam (use `steam-publish`); jam *scope/planning* (use
22`game-jam` — this skill is only the upload mechanics); building the game itself (engine
23skills).
24
25## Core workflow
26
271. **Create the project page** at `itch.io/game/new`. Set the **Kind of project**: keep
28 *Downloadable* for native builds, or choose **HTML** for a browser-playable game (this is
29 required for web builds — see Pitfalls). Set pricing/visibility (Draft until ready).
302. **Install butler and log in.** Download from `itchio.itch.io/butler`, add it to `PATH`,
31 then `butler login` (opens a browser to authorize). Verify with `butler version`. For
32 CI, use `BUTLER_API_KEY` instead — see the reference.
333. **Prepare a portable build folder** — the exact files a player runs, nothing extra. Push a
34 **folder** (or a single `.zip` *of* that folder), **not an installer** and **not a
35 pre-compressed archive of archives** (hurts patching; see Pitfalls).
364. **Push to a channel:** `butler push <dir> <user>/<game>:<channel>`. The channel name
37 determines the platform tag (see Patterns). The first push uploads everything; later
38 pushes to the same channel upload only the diff.
395. **Set platform/HTML tags** on the *Edit game* page if a channel wasn't auto-tagged
40 correctly, then **Save**. For browser games also flip the page to **HTML** and tag the
41 channel *playable in browser*.
426. **Version your builds** (optional but recommended): `--userversion 1.2.0` or
43 `--userversion-file build.txt` so you control the version string players and the update
44 API see.
457. **Update later** by pushing to the *same* channel again. Use `butler status <user>/<game>`
46 to see channels/builds and `butler push-preview` to see what a push would change before
47 sending it.
48
49## Patterns
50
51### 1. The one command you need — `butler push`
52
53```bash
54# butler push <directory-or-zip> <user>/<game>:<channel>
55butler push ./build/windows leafy/my-game:windows
56butler push ./build/mac leafy/my-game:osx
57butler push ./build/linux leafy/my-game:linux
58butler push ./web leafy/my-game:html # browser build (also set page Kind = HTML)
59```
60
61### 2. Channel naming controls the platform tag (kebab-case, lowercase)
62
63```text
64Substring in channel name -> auto-applied tag:
65 win / windows -> Windows linux -> Linux
66 mac / osx -> macOS android -> Android
67Multiple platforms in one channel are allowed: e.g. a Java jar:
68 butler push ./jar leafy/my-game:win-linux-mac
69Convention: lowercase words separated by dashes (windows-beta, osx-demo, soundtrack).
70Tags are only the INITIAL guess — fix them anytime on the Edit game page (then Save).
71```
72
73### 3. Version, verify, and preview
74
75```bash
76butler version # print version; confirms install + PATH
77butler login # authorize this machine (opens browser)
78
79# Set an explicit version string instead of itch's auto-incrementing integer:
80butler push ./build leafy/my-game:windows --userversion 1.2.0
81butler push ./build leafy/my-game:windows --userversion-file build_number.txt
82
83butler status leafy/my-game # list channels + latest builds/versions
84butler push-preview ./build leafy/my-game:windows # NEW/MODIFIED/DELETED/SAME, uploads nothing
85```
86
87### 4. First-time, hidden, and filtered pushes
88
89```bash
90# Hide a brand-new channel from the page until you're ready (NEW channels only):
91butler push ./build leafy/my-game:windows-beta --hidden
92
93# Exclude files from the upload without copying the folder (--ignore is repeatable):
94butler push ./build leafy/my-game:windows --ignore '*.pdb' --ignore '*.dSYM'
95
96# Preview exactly what would be sent, without sending it:
97butler push ./build leafy/my-game:windows --dry-run
98```
99
100## Pitfalls
101
102- **Pushing an installer.** itch.io patches *portable* builds; an installer (`.exe`/`.msi`)
103 defeats patching and the itch app's auto-update, and may need admin rights players don't
104 have. Push the extracted, runnable folder instead.
105- **Pre-compressed builds.** Pushing a heavily compressed archive (or an archive of archives)
106 makes patches huge — a tiny change rewrites the whole compressed blob. Push uncompressed
107 files; itch.io compresses on its side.
108- **A folder containing only one `.zip`.** butler auto-unzips it and pushes the contents
109 (to avoid a "zip in a zip"). Pass `--no-auto-unzip` only if you truly want the zip uploaded
110 as one opaque file.
111- **HTML5 game shows as a download.** Two switches are required: set the page **Kind** to
112 *HTML* and tag the channel *playable in browser* on the *Edit game* page after the first
113 push — neither happens automatically from the channel name.
114- **`--hidden` on an existing channel errors.** It only applies when the push *creates* a new
115 channel. Unhide later from *Edit game*.
116- **Channel typos make duplicate slots.** `windows` and `win-final` are different channels and
117 create separate downloads. Decide your channel names up front and reuse them.
118- **30 GB cap.** itch.io rejects builds whose total *uncompressed* size exceeds 30 GB.
119- **Secrets in CI logs.** A `BUTLER_API_KEY` printed in a public log is compromised — revoke
120 it immediately on the API keys page. See the reference for safe CI usage.
121
122## References
123
124- For CI/CD (GitHub Actions/GitLab) with `BUTLER_API_KEY`, automated install via `broth`, the
125 full flag list, and the update-check API, read `references/butler-ci.md`.
126- Primary docs: the butler manual — `itch.io/docs/butler` (installing, login, pushing).
127
128## Related skills
129
130- `steam-publish` — the same game on Steam via SteamPipe (often shipped alongside itch.io).
131- `game-jam` — most jams are hosted on itch.io; this skill handles the upload step.
132- `prototype-fast` — share an early prototype on a Draft/restricted itch page for playtesting.