No description
  • D 61.6%
  • Rust 37.2%
  • HTML 0.7%
  • Makefile 0.4%
  • Shell 0.1%
Find a file
2026-05-08 23:09:14 +02:00
target add gitignore 2026-05-08 23:09:14 +02:00
unipack-core Second commit 2026-05-08 22:50:59 +02:00
unipack-creator Second commit 2026-05-08 22:50:59 +02:00
unipack-installer Second commit 2026-05-08 22:50:59 +02:00
.gitignore add gitignore 2026-05-08 23:09:14 +02:00
Cargo.lock Initial commit 2026-05-08 21:07:12 +02:00
Cargo.toml Initial commit 2026-05-08 21:07:12 +02:00
comprehensive_test.sh Second commit 2026-05-08 22:50:59 +02:00
CONFIG_FIX_SUMMARY.md Second commit 2026-05-08 22:50:59 +02:00
end_to_end_test.sh Second commit 2026-05-08 22:50:59 +02:00
FUNCTIONALITY_FIXES.md Second commit 2026-05-08 22:50:59 +02:00
IMPORT_IMPROVEMENTS.md Second commit 2026-05-08 22:50:59 +02:00
LICENSE Initial commit 2026-05-08 21:07:12 +02:00
quick_start.sh Second commit 2026-05-08 22:50:59 +02:00
README.md Initial commit 2026-05-08 21:07:12 +02:00
TAURI_CONFIG_FIX.md Second commit 2026-05-08 22:50:59 +02:00
test_import.sh Second commit 2026-05-08 22:50:59 +02:00

UniPack — Universal Linux Package Format

One format. Every distro. No bullshit.

UniPack is a dead-simple universal package format for Linux. A .unipack file is literally a .tar.xz archive with a METADATA.toml prepended — nothing exotic. The smart part is the installer, which detects your distro and does the right thing: native pacman on Arch, builds a .deb on Debian/Ubuntu, builds an .rpm on Fedora, and falls back to ~/.local install everywhere else.

Why?

Problem Solution
AppImages don't integrate with the system UniPack installs like a real package
AppImages need FUSE / throw FUSE errors UniPack is a plain tar.xz extract
Snap needs a background daemon UniPack has zero runtime overhead
Flatpak bundles its own runtime UniPack uses native system libraries
Maintaining distro packages is hell One .unipack file works everywhere

Components

unipack/
├── unipack-core/          # Shared Rust library (pack, unpack, install, distro detect)
├── unipack-creator/       # Tauri GUI — create .unipack files
│   ├── src/               # Frontend HTML
│   └── src-tauri/         # Rust backend
├── unipack-installer/     # Tauri GUI — install .unipack files
│   ├── src/               # Frontend HTML
│   └── src-tauri/         # Rust backend + MIME type assets
└── website.html           # Project website (single file)

Format

A .unipack file is a .tar.xz archive containing:

METADATA.toml       ← always the first entry
payload/
  bin/myapp
  share/applications/myapp.desktop
  share/icons/hicolor/48x48/apps/myapp.png
  lib/...

METADATA.toml

[package]
name = "myapp"
display_name = "My App"
version = "1.0.0"
description = "Does cool stuff"
author = "You"
license = "MIT"
arch = "x86_64"
format_version = 1

[install]
prefix = "/usr"
executable = "bin/myapp"
supports_user_install = true

[dependencies]
arch   = ["openssl"]
debian = ["libssl3"]
fedora = ["openssl-libs"]

[scripts]
post_install = "gtk-update-icon-cache -f /usr/share/icons/hicolor"

[desktop]
name = "My App"
exec = "bin/myapp"
icon = "myapp"
categories = "Utility;"
terminal = false

Distro support

Distro Method Notes
Arch Linux pacman -U on renamed tar.xz Native package
Manjaro, EndeavourOS, CachyOS Same as Arch Arch-compatible
Debian, Ubuntu, Mint, Pop!_OS Builds .debdpkg -i On-the-fly
Fedora, RHEL, AlmaLinux, Rocky Builds .rpmrpm -i On-the-fly
openSUSE Builds .rpmzypper install On-the-fly
Void Linux Extracts to ~/.local User install
Alpine Linux Extracts to ~/.local User install
Any other Extracts to ~/.local + .desktop Fallback

Prerequisites

  • Rust 1.75+ (curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh)
  • Tauri CLI (cargo install tauri-cli)
  • WebKit2GTK (Arch: webkit2gtk, Debian: libwebkit2gtk-4.1-dev)
  • pkg-config, libssl-dev (or equivalent)

Building

# Build everything
cargo build --workspace

# Build creator GUI
cd unipack-creator/src-tauri
cargo tauri build

# Build installer GUI
cd unipack-installer/src-tauri
cargo tauri build

# Register .unipack MIME type (so double-click works)
sudo xdg-mime install unipack-installer/src-tauri/assets/unipack-mime.xml
sudo update-mime-database /usr/share/mime
sudo cp unipack-installer/src-tauri/assets/unipack-installer.desktop /usr/share/applications/
sudo update-desktop-database /usr/share/applications

Usage

Creating a package

  1. Launch unipack-creator
  2. Point "Source Directory" at your build output (the directory that would become /usr)
  3. Fill out the metadata form — name, version, description, arch, dependencies
  4. Enable "Desktop Entry" if your app has a GUI
  5. Click Pack → you get myapp-1.0.0.x86_64.unipack

Installing a package

Double-click the .unipack file in your file manager (after registering the MIME type), or:

unipack-installer myapp-1.0.0.x86_64.unipack

The GUI shows you package info, lets you choose user vs system install, then installs.

Library usage

use unipack_core::{
    pack::{pack, PackOptions},
    install::{install, InstallOptions, InstallScope},
    unpack::read_metadata,
};

// Read metadata from a .unipack
let meta = read_metadata(Path::new("myapp.unipack"))?;
println!("{} v{}", meta.package.name, meta.package.version);

// Install a .unipack
let result = install(InstallOptions {
    unipack_path: PathBuf::from("myapp.unipack"),
    scope: InstallScope::User,
    verify_checksum: true,
    install_deps: true,
    progress: Some(Box::new(|stage, msg| println!("[{stage}] {msg}"))),
})?;

License

MIT — see LICENSE.