tortia-1.1.0 is not a library.

Tortia

tortia packages and runs applications in an isolated, non-virtualized execution environment.

It creates a single .tortia archive (7z format) that contains:

  • your project files
  • requested runtimes (for example Node, Rust, Python)
  • optional package manager setup
  • a run manifest

Then tortia run extracts and executes the archive with an isolated PATH.

Features

  • init, build, run, clean commands
  • Colorful logs (STEP, INFO, OK, ERROR)
  • Runtime auto-install during build
  • Package manager integration and optional auto dependency install
  • Host system package manager integration (brew, apt, pacman)
  • User extensions (plugin-style event scripts)
  • Runtime/command blocking via shims when not requested
  • Download cache reuse for runtime installers and archives
  • No VM/container runtime required

Requirements

  • macOS or Linux
  • 7z
  • curl
  • tar
  • POSIX sh

Notes:

  • Runtime downloads require network access at build time.
  • Runtime installation support is currently implemented for macOS/Linux on x86_64/aarch64.

Install / Build

cargo install tortia

CLI

tortia init [dir] [--force] [--] [args]
tortia build [dir] [-o|--output <path>]
tortia run <archive.tortia>
tortia clean [dir] [--temp] [--cache] [--tools] [--all] [--dry-run]

Cleanup

tortia clean removes leftovers from failed/interrupted runs and build caches.

Examples:

# default: clean stale temp dirs (tortia-build-*, tortia-run-*)
tortia clean

# preview only
tortia clean --all --dry-run

# remove global download cache only
tortia clean --cache

# remove project-local tools dir only
tortia clean . --tools

Flags:

  • --temp: remove stale temp dirs from the OS temp directory
  • --cache: remove global Tortia cache (TORTIA_CACHE_DIR or default cache root)
  • --tools: remove project-local tools directory (<project>/.tortia-tools by default)
  • --all: enable --temp, --cache, and --tools
  • --dry-run: print targets without deleting them

Quick Start

# 1) Create template config
tortia init .

# 2) Edit RecipeFile

# 3) Build archive

tortia build .

# 4) Run archive
tortia run ./my-app.tortia

Minimal Examples

Each example is intentionally minimal and runnable with only tortia.

Node.js

index.js

console.log("hello from node in tortia");

RecipeFile

[project]
name = "node-min"

[runtimes]
items = ["node@22.14.0"]

[package_managers]
items = ["npm"]
auto_install = false

[deps]
command = ""

[build]
command = ""

[run]
command = "node index.js"

[bundle]
include = ["index.js"]
exclude = []

Build and run:

tortia build .
tortia run ./node-min.tortia

Python

main.py

print("hello from python in tortia")

RecipeFile

[project]
name = "python-min"

[runtimes]
items = ["python@3.12"]

[package_managers]
items = ["pip"]
auto_install = false

[deps]
command = ""

[build]
command = ""

[run]
command = "python main.py"

[bundle]
include = ["main.py"]
exclude = []

Build and run:

tortia build .
tortia run ./python-min.tortia

Rust

Cargo.toml

[package]
name = "rust-min"
version = "0.1.0"
edition = "2021"

src/main.rs

fn main() {
    println!("hello from rust in tortia");
}

RecipeFile

[project]
name = "rust-min"

[runtimes]
items = ["rust@stable"]

[package_managers]
items = ["cargo"]
auto_install = false

[deps]
command = ""

[build]
command = "cargo build --release"

[run]
command = "./target/release/rust-min"

[bundle]
include = ["Cargo.toml", "src"]
exclude = []

Build and run:

tortia build .
tortia run ./rust-min.tortia

RecipeFile

tortia reads configuration from RecipeFile in the project root.

[project]
name = "my-app"

[runtimes]
items = ["node@22.14.0", "rust@stable", "python@3.12", "go@1.22.12", "deno@2.2.5", "bun@1.2.5"]

[package_managers]
items = ["npm", "pnpm", "pip", "uv", "cargo", "go", "deno", "bun"]
auto_install = true

[system_packages]
items = ["brew:wget"] # also supports apt:<pkg>, pacman:<pkg>
auto_install = false
use_sudo = false
update = false
missing_only = true

[extensions]
dirs = ["extensions"]
before_deps = []
after_deps = []
before_build = []
after_build = []
before_run = []
after_run = []

[deps]
command = ""

[build]
command = ""

[run]
command = "node app/index.js"

[bundle]
include = ["."]
exclude = [".git", "target"]

Runtime Support

Supported runtimes in [runtimes].items:

  • node@<version> (default: 22.14.0)
  • rust@<toolchain> (default: stable)
  • python@<version> or python/python@latest
  • go@<version> (default: 1.22.12)
  • deno@<version> or deno/deno@latest
  • bun@<version> or bun/bun@latest

Package Manager Integration

Supported package managers in [package_managers].items:

  • npm, pnpm, yarn
  • pip, uv
  • cargo, go, deno, bun

Behavior:

  • Required runtimes are auto-added if missing.
    • Example: package_managers = ["npm"] auto-adds Node runtime.
  • pnpm/yarn are prepared via corepack.
  • pip and uv wrappers are provided inside the isolated environment.

Auto Dependency Install

If auto_install = true, tortia build attempts dependency install automatically:

  • npm: npm ci (if package-lock.json), else npm install
  • pnpm: pnpm install --frozen-lockfile (if lockfile), else pnpm install
  • yarn: yarn install --immutable || yarn install --frozen-lockfile || yarn install (if lockfile), else yarn install
  • bun: bun install (if package.json)
  • uv: uv sync (if pyproject.toml) or uv pip install -r requirements.txt
  • pip: pip install -r requirements.txt or pip install . (if pyproject.toml)
  • cargo: cargo fetch (if Cargo.toml)
  • go: go mod download (if go.mod)
  • deno: currently only prepares runtime/manager; use explicit [deps].command for custom prefetch

Host System Packages

tortia can optionally install host-level system packages during build.

Configuration:

[system_packages]
items = ["brew:cmake", "apt:libssl-dev", "pacman:openssl"]
auto_install = true
use_sudo = true
update = true
missing_only = true

Behavior:

  • Supported managers: brew, apt, pacman
  • Entry format: <manager>:<package>
  • Install runs on the host (not inside archive)
  • missing_only = true skips packages already installed
  • use_sudo = true runs install/update commands with sudo

Notes:

  • apt uses apt-get
  • pacman uses non-interactive flags (--noconfirm)
  • If a manager is not installed on the host, build fails with an explicit error

Extensions (Plugins)

tortia supports user-defined extension scripts triggered at lifecycle events.

Configuration:

[extensions]
dirs = [".tortia/extensions", "extensions"]
before_deps = ["prepare-env"]
after_deps = []
before_build = ["gen-assets.sh"]
after_build = []
before_run = ["preflight"]
after_run = ["cleanup"]

Resolution rules:

  • dirs are searched in order
  • Script references are relative paths
  • If no extension is provided in a reference, .sh is also tried

Events:

  • before_deps, after_deps
  • before_build, after_build
  • before_run, after_run

Runtime behavior:

  • Build events search scripts from your project root
  • Run events search scripts from extracted archive contents
  • Scripts execute with:
    • TORTIA_EVENT
    • TORTIA_PROJECT_ROOT
    • TORTIA_STAGE_ROOT

Isolation Model

tortia runs hooks ([deps], [build]) and [run].command in an isolated environment:

  • PATH is rebuilt from archive-internal tool paths + system base path
  • non-requested runtime commands are blocked by shim executables
  • host user-level runtime paths are not used by default

This means a runtime not declared in RecipeFile should not be available inside tortia run.

Archive Contents

A .tortia archive includes:

  • bundled project files from [bundle].include
  • tool directories (for installed runtimes/package managers)
  • .tortia-manifest.toml with run metadata

Paths and Overrides

Tool directory inside build/run payload:

  • default: .tortia-tools
  • override: set TORTIA_TOOLS_DIR to a relative directory name/path

Global cache directory:

  • override: TORTIA_CACHE_DIR
  • defaults:
    • Linux/macOS: $XDG_CACHE_HOME/tortia or $HOME/.cache/tortia
    • Windows: %LOCALAPPDATA%\\tortia\\cache
    • fallback: OS temp directory (.../tortia-cache)

Runtime download cache path:

  • <cache-root>/downloads

Troubleshooting

  • could not resolve host ...
    • Build needs network to download runtimes/tools.
  • command ... is blocked in this isolated environment
    • Add corresponding runtime in [runtimes].items.
  • Large archive size
    • Python (Miniconda) can significantly increase archive size.
  • Slow repeated builds
    • Tortia now reuses runtime download cache in <cache-root>/downloads.
    • Use tortia clean --cache to fully reset cached downloads.

Security Note

[deps].command, [build].command, and [run].command execute shell commands. Treat RecipeFile as code.