Skip to content

ARCHITECTURE · 25

Migrating from Tebako v1.

Tebako v2 is a re-architecture, not a patch release. The C++/CMake era is archived; the platform is Rust, the runtime is a small artifact set (exe + env image, plus the ruby DLL on windows), and payloads are self-describing slices. This page is the map from there to here.

Note

Status: shipped — ships today: the CLI on the 0.2.x line, ruby runtimes on the 0.16.x line; the migration path below is live.

The short version.

If you run tebako packages: uninstall the gem-era tooling, install the v2 CLI, and keep working. Packages pressed with v1 must be re-pressed — v1 embedded images do not load in v2.

If you press packages: your workflow no longer needs CMake, compilers, or system libraries on the packager’s machine. The packaging tools arrive as binaries.

If you pinned a Ruby version: the pin becomes a runtime constraint in the payload manifest (runtime_requirement: ruby "~> 3.3.0"). Runtimes download once and are shared by every package on the machine.

What changed, in one table.

Area v1 (archived) v2 (current)

Implementation

C++ (tebako-main, libtfs) + the tebako gem

Rust end to end (bootstrap, shim, driver, tfs, tpkg, CLI)

Runtime

one merged environment+app image, embedded

interpreter exe + separate env image; shared, downloaded once

Payloads

opaque embedded images

self-describing slices (/tpkg/manifest.yaml), co-mounted

Packaging tools

compiled on your machine (CMake + system libs)

prebuilt binaries per platform

Distribution

one fat binary only

fat/lean binaries and the managed store (registries, shims, version manager)

Native tools

not supported

zero-runtime payloads (Inkscape, JRE, hello) as first-class slices

The command map.

v1 (gem) v2 Notes

gem install tebako

brew install tamatebako/tap/tebako

prebuilt per platform; no compilers

tebako press … (the gem)

tebako press … (the Rust CLI)

same verb, prebuilt binary; lean/fat — classic mode is gone

— (no install verb)

tebako add-registry … && tebako install …

the managed flow: registries, store, shims

RUBY VERSION pin

runtime_requirement: ruby "~> 3.3.0"

in the payload manifest; the dispatcher resolves it

The steps, in order.

  1. Remove the gem-era install. gem uninstall tebako and drop any v1 build trees. The v1 repo is archived at tamatebako/tebako-v1 — read-only reference, no new development.

  2. Install the v2 CLI. brew install tamatebako/tap/tebako (or the per-platform release asset from tamatebako/tebako).

  3. Re-press your payloads. v1 images do not load in v2. For a Ruby app: declare the runtime constraint in the manifest, press with tebako press (lean or fat), and either ship the stitched executable or publish the payload to a registry for the managed flow. Data and toolkit slices are built with tfs mkimage.

  4. First run downloads the runtime once. It lands in ~/.tebako/runtimes/, SHA-256 verified, shared by every tebako package on the machine. Subsequent runs are silent cache hits; TEBAKO_OFFLINE=1 makes that explicit.

Worth knowing.

  • The env image is not your app. v1 merged them; v2 never does. The runtime’s env image is the interpreter’s stdlib and gems — your app is a separate payload slice mounted over it.

  • Native tools are slices now. If your app shells out to a binary (Inkscape, a JRE, ffmpeg), package it as a toolkit payload and declare it in requires: with a mount point. Your users stop installing it by hand.

  • A run never installs. Executing a package reads and runs only; tebako install is the explicit verb that populates the store and registers shims.

  • Unsigned is first-class, loud. Unsigned payloads install with a warning and a journal line; TEBAKO_REQUIRE_SIGNED=1 fails closed. Signing is opt-in per package.

See also: The deep migration guide — the press flag map, lean versus fat packages, verified CI before/afters, and the behavior differences that bite.