Tibi

CLI

Every tibi subcommand the binary currently ships, with examples.

tibi (no args)

$ tibi tibi 0.1.0 runtime ABI: 1 release pubkey: RWSXEThYUQGbMjdahUrZw055j7dSBFOtopLXD+z4uh6PW4zl8O69Q8eo (id 329B015158381197)

Same output as tibi about. Use for support reports.

tibi new <name>

$ tibi new my-app Created Tibi project at /path/to/my-app …

Scaffolds .tibi-config, .gitignore, package.json, and pages/_layout.tibi / pages/index.tibi / pages/_404.tibi. No Cargo.toml, no src/main.rs, no Dockerfile. The bundled tibi binary boots the app from the config alone; tibi build produces a static dist/ that deploys to any host. The package.json's preinstall hook installs tibi automatically on PaaS platforms that run npm install. Fails if the target directory already exists.

tibi routes [path]

$ tibi routes pages scanned 5 route(s) from pages: / -> pages/index.tibi /about -> pages/about.tibi /blog -> pages/blog/index.tibi /blog/{slug} -> pages/blog/[slug].tibi (404 fallback) -> pages/_404.tibi

Prints the URL → file map. Defaults to ./pages.

tibi check [path]

Parses every .tibi file in pages/ + every layout. Exits non-zero with the failing files on parse / component-resolution errors. Useful in pre-commit hooks.

tibi build [--pages path] [--dist path]

$ tibi build --pages pages --dist dist built 3 page(s) into dist + / -> dist/index.html (12029 bytes) + /about -> dist/about/index.html (8223 bytes) + /blog -> dist/blog/index.html (8408 bytes) - skipped /blog/{slug} - skipped notfound

Writes one HTML file per static route via tibi_ssg::build_site. Dynamic routes and _404 / _500 are reported as skipped.

tibi serve [--config <path>]

$ tibi serve tibi: loaded config from /path/to/my-app/.tibi-config tibi: 2 routes from /path/to/my-app/pages / -> pages/index.tibi (404 fallback) -> pages/_404.tibi tibi-serve listening on http://0.0.0.0:9017

Discovers .tibi-config from the current working directory upwards (or takes an explicit path via --config) and runs the no-Rust path: pages scanned from pages_dir, server bound to [server] host + port, every component-declared channel (__channels in their frontmatter) spawned, downloads_dir mounted at /downloads/* AND at the URL root with Content-Disposition: attachment (browsers download instead of rendering), and public_dir mounted at the URL root for inline assets (favicons, logos, fonts). Public wins on filename collisions.

tibi dev

$ tibi dev tibi dev: serving via .tibi-config at /path/to/my-app/.tibi-config with TIBI_DEV=1 … dev: watching pages

Re-execs tibi serve with TIBI_DEV=1 set so the app spawns the file watcher; saves to any .tibi file push "reload" on the hmr WebSocket channel and the browser refreshes. Same config discovery as serve.

tibi plugin <cmd>

$ tibi plugin search # list every plugin in the marketplace $ tibi plugin show tailwind # readme + versions + install steps $ tibi plugin add tailwind # patches .tibi-config plugins=[…] $ tibi plugin list # what's declared in this project $ tibi plugin remove tailwind # reverse of add $ tibi plugin compile # pre-compile Rust plugins to dist/plugins-bin/ $ tibi plugin new my-widgets # scaffold a packaged-plugin source tree (manifest + components/Sample.tibi) $ tibi plugin pack ./my-widgets # writes dist/plugins/my-widgets/{tibi-plugin.toml, tibi-plugin.tpkg} # copy that pair into a target project's plugins/my-widgets/ to install

Marketplace front-end + Rust plugin pre-compile pass + packaged-plugin scaffolder. compile walks [server] plugins_dir, builds every *.rs source via rustc -O into dist/plugins-bin/<name>-<sha8>, and the runtime loader picks those up first. new drops a ready-to-edit source tree (omit the name to be prompted; --prefix Xy changes the tag namespace, default Ti). pack turns that tree into the verified two-file bundle the runtime accepts. Sharing the resulting pair is manual today -- no central submission path exists yet. See Plugins for the full lifecycle + binary search order.

Override the marketplace source with TIBI_MARKETPLACE_URL — must be an http(s):// endpoint serving the same JSON shape. Local file:// / relative-path forms were removed in v0.2.13 because a leaked env var turned the CLI into an arbitrary-file-read primitive; serve local mirrors over loopback HTTP instead.

tibi deploy cf-pages [--project name] [--branch name] [--dist path] [--skip-build]

$ tibi deploy cf-pages --project my-app deploying dist → cloudflare pages project 'my-app' ⛅️ wrangler 3.x.y …

Wraps tibi build + wrangler pages deploy dist/ --project-name <name>. Requires wrangler on PATH (install via npm install -g wrangler; or use npx wrangler directly if you'd rather not install globally). Tibi never touches CF credentials — wrangler owns auth via its own wrangler login flow. Missing wrangler surfaces a friendly install hint rather than a raw OS error.

Drop the per-invocation flags by setting them in .tibi-config:

[deploy.cloudflare_pages] project = "my-app" branch = "preview" # optional

CLI flags always win over config values. Use --skip-build when CI already produced dist/ in a previous stage; --dist overrides the upload directory. See Deploy for the full Cloudflare Pages walkthrough plus the SSR / container alternative.

tibi update [--version <channel>]

$ tibi update tibi update: fetching https://tibi.fi/install.sh (channel: main) tibi-install: downloading https://tibi.fi/downloads/tibi-cli/main/tibi-cli-linux-x86_64.tar.gz tibi-install: installed to /home/…/.local/bin/{tibi,cargo-tibi} tibi update: done. Run `tibi --version` to confirm.

Re-runs the official install script from tibi.fi so the update path matches a fresh install exactly — fetches the pre-built tarball, drops tibi + cargo-tibi into ~/.local/bin. No local compile.

On Windows the same command fetches install.ps1 and runs it through PowerShell instead — the zip lands in %LOCALAPPDATA%\Programs\tibi, and the installer renames the running tibi.exe aside before dropping the new one in, so updating from the binary being replaced just works.

Channels:

  • tibi update — tracks main (stable).
  • tibi update --version staging — swap to the staging tarball for previewing unreleased changes.

Override the release host with TIBI_RELEASE_HOST (handy for self-hosted mirrors or local-testing the install flow).

Background version check

Every tibi invocation (except tibi update itself) checks the release channel's VERSION file on tibi.fi for a newer build. The check is cached for 24h at $XDG_CACHE_HOME/tibi/version-check (or ~/.cache/tibi/version-check / %LOCALAPPDATA%\tibi\version-check), and the refresh runs in a detached background thread, so it never blocks the current command.

When a newer version is found and stderr is a TTY, a one-line hint is printed:

tibi: new version available: 0.2.0 (you have 0.1.0). Run `tibi update` to upgrade, or set TIBI_NO_UPDATE_CHECK=1 to silence.

It never auto-updates — you stay in control of when to run tibi update. Set TIBI_NO_UPDATE_CHECK=1 to disable the nag entirely (handy for shared images / CI).

cargo tibi <cmd>

If you'd rather invoke through cargo, install cargo-tibi and run cargo tibi <cmd>. The shim drops the leading tibi arg and execs the colocated tibi binary.