6 releases (3 stable)
Uses new Rust 2024
| 1.1.0 | Mar 9, 2026 |
|---|---|
| 1.0.1 | Mar 8, 2026 |
| 0.4.0 | Mar 8, 2026 |
| 0.3.0 | Mar 8, 2026 |
| 0.2.0 | Mar 8, 2026 |
#48 in Operating systems
90KB
2.5K
SLoC
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,cleancommands- 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
7zcurltar- 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_DIRor default cache root)--tools: remove project-local tools directory (<project>/.tortia-toolsby 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>orpython/python@latestgo@<version>(default:1.22.12)deno@<version>ordeno/deno@latestbun@<version>orbun/bun@latest
Package Manager Integration
Supported package managers in [package_managers].items:
npm,pnpm,yarnpip,uvcargo,go,deno,bun
Behavior:
- Required runtimes are auto-added if missing.
- Example:
package_managers = ["npm"]auto-adds Node runtime.
- Example:
pnpm/yarnare prepared viacorepack.pipanduvwrappers are provided inside the isolated environment.
Auto Dependency Install
If auto_install = true, tortia build attempts dependency install automatically:
npm:npm ci(ifpackage-lock.json), elsenpm installpnpm:pnpm install --frozen-lockfile(if lockfile), elsepnpm installyarn:yarn install --immutable || yarn install --frozen-lockfile || yarn install(if lockfile), elseyarn installbun:bun install(ifpackage.json)uv:uv sync(ifpyproject.toml) oruv pip install -r requirements.txtpip:pip install -r requirements.txtorpip install .(ifpyproject.toml)cargo:cargo fetch(ifCargo.toml)go:go mod download(ifgo.mod)deno: currently only prepares runtime/manager; use explicit[deps].commandfor 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 = trueskips packages already installeduse_sudo = trueruns install/update commands withsudo
Notes:
aptusesapt-getpacmanuses 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:
dirsare searched in order- Script references are relative paths
- If no extension is provided in a reference,
.shis also tried
Events:
before_deps,after_depsbefore_build,after_buildbefore_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_EVENTTORTIA_PROJECT_ROOTTORTIA_STAGE_ROOT
Isolation Model
tortia runs hooks ([deps], [build]) and [run].command in an isolated environment:
PATHis 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.tomlwith run metadata
Paths and Overrides
Tool directory inside build/run payload:
- default:
.tortia-tools - override: set
TORTIA_TOOLS_DIRto a relative directory name/path
Global cache directory:
- override:
TORTIA_CACHE_DIR - defaults:
- Linux/macOS:
$XDG_CACHE_HOME/tortiaor$HOME/.cache/tortia - Windows:
%LOCALAPPDATA%\\tortia\\cache - fallback: OS temp directory (
.../tortia-cache)
- Linux/macOS:
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.
- Add corresponding runtime in
- 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 --cacheto fully reset cached downloads.
- Tortia now reuses runtime download cache in
Security Note
[deps].command, [build].command, and [run].command execute shell commands. Treat RecipeFile as code.
Dependencies
~1.3–2.1MB
~41K SLoC