This is a unified launcher for Windows games on Linux. It is essentially a copy of the Steam Runtime Tools and Steam Linux Runtime that Valve uses for Proton, with some modifications made so that it can be used outside of Steam.
An umu is an above-ground oven of hot volcanic stones originating from Polynesian culture. After the stones are heated, the top layer is removed and the food placed on top to heat/cook. We chose the name because Valve's containerization tool is named pressure-vessel. We're "preparing" the pressure vessel similar to how you would use a stove top pressure-cooker -- by placing it on our umu's "stovetop"
When Steam launches a Proton game, it launches it like this:
/home/tcrider/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=348550 -- /home/tcrider/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- /home/tcrider/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point --verb=waitforexitandrun -- /home/tcrider/.local/share/Steam/compatibilitytools.d/GE-Proton8-27/proton waitforexitandrun /home/tcrider/.local/share/Steam/steamapps/common/Guilty Gear XX Accent Core Plus R/GGXXACPR_Win.exe
We can ignore this /home/tcrider/.local/share/Steam/ubuntu12_32/steam-launch-wrapper, it's just a process runner with no real value other than forwarding environment variables (more on that later).
I managed to pull the environment variables it uses by making Steam run printenv for the game's command line. We needed these envvars because Proton expects them in order to function. With them we can essentially make Proton run without needing steam at all.
Next this part /home/tcrider/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point
The first part /home/tcrider/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper/ is steam-runtime-tools compiled and is used alongside the sniper runtime container used during Proton builds.
The second part _v2-entry-point is just a bash script which loads Proton into the container and runs the game.
So, umu is basically a copy paste of SteamLinuxRuntime_sniper, which is a compiled version of steam-runtime-tools. We've renamed _v2-entry-point to umu and added umu-run to replace steam-launch-wrapper.
When you use umu-run to run a game, it uses the specified WINEPREFIX, Proton version, executable, and arguments passed to it to run the game in Proton, inside Steam's runtime container JUST like if you were running the game through Steam, except now you're no longer limited to Steam's game library or forced to add the game to Steam's library. In fact, you don't even have to have Steam installed.
umu-run "$HOME/Games/epic-games-store/drive_c/Program Files (x86)/Epic Games/Launcher/Portal/Binaries/Win32/EpicGamesLauncher.exe" -opengl -SkipBuildPatchPrereq
Optionally, with WINEPREFIX, GAMEID, STORE, and PROTONPATH:
WINEPREFIX=$HOME/Games/epic-games-store GAMEID=umu-dauntless STORE=egs PROTONPATH="$HOME/.steam/steam/compatibilitytools.d/GE-Proton8-28" umu-run "$HOME/Games/epic-games-store/drive_c/Program Files (x86)/Epic Games/Launcher/Portal/Binaries/Win32/EpicGamesLauncher.exe" -opengl -SkipBuildPatchPrereq
Notes:
WINEPREFIX designates where to create the wine prefix. If not specified it will default to /home/username/Games/umu/GAMEIDGAMEID designates a corresponding umu-id from the umu-database for games that have fixes that need to be applied. Defaults to umu-defaultPROTONPATH designates the full path to a specific proton version. Alternatively you can use value "GE-Proton" to auto-download and use the latest GE-Proton build. Defaults to UMU-Proton. (UMU-Proton is the latest stable version of Valve's proton tool with UMU compatibility added)STORE designates what storefront to use. UMU uses GAMEID and STORE to search the umu-database for fixes to apply to a game. Defaults to "none".See the documentation for more examples and the project's wiki for Frequently Asked Questions.
Note: umu-launcher will automatically use and download the latest Steam Runtime that is required by Proton, and move its files to $HOME/.local/share/umu.
Right now protonfixes packages a folder of 'gamefixes' however it could likely be recoded to pull from online quite easily. The idea is to get all of these tools using this same umu-run and just feeding their envvars into it. That way any changes that need to happen can happen in proton-ge and/or protonfixes, or a 'unified proton' build based off GE, or whatever they want.
umu-run alongside the store type, Proton version, wine prefix, game executable, and launch arguments.umu-run, protonfixes picks up the store type and umu ID and finds the appropriate fix script for it, then applies it before running the game.Example:
Borderlands 3 from EGS store.
1. Generally a launcher is going to know which store it is using already, so that is easy enough to determine and feed the STORE variable to the launcher.
2. To determine the game title, EGS has various codenames such as 'Catnip'. The launcher would see "ok store is egs and codename is Catnip, let's search the umu database for those"
3. In our umu unified database, we create a 'title' column, 'store' column, 'codename' column, 'umu-ID' column. We add a line for Borderlands 3 and fill in the details for each column.
4. Now the launcher can search 'Catnip' and 'egs' as the codename and store in the database and correlate it with Borderlands 3 and umu-12345. It can then feed umu-12345 to the umu-run script.
When reporting issues for games that fail to run, be sure to attach a log with your issue report. To acquire a log from umu, add UMU_LOG=1 to your environment variables for verbose logging. Furthermore, you can use PROTON_LOG=1 for proton to create a verbose log in your $HOME directory. The log will be named steam-<appid>.log, where <appid> will be default if you haven't set a GAMEID or a number, depending on what you have set for GAMEID.
Do NOT report issues here when using compatibility tools that are NOT explictly supported, report them to their maintainers first. This includes non-Proton compatibility tools, as well as third-party Proton compatibility tools that are not provided through umu-launcher.
Building umu-launcher currently requires bash, make, and scdoc for distribution, as well as the following Python build tools: build, hatchling, installer, and pip.
Additionally, cargo will be required with the minimum MSRV being the latest stable versions of it's direct dependencies.
To build umu-launcher, after downloading and extracting the source code from this repository, change into the newly extracted directory
cd umu-launcher
To configure the installation PREFIX (this is not related to wine's WINEPREFIX) use the configure.sh script
./configure.sh --prefix=/usr
Change the --prefix as fit for your distribution, for example /usr/local, or /app for packaging through Flatpak.
Then run make to build. After a successful build the resulting files should be available in the ./builddir directory
To install umu-launcher run the following command after completing the steps described above
make install
Or if you are packaging umu-launcher
make DESTDIR=<packaging_directory> install
Additionally, user installations are supported if desired.
First, configure the build for a user installation
./configure.sh --user-install
Then run make install
make install
Note: When installing as a user, this will place the executable umu-run in $HOME/.local/bin. You will need to add $HOME/.local/bin in your $PATH to be able to run umu-launcher this way by exporting the path in your shell's configuration, for example $HOME/.bash_profile
export PATH="$HOME/.local/bin:$PATH"
Alternatively, uv can be used to quickly setup umu-launcher. For more detail on how this feature works, see the documentation.
First, create the script within the project directory.
touch umu-run
Then, assuming you have uv installed, create the virtual environment and install the project's dependencies.
For example
uv add --script umu-run 'python-xlib' 'urllib3' 'truststore'
Afterwards, run the script through uv
uv run umu-run -h
dnf install umu-launcher
pacman -S umu-launcher
Available in nixpkgs since 25.05. Simply add pkgs.umu-launcher to your configuration.
NixOS example
# configuration.nix
{pkgs, ...}: {
environment.systemPackages = [
pkgs.umu-launcher
];
}
home-manager example
# home.nix
{pkgs, ...}: {
home.packages = [
pkgs.umu-launcher
];
}
If you're using an older nixpkgs channel, such as nixos-24.11, you could consider using multiple nixpkgs channels or using our flake (see below).
[!NOTE] If there is any problem with the flake, please open a bug report and tag at lease one of the maintainers: \ @beh-10257, @MattSturgeon, & @LovingMelody
If the version in nixpkgs is not up-to-date enough for you, the latest git snapshot can be installed using the flake in this repo.
Example flake (NixOS)
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
umu.url = "github:Open-Wine-Components/umu-launcher?dir=packaging/nix";
umu.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = {nixpkgs, ...} @ inputs: {
nixosConfigurations.desktop = nixpkgs.lib.nixosSystem {
# Pass `inputs` to the nixos configuration,
# allowing it to be used as a module arg
specialArgs = {inherit inputs;};
modules = [./configuration.nix];
};
};
}
# configuration.nix
{
inputs,
pkgs,
...
}: let
# Get `system` from `pkgs`
inherit (pkgs.stdenv.hostPlatform) system;
in {
environment.systemPackages = [
# Install the `default` package from the umu input
inputs.umu.packages.${system}.default;
];
}
Example flake (using overlays)
If you pass your flake inputs to specialArgs, you can apply the overlay within your configuration.nix:
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
umu.url = "github:Open-Wine-Components/umu-launcher?dir=packaging/nix";
umu.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = {nixpkgs, ...} @ inputs: {
nixosConfigurations.desktop = nixpkgs.lib.nixosSystem {
# Pass inputs to the nixos configuration,
# allowing it to be us
$ claude mcp add umu-launcher \
-- python -m otcore.mcp_server <graph>