truss

Resize, crop, convert, optimize, blur, sharpen, and watermark images from the CLI, an HTTP server, or the browser -- written in Rust with signed-URL authentication and SSRF protection built in.
Try the WASM demo in your browser -- no install, no upload, runs 100 % client-side.

Why truss?
- One binary, three interfaces -- the same Rust core powers the CLI, an HTTP image-transform server, and a WASM browser demo.
- Security by default -- signed URLs, SSRF protections, and SVG sanitization are built in.
- Broad format support -- JPEG, PNG, WebP, AVIF, BMP, and SVG; retains EXIF, ICC, and XMP metadata where possible.
- Cross-platform -- Linux, macOS, Windows.
- Tested contracts -- CLI behavior is locked by ShellSpec, HTTP API by runn.
Comparison
Feature comparison with imgproxy and imagor as of March 2026.
| Feature | truss | imgproxy | imagor |
|---|---|---|---|
| Language | Rust | Go | Go |
| Runtime dependencies | None | libvips (C) | libvips (C) |
| CLI | Yes | No | No |
| WASM browser demo | Yes | No | No |
| Signed URLs | Yes | Yes | Yes |
| JPEG / PNG / WebP / AVIF | Yes | Yes | Yes |
| JPEG XL (JXL) | No | Input only | Yes |
| TIFF | Yes | Yes | Yes |
| GIF animation processing | No (out of scope) | Yes | Yes |
| SVG sanitization | Yes | Yes | No |
| Smart crop | No | Yes | Yes |
| Sharpen filter | Yes | Yes | Yes |
| Crop / Trim / Padding | Yes | Yes | Yes |
| S3 | Yes | Yes | Yes |
| GCS | Yes | Yes | Yes |
| Azure Blob Storage | Yes | Yes | No |
| Watermark | Yes | Yes | Yes |
| Prometheus metrics | Yes | Yes | Yes |
| License | MIT | Apache 2.0 | Apache 2.0 |
Architecture
flowchart TB
CLI["CLI<br/>(truss convert)"] --> Core
Server["HTTP Server<br/>(truss serve)"] --> Core
WASM["WASM<br/>(browser)"] --> Core
subgraph Core["Shared Rust core"]
direction LR
Sniff["Detect format"] --> Transform["Crop / resize / blur / sharpen / watermark"]
Transform --> Encode["Encode output"]
end
Server --> Storage
subgraph Storage["Storage backends"]
FS["Local filesystem"]
S3["S3"]
GCS["GCS"]
Azure["Azure Blob"]
end
CLI reads local files or fetches remote URLs directly. The HTTP server resolves images from storage backends or client uploads. The WASM build processes files selected in the browser.
Installation
Prebuilt binaries are available on the GitHub Releases page. See Deployment Guide for details on all targets and Docker images.
Quick Start
CLI
The convert subcommand can be omitted: truss photo.png -o photo.jpg is equivalent to truss convert photo.png -o photo.jpg. Run truss convert --help to see the full set of options.
# Convert format
# Resize + convert
# Optimize in place with the shared pipeline
# Convert from a remote URL
# Sanitize SVG (remove scripts and external references)
# Inspect metadata
Format conversion & quality
truss supports JPEG, PNG, WebP, AVIF, BMP, TIFF, and SVG. The output format is inferred from the file extension, or you can specify it explicitly with --format.
| Format | File size (640 × 427) | Notes |
|---|---|---|
| JPEG (original) | 80 KB | Lossy, widely supported |
WebP (--quality 80) |
38 KB | ~52 % smaller than JPEG |
AVIF (--quality 50) |
17 KB | ~79 % smaller than JPEG |
| PNG | 480 KB | Lossless |
# JPEG → WebP (smaller file, same visual quality)
# JPEG → AVIF (best compression)
# Explicit format override (ignore extension)
Use --quality <1-100> to control lossy encoding. Lower values produce smaller files at the cost of visual quality.
Use --optimize auto|lossless|lossy on truss convert, or the dedicated truss optimize subcommand, to reduce output size with format-aware encoding choices. Add --target-quality ssim:0.98 or --target-quality psnr:42 when you want lossy optimization to aim for a specific perceptual threshold.
| Quality 90 (95 KB) | Original (80 KB) | Quality 30 (27 KB) |
|---|---|---|
![]() |
![]() |
![]() |
Resize & fit modes
Specify --width and/or --height to resize. When both are given, --fit controls how the image fits the target box:
| Mode | Behavior |
|---|---|
contain (default) |
Scale down to fit entirely inside the box, preserving aspect ratio. Padding is filled with --background. |
cover |
Scale to fill the box completely, cropping excess. Use --position to choose the crop anchor. |
fill |
Stretch to exact dimensions (ignores aspect ratio). |
inside |
Like contain, but never upscales a smaller image. |
| Original (640 × 427) | contain 300 × 300 | cover 300 × 300 | fill 300 × 300 | inside 300 × 300 |
|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
# contain -- fit inside the box, pad with gray background
# cover -- fill the box, crop the excess
# fill -- stretch to exact dimensions
# inside -- like contain, but never upscale
# Width only -- height is calculated to preserve aspect ratio
Cover position
When using --fit cover, --position controls which part of the image is kept:
--position top-left |
--position center (default) |
--position bottom-right |
|---|---|---|
![]() |
![]() |
![]() |
Available positions: center, top, right, bottom, left, top-left, top-right, bottom-left, bottom-right.
Crop, rotate & background
# Crop a region (x, y, width, height) -- applied before resize
# Rotate 270 degrees clockwise (accepts 0, 90, 180, 270)
# Background color as RRGGBB or RRGGBBAA hex (useful with contain or PNG alpha)
| Original | Crop (--crop 100,50,400,300) |
Rotate (--rotate 270) |
Background (--background FF6B35FF) |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Blur, sharpen & watermark
| Original | Gaussian Blur (--blur 5.0) |
Sharpen (--sharpen 3.0) |
Watermark |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
# Gaussian blur (sigma 0.1 - 100.0)
# Sharpen (sigma 0.1 - 100.0)
# Watermark with full control
Watermark positions are the same as cover positions: center, top, right, bottom, left, top-left, top-right, bottom-left, bottom-right.
Note:
--blur,--sharpen, and--watermarkare raster-only and not supported for SVG inputs.
Metadata control
By default, truss strips all metadata for smaller and safer output.
| Flag | Behavior |
|---|---|
--strip-metadata (default) |
Remove all EXIF, ICC, and other metadata |
--keep-metadata |
Preserve EXIF, ICC, and all other supported metadata |
--preserve-exif |
Keep EXIF only, strip ICC and others |
--auto-orient (default) |
Apply EXIF orientation tag and reset it |
--no-auto-orient |
Skip EXIF orientation correction |
# Keep all metadata (useful for archival)
# Keep EXIF only (strip ICC profiles)
# Disable auto-orientation
Stdin / stdout piping
Use - for input and/or output to integrate truss into shell pipelines. When reading from stdin, --format is required for output.
# Pipe from stdin to stdout
|
# Download, convert, and upload in one pipeline
| | \
# Optimize after converting
|
SVG handling
truss sanitizes SVG files by removing scripts and external references, making them safe for user-generated content.
# Sanitize SVG (remove scripts, external refs)
# Rasterize SVG to PNG at a specific width
Filenames starting with -
Use --output= (or --output) to avoid ambiguity with filenames that start with a dash:
# Dash-prefixed output: use --output= to assign the value unambiguously
# Dash-prefixed input: use a path prefix
HTTP Server -- one curl to transform
# Start the server
TRUSS_BEARER_TOKEN=changeme
# Resize a local image to 400 px wide WebP in one request
See the API Reference for the full endpoint list and CDN integration guide.
Commands
| Command | Description |
|---|---|
convert |
Convert and transform an image file (can be omitted; see above) |
optimize |
Optimize an image with format-aware auto/lossless/lossy modes (truss optimize photo.jpg -o photo-optimized.jpg --mode auto) |
inspect |
Show metadata (format, dimensions, alpha) of an image |
serve |
Start the HTTP image-transform server (implied when server flags are used at the top level) |
validate |
Validate server configuration without starting the server (useful in CI/CD) |
sign |
Generate a signed public URL for the server |
completions |
Generate shell completion scripts |
version |
Print version information |
help |
Show help for a command (e.g. truss help convert) |
Documentation
| Page | Description |
|---|---|
| Configuration Reference | Environment variables, storage backends, logging, and all server settings |
| API Reference | HTTP endpoints, request/response formats, CDN integration |
| Deployment Guide | Docker, prebuilt binaries, cloud storage (S3/GCS/Azure), production setup |
| Development Guide | Building from source, testing, benchmarks, WASM demo, contributing |
| Prometheus Metrics | Metrics reference, bucket boundaries, example PromQL queries |
| OpenAPI Spec | Machine-readable API specification |
Roadmap
See the public roadmap for planned features and milestones.
Contributing
Contributions are welcome. See CONTRIBUTING.md for details.
- Look for
good first issueto get started. - Report bugs and request features via Issues.
- If the project is useful, starring the repository helps.
- Support via GitHub Sponsors is also welcome.
- Sharing the project on social media or in blog posts is appreciated.
License
Released under the MIT License.














