CLI reference
banto is the only command you need to install. It scaffolds a project,
compiles your .banto files, formats them, manages your image/audio
assets, and publishes your game to banto.tv.
If you’ve never used it, start with Getting started; this doc is the keep-it-open-while-you-work reference.
Install
npm install -g @bantohq/cli
banto --help
You should see the subcommands: init, build, fmt, auth,
publish, and assets.
You can also install per-project (npm install --save-dev @bantohq/cli)
and invoke as npx banto ….
Get the editor extension too. The Banto DSL VS Code extension gives you syntax highlighting, inline diagnostics, and completions as you type — it’s the fastest way to catch mistakes before you build. See Getting started → the extension.
The workflow at a glance
Your game runs on banto.tv, but you can test it without real phones using the sandbox. The loop is:
- Write
.bantofiles (the editor extension flags errors live). banto buildto typecheck and catch anything the editor missed.banto publish— publish as a private game ("public": false) while you iterate.banto sandbox— open the owner-only sandbox: the host screen plus simulated player windows in one browser, no phones needed.- Edit, re-
publish(it updates in place), reload the sandbox, repeat. Host it live on banto.tv from a few phones/tabs for a real multi-device round, and flip"public": trueto list it.
Subcommands
banto init <dir>
Scaffolds a new project at ./<dir>. The directory must not already
exist (or must be empty). The starter is the empty lobby template:
host shows the room code with a kick list, players see a “you’re in”
message.
banto init my-game
Files created:
my-game/
├── globals.banto
├── start.banto
├── styles.banto.css
├── banto.config.json
└── .gitignore
banto build
Compiles the project to a single game.json IR file at the project
root. Run it from anywhere inside the project — the CLI walks up
until it finds globals.banto.
banto build # quiet
banto build --verbose # print per-file progress
Output on success:
Wrote ./game.json (487 bytes, 0 error(s), 0 warning(s)).
On a syntax/type error, you get the same diagnostics your editor shows, then a non-zero exit code:
start.banto:14:17 error [banto.cstate-write-interleaved]: …
Compilation aborted: 1 error(s), 0 warning(s).
game.json is a build artifact — keep it out of version control
(the starter’s .gitignore already does this). banto publish builds
for you, so you rarely need to run build by hand except to verify a
change compiles.
banto fmt [path]
Formats .banto files in place using the canonical formatter — the
same output as Format Document in the editor.
banto fmt # format every .banto file under the current dir
banto fmt start.banto # format a single file
banto fmt --check # report unformatted files, exit 1 if any (CI-friendly)
| Option | What it does |
|---|---|
-c, --check | Don’t rewrite anything — just list files that aren’t formatted and exit 1 if there are any. |
path may be a file or a directory (defaults to .).
banto auth
Logs you into banto.tv using a browser-based loopback flow:
- The CLI starts a tiny local web server.
- It opens your browser to a banto.tv consent page.
- You approve, banto.tv redirects to
localhost, and the CLI captures the token.
banto auth
You only need to run this explicitly the first time. banto publish
and banto assets will trigger the same flow automatically if your
token is missing or expired.
banto publish
Compiles your project and ships it to banto.tv. The settings in
banto.config.json (title, description, default datasets) become
your game’s listing.
banto publish
Re-running banto publish after edits updates the existing game in
place — same ID, no duplicate listing. The CLI uses
banto.lock.json (sibling of banto.config.json) to remember which
remote game your project is bound to.
Publish with "public": false while you iterate — the game is
reachable only by you (and anyone you send a direct link) so you can
host and playtest it privately. Set "public": true to list it in the
public catalog.
Publishing is admin-gated on banto.tv by default. If you get a 403, your account doesn’t have publishing permissions.
banto sandbox
Opens the sandbox for your currently-published game in the browser — an owner-only test harness that runs the real game with the host screen and simulated player windows side by side, so you can play a full round without real phones.
banto sandbox # default layout (host + 2 player windows)
banto sandbox -t 3 # a different layout preset
-t, --template <0-3>picks a layout preset (how many player windows to tile); defaults to2. Use + Add player in the UI to add or drop players live.- The sandbox opens the published build, so run
banto publishfirst (and again after each change, then reload). - It’s owner-gated — the browser must be signed in to banto.tv as
the project’s owner (the account from
banto auth). - Click the Inspector button (top-right) for a live view of every
var.*and state-param, the datasets, each window’scstate, and a Logs panel showing yourfunc.log(...)output and any runtime errors.
banto assets
Manage the custom image/audio assets your game renders with
cpnt.image, cpnt.audio, or client.playSound. Drop media files in
an assets/ directory at your project root; reference them from
.banto as asst.<name> (the file’s base name, no extension). See
Custom image & audio assets
for the language side.
banto assets push # upload new/changed files from ./assets
banto assets ls # list this project's assets + moderation state
banto assets rm <name|id># delete an owned asset (by base name or id)
banto assets catalog # open the public asset catalog in your browser
| Subcommand | What it does |
|---|---|
push [dir] | Uploads new or changed files from ./assets (or dir) to your account, records their ids in banto.lock.json, and reconciles moderation status. |
ls | Lists each asset with its kind, moderation status, and id. |
rm <name|id> | Deletes one of your assets from the server and the lock file. |
catalog | Opens the shared, admin-approved asset catalog on banto.tv. |
Titles come from an assets map in banto.config.json, keyed by the
file’s base name:
{
"assets": {
"logo": { "title": "Game logo" },
"victory-fanfare": { "title": "Victory fanfare" }
}
}
Moderation. Uploaded assets start pending and are visible only in your own games until an admin approves them.
asst.<name>references still build and render for you while pending — approval just makes the asset usable by others and listable in the catalog.
Config files
banto.config.json (per project)
How your game appears on banto.tv. Lives next to globals.banto.
{
"title": "Grant's Trivia Tournament",
"description": "It's like Trivia, but as a tournament!",
"public": false,
"default": {
"questionSet": "this"
},
"new": {
"questionSet": [
{
"prompt": "Which of these are programming languages?",
"options": ["Python", "HTML", "JavaScript", "HTTP"],
"correctOptions": [0, 2]
}
]
},
"assets": {
"logo": { "title": "Game logo" }
}
}
| Field | What it does |
|---|---|
title | Display name on the banto.tv listing. |
description | Short blurb on the listing page. |
public | false = only you and people with a direct link can find it. true = listed in the public catalog. |
default.* | For each data block your project declares (questionSet, promptSet, or dynamic), the data source pre-selected when a host starts a game. Use a banto.tv data-source ID, or the literal "this" to point at the matching new.* entry. |
new.* | Inline contents of a fresh data source to create on banto.tv as part of publishing. Shape matches the data block: questions for questionSet, strings for promptSet, or a (string | number | (string | number | (string | number)[])[])[] list for dynamic. |
assets.* | Titles for your custom assets, keyed by the media file’s base name. Used by banto assets push. |
Where credentials live
banto auth saves your bearer token outside the project, scoped to
your OS user:
| OS | Path |
|---|---|
| Linux / macOS | ~/.config/banto/ |
| Windows | %APPDATA%\banto\ |
The folder holds credentials.json — your bearer token. Treat it like
a password. You don’t normally need to edit it by hand; banto auth
writes it for you.
banto.lock.json (next to banto.config.json, in your project) is
different: it remembers which remote game and assets this project is
bound to. Commit it — it’s how re-publishing updates in place instead
of creating a duplicate.
Troubleshooting
| Symptom | Fix |
|---|---|
banto build says “no globals.banto found in this directory or any parent” | You’re not inside a Banto project. cd into one or run banto init <name>. |
banto build reports unknown-asset | You referenced asst.<name> for a file you haven’t pushed yet. Run banto assets push, or check the base name matches a file in assets/. |
banto publish returns 403 | Your account isn’t allowed to publish. Publishing is admin-gated by default. |
banto init says “target is not empty” | Pick a different name, or move the existing files out. There’s no --force flag. |
| The browser-opened consent page errors out | Re-run banto auth. The loopback listener uses a random port and the previous attempt’s port may have been blocked. |