Skip to content

Instantly share code, notes, and snippets.

@Mihitoko
Last active March 4, 2026 02:52
Show Gist options
  • Select an option

  • Save Mihitoko/bd76340e56e78ec972c8a1365abb0d55 to your computer and use it in GitHub Desktop.

Select an option

Save Mihitoko/bd76340e56e78ec972c8a1365abb0d55 to your computer and use it in GitHub Desktop.
Install GeForceNow on Desktop Linux/Non SteamOs devices

Guide for installing GeForceNow on Desktop Linux

With GeForceNow now being available for Linux we can now use the service with optimal performance.

Unfortunately Nvidia only officially supports SteamDeck and during getting this to work on my systems I had to get through some hoops that i want to share here.

First of all the app Nvidia provided is just a normal Flatpak app so the installation is relatively straight forward.
We will not use the official binary that Nvidia proved here, we can install the Flatpak app ourselves.

Just for reference im on PopOs 22.04 but since this is a flatpak it should work the same for everyone.

The guide assumes you have a working flatpak installation.

Installation

Install runtime

First install the runtime that GeForceNow uses, high chance that this is already installed.
The official installer installs this with the --system flag but I find this unnecessary so we install it as user like everything else.

flatpak install --user flathub org.freedesktop.Sdk//24.08

Add Nvidia repository

flatpak remote-add --user  --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo

Install GeForceNow

flatpak install --user GeForceNOW com.nvidia.geforcenow

That's it you should now be able to launch the app.

Troubleshooting

Some issues I encountered and how I worked around them.

GeForce now encountered a problem and needs to be reinstalled

I encountered while testing this in a VM. The application failed because some GPU features where not available. On real hardware I had no issues. However, if you encounter that check these log files.

cat ~/.var/app/com.nvidia.geforcenow/.local/state/NVIDIA/GeForceNOW/geronimo.log
cat ~/.var/app/com.nvidia.geforcenow/.local/state/NVIDIA/GeForceNOW/GeForceNOW.log

I'm on a full AMD system, I could imagine Nvidia GPUs might make some trouble since the SteamDeck uses AMD.

Logging in not possible (Endless loading spinner)

This is because GeForceNow is failing to open the hosts browser. Luckily Nvidia writes the oauth url it wants to open into a logfile.
You can extract the line with this command.

tac ~/.var/app/com.nvidia.geforcenow/.local/state/NVIDIA/GeForceNOW/console.log | grep starfleet/o-auth | head -n 1

Then paste it into your browser and continue as you would normally.

Network Test Failing

For me the Network Test always failed and claimed there was no connection to Nvidia servers. Even though the app was clearly online. I'm usure why this happens. What I ended up doing is:

  • Click the Burger Menu on the Left Top Corner
  • Go to Settings
  • Gameplay
  • Change Streaming Quality Mode to Custom

This will skip the network check.

Window not opening on Wayland

When the GeForceNow App is not opening and you are under wayland try removing the wayland permission from the flatpak to force it thorough XWayland.

flatpak override --user --nosocket=wayland com.nvidia.geforcenow 

End

Thats it, for me it worked flawlessly afterwards. If you have any additional issues and fixes write them in the comments so we can update the Gist.

@bacatta
Copy link

bacatta commented Dec 25, 2025

Does anyone know a way to force or persist AZERTY keyboard layout inside game launchers (Steam / Battle.net) when using GeForce NOW on Linux?

@krxdow Same for me with BÉPO or AZERTY layouts. GFN uses an English version of Steam with a QWERTY layout, and I know no workaround for this. Many people already complained about this in the GFN forum.

Yes, I confirm this is not Linux nor SteamOS specific. https://gist.github.com/Mihitoko/bd76340e56e78ec972c8a1365abb0d55?permalink_comment_id=5812552#gistcomment-5812552 If you find a solution somewhere, please share it here, i will do the same :)

I've just tested again on Chromebook and there is actually an option for keyboard layout that is working !
I think it's the Android client since I also got the same option available on my smartphone (but not tested).

@KingPin
Copy link

KingPin commented Dec 26, 2025

anyone know how I can connect to my epic account? i just get the popup saying a browser tab is open, finish connecting your account. but nothing happens

thanks

@armeldemarsac92
Copy link

armeldemarsac92 commented Dec 28, 2025

Updated script for fedora, with the right geforce client version, the latest update broke everyhting.

# https://gist.github.com/Mihitoko/bd76340e56e78ec972c8a1365abb0d55?permalink_comment_id=5840016#gistcomment-5840016
# GPU check: Verify that the graphics card is from AMD
if ! lspci | grep -i 'VGA' | grep -qi 'amd\|advanced micro devices'; then
    echo "⚠️ This script requires an AMD GPU. Exiting."
    exit 1
fi
echo ""
echo "βœ… AMD GPU detected. So far, so good."
echo ""
# Check if dnf is installed, it should if it's a Fedora distro:
if ! command -v dnf &> /dev/null; then
    echo "⚠️ This script is designed for Fedora and Fedora-based distributions."
    echo "   'dnf' command not found. Exiting."
    exit 1
fi
echo ""
# Exit immediately if a command exits with a non-zero status.
set -e

# --- Configuration ---
# Path for the custom launcher script
LAUNCHER_DIR="$HOME/.local/bin"
LAUNCHER_SCRIPT_PATH="$LAUNCHER_DIR/geforce-now-launcher.sh"

# Define the file name and the two key locations
DESKTOP_FILE_NAME="com.nvidia.geforcenow.desktop"
LOCAL_SHARE_APPLICATIONS="$HOME/.local/share/applications"
MENU_FILE_PATH="$HOME/.local/share/applications/$DESKTOP_FILE_NAME" # The "source" file for the app menu
# Find the user's desktop directory, falling back to "$HOME/Desktop" if the command fails
DESKTOP_DIR=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop")
# Define the full path for the desktop shortcut
DESKTOP_FILE_PATH="$DESKTOP_DIR/$DESKTOP_FILE_NAME"
# --- NEW: Define sudoers file for passwordless mounting ---
SUDOERS_FILE="/etc/sudoers.d/99-geforcenow-spoof"

echo ""
echo "Before we start we will need to install Flatpak, which requires root permissions to get it installed"
echo ""
if dnf list installed flatpak &> /dev/null; then
    echo "βœ… Flatpak is already installed. Good!"
else
    echo "Flatpak is not installed. We will need to install it, which requires root permissions."
    sudo dnf install -y flatpak
    echo "βœ… Flatpak has been successfully installed."
fi
echo ""

# --- Installation Steps ---
echo "πŸš€ Starting GeForce NOW Installer for AMD Linux Systems..."
echo "1. Adding Flathub repo and installing required Flatpak runtimes..."
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Platform//24.08 || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Sdk//24.08 || true
echo "βœ… Required runtimes installed"

echo "2. Adding the GeForce NOW Flatpak repository..."
flatpak remote-add --user --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo || true
echo "βœ… GeForce NOW repo added"

echo "3. Installing GeForce NOW..."
flatpak uninstall --noninteractive -y --user com.nvidia.geforcenow &>/dev/null || echo "βœ… GeForce NOW not found. Ready for a fresh installation."
flatpak install --noninteractive -y --user GeForceNOW com.nvidia.geforcenow || echo "βœ… App installed. In the next steps we'll apply some custom tweaks so it can work."

# --- MODIFICATION START: Force Specific Version ---
echo "⬇️  Downgrading to requested version: 2.0.78.147..."
flatpak update --noninteractive -y --user --commit=0d56051d6c9c81177f685a988d666fa12b647ca25f994e9bb378d4c9305b10c2 com.nvidia.geforcenow
echo "πŸ”’ Locking version to prevent auto-updates..."
flatpak mask --user com.nvidia.geforcenow
# --- MODIFICATION END ---

mkdir -p "$HOME/.local/share/icons/hicolor/512x512/apps"
curl -sL -o "$HOME/.local/share/icons/hicolor/512x512/apps/com.nvidia.geforcenow.png" https://gitlab.com/anthrgk/geforcenow-installer-linux/-/raw/main/arch/img/com.nvidia.geforcenow.png
echo "βœ… GeForce NOW installed. Tweaking few things so it can launch succesfully..."
echo "4. Applying required Flatpak overrides..."
flatpak override --user --nosocket=wayland com.nvidia.geforcenow
flatpak override --user --nofilesystem=host-etc com.nvidia.geforcenow
echo "βœ… Flatpak overrides applied"

# --- NEW STEP: Configure passwordless sudo for the mounting commands ---
echo "5. Configuring passwordless sudo for automatic system value spoofing..."
echo ""
echo "   This next step is optional, but required if you want to enable up to 4K 120FPS streaming."
echo "   If you agree, your device's system information (product, vendor, and board name) will be temporarily"
echo "   'spoofed' or disguised to look like a different device while GeForce NOW is running."
echo ""
echo "   ⚠️ IMPORTANT: Because of this temporary change, it is strongly recommended NOT to perform"
echo "   any system or software updates while GeForce NOW is open."
echo "   Proceed at your own risk."
echo ""
read -p "   Do you want to proceed? (y/N) " -n 1 -r
echo # Move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
    # Define the exact commands that will be allowed without a password
    SUDOERS_CONTENT="
# Allow user $USER to run mount/umount for GeForce NOW DMI spoofing
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_product_name /sys/class/dmi/id/product_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_sys_vendor /sys/class/dmi/id/sys_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_board_vendor /sys/class/dmi/id/board_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_board_name /sys/class/dmi/id/board_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/product_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/sys_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/board_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/board_name
"
    # Use tee with sudo to write the file, as we need root privileges
    echo "$SUDOERS_CONTENT" | sudo tee "$SUDOERS_FILE" > /dev/null
    sudo chmod 0440 "$SUDOERS_FILE"
    echo "βœ… Sudoers file created successfully."
else
    echo "⚠️  Skipping sudoers configuration. The launcher will not be able to spoof DMI values."
fi


echo "6. Creating the custom launcher script..."
# Ensure the local bin directory exists
mkdir -p "$LAUNCHER_DIR"
# --- HEAVILY MODIFIED: Create the new launcher script with spoofing and cleanup ---
cat > "$LAUNCHER_SCRIPT_PATH" << 'EOF'
#!/bin/bash
# The first section toggles the GeForce NOW TV Mode.
# It will obviously skip the modification if the directory or config file is not found,
# allowing the rest of the launch script to continue.

# 1. Define the base directory.
CONFIG_JSON_DIR="$HOME/.local/share/flatpak/app/com.nvidia.geforcenow/x86_64/master/"
# 2. Attempt to find the config file path.
CONFIG_FILE=$(find "$CONFIG_JSON_DIR" -type f -name "config.json" -print -quit 2>/dev/null)

# 3. Proceed with modifications ONLY if the config file was found.
if [ -n "$CONFIG_FILE" ]; then
    echo "Found config file: $CONFIG_FILE"

    # Check if we are on a Steam Deck Gaming Mode or we launched the GeForce NOW via Steam, and apply the appropriate setting so it launches with tv layout.
    if [ -n "$SteamDeck" ] && [ "$SteamDeck" -eq 1 ]; then
        echo "App launched via Steam. Enabling TV Mode..."
        sed -i 's/"tvMode": false,/"tvMode": true,/' "$CONFIG_FILE"
        echo "βœ… 'tvMode' set to 'true'."
    else
    # If we aren't on Steam Deck Gaming Mode nor launched GeForce NOW via Steam, it will set GFN with the desktop layout.
        echo "Standard environment detected. Disabling TV Mode..."
        sed -i 's/"tvMode": true,/"tvMode": false,/' "$CONFIG_FILE"
        echo "βœ… 'tvMode' set to 'false'."
    fi
else
    echo "GeForce NOW config not found. Skipping modification."
fi
echo ""
# This section of the script performs two main functions:
# 1. DMI Spoofing: Mounts temporary files to pretend the system is a Steam Deck.
# 2. Flatpak Spoofing: Runs GeForce NOW inside a Flatpak sandbox with a fake os-release.
# It automatically cleans up the DMI mounts when the application is closed.

# --- Function to clean up the mounts and temp files ---
cleanup() {
    echo "GeForce NOW closed. Cleaning up DMI spoof..."
    # Unmount in reverse order, ignoring errors if they are already unmounted
    sudo umount /sys/class/dmi/id/board_name &>/dev/null || true
    sudo umount /sys/class/dmi/id/board_vendor &>/dev/null || true
    sudo umount /sys/class/dmi/id/sys_vendor &>/dev/null || true
    sudo umount /sys/class/dmi/id/product_name &>/dev/null || true

    # Remove the temporary files
    rm -f /tmp/fake_product_name /tmp/fake_sys_vendor /tmp/fake_board_vendor /tmp/fake_board_name
    echo "βœ… Cleanup complete."
}

# --- Trap the exit signal to ensure cleanup always runs ---
# This makes sure the 'cleanup' function is called when the script exits for any reason.
trap cleanup EXIT

# --- Step 1: Perform DMI Spoofing on the host system ---
echo "πŸš€ Applying DMI spoof so we can mimic another device and enable 4k 120FPS with HDR.."
echo "83L3" > /tmp/fake_product_name
echo "Lenovo" > /tmp/fake_sys_vendor
echo "Lenovo" > /tmp/fake_board_vendor
echo "8ARP1" > /tmp/fake_board_name

# Use sudo for the mount commands (passwordless due to sudoers config)
sudo mount --bind /tmp/fake_product_name /sys/class/dmi/id/product_name
sudo mount --bind /tmp/fake_sys_vendor /sys/class/dmi/id/sys_vendor
sudo mount --bind /tmp/fake_board_vendor /sys/class/dmi/id/board_vendor
sudo mount --bind /tmp/fake_board_name /sys/class/dmi/id/board_name
echo "βœ… DMI values spoofed. Launching GeForce NOW..."

# --- Step 2: Launch GeForce NOW with Flatpak Spoofing ---
# The rest of this is the original flatpak sandboxed launch command
flatpak run --user --command=bash com.nvidia.geforcenow -c '
    # Exit immediately if a command exits with a non-zero status.
    set -e

    # Create the directory that holds the os-release and SSL certs
    mkdir -p /run/host/etc/ssl

    # Create the SteamOS os-release file
    cat > /run/host/etc/os-release << EOL
NAME="SteamOS"
PRETTY_NAME="SteamOS"
VERSION_CODENAME=holo
ID=steamos
ID_LIKE=arch
ANSI_COLOR="1;35"
HOME_URL="https://www.steampowered.com/"
DOCUMENTATION_URL="https://support.steampowered.com/"
SUPPORT_URL="https://support.steampowered.com/"
BUG_REPORT_URL="https://support.steampowered.com/"
LOGO=steamos
VARIANT_ID=steamdeck
VERSION_ID=3.7.13
BUILD_ID=20250630.1
STEAMOS_DEFAULT_UPDATE_BRANCH=stable
EOL

    # Recursively copy the host system'\''s SSL certificates into the sandbox
    cp -r /etc/ssl /run/host/etc/

    # Launch GeForce NOW (this command blocks until the app is closed)
    /app/bin/GeForceNOW
'
EOF

# Make the launcher script executable
chmod +x "$LAUNCHER_SCRIPT_PATH"
echo "βœ… Custom launcher script created at: $LAUNCHER_SCRIPT_PATH"

echo "7. Creating and modifying the main application menu shortcut..."
mkdir -p "$LOCAL_SHARE_APPLICATIONS"
cat > "$MENU_FILE_PATH" << EOF
[Desktop Entry]
Version=1.0
Name=NVIDIA GeForce NOW
GenericName=NVIDIA GeForce NOW
Exec=$LAUNCHER_SCRIPT_PATH
Icon=com.nvidia.geforcenow
Type=Application
Categories=Network;Game;
EOF
echo "βœ… Main menu shortcut modified to use the custom launcher script."

echo "8. Creating/Updating the desktop shortcut and if possible adding GeForce NOW to Steam..."
cp "$MENU_FILE_PATH" "$DESKTOP_FILE_PATH"
echo "βœ… Desktop shortcut created and synchronized with the main menu entry."
if command -v steamos-add-to-steam >/dev/null 2>&1; then
  steamos-add-to-steam "$MENU_FILE_PATH" || steamos-add-to-steam com.nvidia.geforcenow || true
  echo "βœ… GeForce NOW shortcut added to Steam as well."
elif command -v xdg-open >/dev/null 2>&1; then
  xdg-open "steam://AddNonSteamGame" >/dev/null 2>&1 || true
fi

echo "9. Making shortcuts launchable..."
case "$XDG_CURRENT_DESKTOP" in
    *GNOME*|*Cinnamon*|*MATE*|*Budgie*)
        echo "   Detected a GNOME-based desktop. Using 'gio' to trust files."
        /usr/bin/gio set "$MENU_FILE_PATH" metadata::trusted true || echo "⚠️  Warning: Could not trust the main menu shortcut."
        /usr/bin/gio set "$DESKTOP_FILE_PATH" metadata::trusted true || echo "⚠️  Warning: Could not trust the desktop shortcut."
        ;;
    *KDE*|*)
        echo "βœ… Detected KDE or another desktop. Setting executable permissions."
        chmod +x "$MENU_FILE_PATH"
        chmod +x "$DESKTOP_FILE_PATH"
        ;;
esac
echo "βœ… Both shortcuts are now ready to launch."
echo ""
echo "πŸŽ‰ Installation complete! You can now launch GeForce NOW from your desktop OR your application menu."
echo ""
echo "ℹ️  NOTE: To uninstall, you can delete the application and manually remove the files added by this script with:"
echo "   flatpak uninstall --user com.nvidia.geforcenow"
echo "   sudo rm '$SUDOERS_FILE'"
echo "   rm '$LAUNCHER_SCRIPT_PATH' '$MENU_FILE_PATH' '$DESKTOP_FILE_PATH'"```

@d4vid1
Copy link

d4vid1 commented Jan 3, 2026

Hi guys, installed GeforceNow from here ubuntu but i cannot start a game. become Network Test window and it say that i can not connect to the nvidia server, and iam Change Streaming Quality Mode to Custom already, but that doesn’t help.
What can i do to skip that Network Test Window?

@LeonardPuettmann
Copy link

The installation itself works, but I don't have the 4k option and in the terminal, I see: [34:62:2026-01-03/ 18:05:46.916:ERROR:registration_request.cc(291)] Registration response error message: DEPRECATED_ENDPOINT Callback requested, but no callback function provided!
Could it be that the device is still not accepted as a Steamdeck?

@LeonardPuettmann
Copy link

I found the issue. In the install script, geforce now is installed with the user flag. However on Debian, the downgrade to the version you need root permission, which is why running flatpak update --noninteractive -y --user --commit=0d56... did not actually downgrade the version. For me it worked installing and then downgrading with the --system flag and not the --user flag.

@d4vid1
Copy link

d4vid1 commented Jan 3, 2026

Updated script for fedora, with the right geforce client version, the latest update broke everyhting.

# https://gist.github.com/Mihitoko/bd76340e56e78ec972c8a1365abb0d55?permalink_comment_id=5840016#gistcomment-5840016
# GPU check: Verify that the graphics card is from AMD
if ! lspci | grep -i 'VGA' | grep -qi 'amd\|advanced micro devices'; then
    echo "⚠️ This script requires an AMD GPU. Exiting."
    exit 1
fi
echo ""
echo "βœ… AMD GPU detected. So far, so good."
echo ""
# Check if dnf is installed, it should if it's a Fedora distro:
if ! command -v dnf &> /dev/null; then
    echo "⚠️ This script is designed for Fedora and Fedora-based distributions."
    echo "   'dnf' command not found. Exiting."
    exit 1
fi
echo ""
# Exit immediately if a command exits with a non-zero status.
set -e

# --- Configuration ---
# Path for the custom launcher script
LAUNCHER_DIR="$HOME/.local/bin"
LAUNCHER_SCRIPT_PATH="$LAUNCHER_DIR/geforce-now-launcher.sh"

# Define the file name and the two key locations
DESKTOP_FILE_NAME="com.nvidia.geforcenow.desktop"
LOCAL_SHARE_APPLICATIONS="$HOME/.local/share/applications"
MENU_FILE_PATH="$HOME/.local/share/applications/$DESKTOP_FILE_NAME" # The "source" file for the app menu
# Find the user's desktop directory, falling back to "$HOME/Desktop" if the command fails
DESKTOP_DIR=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop")
# Define the full path for the desktop shortcut
DESKTOP_FILE_PATH="$DESKTOP_DIR/$DESKTOP_FILE_NAME"
# --- NEW: Define sudoers file for passwordless mounting ---
SUDOERS_FILE="/etc/sudoers.d/99-geforcenow-spoof"

echo ""
echo "Before we start we will need to install Flatpak, which requires root permissions to get it installed"
echo ""
if dnf list installed flatpak &> /dev/null; then
    echo "βœ… Flatpak is already installed. Good!"
else
    echo "Flatpak is not installed. We will need to install it, which requires root permissions."
    sudo dnf install -y flatpak
    echo "βœ… Flatpak has been successfully installed."
fi
echo ""

# --- Installation Steps ---
echo "πŸš€ Starting GeForce NOW Installer for AMD Linux Systems..."
echo "1. Adding Flathub repo and installing required Flatpak runtimes..."
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Platform//24.08 || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Sdk//24.08 || true
echo "βœ… Required runtimes installed"

echo "2. Adding the GeForce NOW Flatpak repository..."
flatpak remote-add --user --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo || true
echo "βœ… GeForce NOW repo added"

echo "3. Installing GeForce NOW..."
flatpak uninstall --noninteractive -y --user com.nvidia.geforcenow &>/dev/null || echo "βœ… GeForce NOW not found. Ready for a fresh installation."
flatpak install --noninteractive -y --user GeForceNOW com.nvidia.geforcenow || echo "βœ… App installed. In the next steps we'll apply some custom tweaks so it can work."

# --- MODIFICATION START: Force Specific Version ---
echo "⬇️  Downgrading to requested version: 2.0.78.147..."
flatpak update --noninteractive -y --user --commit=0d56051d6c9c81177f685a988d666fa12b647ca25f994e9bb378d4c9305b10c2 com.nvidia.geforcenow
echo "πŸ”’ Locking version to prevent auto-updates..."
flatpak mask --user com.nvidia.geforcenow
# --- MODIFICATION END ---

mkdir -p "$HOME/.local/share/icons/hicolor/512x512/apps"
curl -sL -o "$HOME/.local/share/icons/hicolor/512x512/apps/com.nvidia.geforcenow.png" https://gitlab.com/anthrgk/geforcenow-installer-linux/-/raw/main/arch/img/com.nvidia.geforcenow.png
echo "βœ… GeForce NOW installed. Tweaking few things so it can launch succesfully..."
echo "4. Applying required Flatpak overrides..."
flatpak override --user --nosocket=wayland com.nvidia.geforcenow
flatpak override --user --nofilesystem=host-etc com.nvidia.geforcenow
echo "βœ… Flatpak overrides applied"

# --- NEW STEP: Configure passwordless sudo for the mounting commands ---
echo "5. Configuring passwordless sudo for automatic system value spoofing..."
echo ""
echo "   This next step is optional, but required if you want to enable up to 4K 120FPS streaming."
echo "   If you agree, your device's system information (product, vendor, and board name) will be temporarily"
echo "   'spoofed' or disguised to look like a different device while GeForce NOW is running."
echo ""
echo "   ⚠️ IMPORTANT: Because of this temporary change, it is strongly recommended NOT to perform"
echo "   any system or software updates while GeForce NOW is open."
echo "   Proceed at your own risk."
echo ""
read -p "   Do you want to proceed? (y/N) " -n 1 -r
echo # Move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
    # Define the exact commands that will be allowed without a password
    SUDOERS_CONTENT="
# Allow user $USER to run mount/umount for GeForce NOW DMI spoofing
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_product_name /sys/class/dmi/id/product_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_sys_vendor /sys/class/dmi/id/sys_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_board_vendor /sys/class/dmi/id/board_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_board_name /sys/class/dmi/id/board_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/product_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/sys_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/board_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/board_name
"
    # Use tee with sudo to write the file, as we need root privileges
    echo "$SUDOERS_CONTENT" | sudo tee "$SUDOERS_FILE" > /dev/null
    sudo chmod 0440 "$SUDOERS_FILE"
    echo "βœ… Sudoers file created successfully."
else
    echo "⚠️  Skipping sudoers configuration. The launcher will not be able to spoof DMI values."
fi


echo "6. Creating the custom launcher script..."
# Ensure the local bin directory exists
mkdir -p "$LAUNCHER_DIR"
# --- HEAVILY MODIFIED: Create the new launcher script with spoofing and cleanup ---
cat > "$LAUNCHER_SCRIPT_PATH" << 'EOF'
#!/bin/bash
# The first section toggles the GeForce NOW TV Mode.
# It will obviously skip the modification if the directory or config file is not found,
# allowing the rest of the launch script to continue.

# 1. Define the base directory.
CONFIG_JSON_DIR="$HOME/.local/share/flatpak/app/com.nvidia.geforcenow/x86_64/master/"
# 2. Attempt to find the config file path.
CONFIG_FILE=$(find "$CONFIG_JSON_DIR" -type f -name "config.json" -print -quit 2>/dev/null)

# 3. Proceed with modifications ONLY if the config file was found.
if [ -n "$CONFIG_FILE" ]; then
    echo "Found config file: $CONFIG_FILE"

    # Check if we are on a Steam Deck Gaming Mode or we launched the GeForce NOW via Steam, and apply the appropriate setting so it launches with tv layout.
    if [ -n "$SteamDeck" ] && [ "$SteamDeck" -eq 1 ]; then
        echo "App launched via Steam. Enabling TV Mode..."
        sed -i 's/"tvMode": false,/"tvMode": true,/' "$CONFIG_FILE"
        echo "βœ… 'tvMode' set to 'true'."
    else
    # If we aren't on Steam Deck Gaming Mode nor launched GeForce NOW via Steam, it will set GFN with the desktop layout.
        echo "Standard environment detected. Disabling TV Mode..."
        sed -i 's/"tvMode": true,/"tvMode": false,/' "$CONFIG_FILE"
        echo "βœ… 'tvMode' set to 'false'."
    fi
else
    echo "GeForce NOW config not found. Skipping modification."
fi
echo ""
# This section of the script performs two main functions:
# 1. DMI Spoofing: Mounts temporary files to pretend the system is a Steam Deck.
# 2. Flatpak Spoofing: Runs GeForce NOW inside a Flatpak sandbox with a fake os-release.
# It automatically cleans up the DMI mounts when the application is closed.

# --- Function to clean up the mounts and temp files ---
cleanup() {
    echo "GeForce NOW closed. Cleaning up DMI spoof..."
    # Unmount in reverse order, ignoring errors if they are already unmounted
    sudo umount /sys/class/dmi/id/board_name &>/dev/null || true
    sudo umount /sys/class/dmi/id/board_vendor &>/dev/null || true
    sudo umount /sys/class/dmi/id/sys_vendor &>/dev/null || true
    sudo umount /sys/class/dmi/id/product_name &>/dev/null || true

    # Remove the temporary files
    rm -f /tmp/fake_product_name /tmp/fake_sys_vendor /tmp/fake_board_vendor /tmp/fake_board_name
    echo "βœ… Cleanup complete."
}

# --- Trap the exit signal to ensure cleanup always runs ---
# This makes sure the 'cleanup' function is called when the script exits for any reason.
trap cleanup EXIT

# --- Step 1: Perform DMI Spoofing on the host system ---
echo "πŸš€ Applying DMI spoof so we can mimic another device and enable 4k 120FPS with HDR.."
echo "83L3" > /tmp/fake_product_name
echo "Lenovo" > /tmp/fake_sys_vendor
echo "Lenovo" > /tmp/fake_board_vendor
echo "8ARP1" > /tmp/fake_board_name

# Use sudo for the mount commands (passwordless due to sudoers config)
sudo mount --bind /tmp/fake_product_name /sys/class/dmi/id/product_name
sudo mount --bind /tmp/fake_sys_vendor /sys/class/dmi/id/sys_vendor
sudo mount --bind /tmp/fake_board_vendor /sys/class/dmi/id/board_vendor
sudo mount --bind /tmp/fake_board_name /sys/class/dmi/id/board_name
echo "βœ… DMI values spoofed. Launching GeForce NOW..."

# --- Step 2: Launch GeForce NOW with Flatpak Spoofing ---
# The rest of this is the original flatpak sandboxed launch command
flatpak run --user --command=bash com.nvidia.geforcenow -c '
    # Exit immediately if a command exits with a non-zero status.
    set -e

    # Create the directory that holds the os-release and SSL certs
    mkdir -p /run/host/etc/ssl

    # Create the SteamOS os-release file
    cat > /run/host/etc/os-release << EOL
NAME="SteamOS"
PRETTY_NAME="SteamOS"
VERSION_CODENAME=holo
ID=steamos
ID_LIKE=arch
ANSI_COLOR="1;35"
HOME_URL="https://www.steampowered.com/"
DOCUMENTATION_URL="https://support.steampowered.com/"
SUPPORT_URL="https://support.steampowered.com/"
BUG_REPORT_URL="https://support.steampowered.com/"
LOGO=steamos
VARIANT_ID=steamdeck
VERSION_ID=3.7.13
BUILD_ID=20250630.1
STEAMOS_DEFAULT_UPDATE_BRANCH=stable
EOL

    # Recursively copy the host system'\''s SSL certificates into the sandbox
    cp -r /etc/ssl /run/host/etc/

    # Launch GeForce NOW (this command blocks until the app is closed)
    /app/bin/GeForceNOW
'
EOF

# Make the launcher script executable
chmod +x "$LAUNCHER_SCRIPT_PATH"
echo "βœ… Custom launcher script created at: $LAUNCHER_SCRIPT_PATH"

echo "7. Creating and modifying the main application menu shortcut..."
mkdir -p "$LOCAL_SHARE_APPLICATIONS"
cat > "$MENU_FILE_PATH" << EOF
[Desktop Entry]
Version=1.0
Name=NVIDIA GeForce NOW
GenericName=NVIDIA GeForce NOW
Exec=$LAUNCHER_SCRIPT_PATH
Icon=com.nvidia.geforcenow
Type=Application
Categories=Network;Game;
EOF
echo "βœ… Main menu shortcut modified to use the custom launcher script."

echo "8. Creating/Updating the desktop shortcut and if possible adding GeForce NOW to Steam..."
cp "$MENU_FILE_PATH" "$DESKTOP_FILE_PATH"
echo "βœ… Desktop shortcut created and synchronized with the main menu entry."
if command -v steamos-add-to-steam >/dev/null 2>&1; then
  steamos-add-to-steam "$MENU_FILE_PATH" || steamos-add-to-steam com.nvidia.geforcenow || true
  echo "βœ… GeForce NOW shortcut added to Steam as well."
elif command -v xdg-open >/dev/null 2>&1; then
  xdg-open "steam://AddNonSteamGame" >/dev/null 2>&1 || true
fi

echo "9. Making shortcuts launchable..."
case "$XDG_CURRENT_DESKTOP" in
    *GNOME*|*Cinnamon*|*MATE*|*Budgie*)
        echo "   Detected a GNOME-based desktop. Using 'gio' to trust files."
        /usr/bin/gio set "$MENU_FILE_PATH" metadata::trusted true || echo "⚠️  Warning: Could not trust the main menu shortcut."
        /usr/bin/gio set "$DESKTOP_FILE_PATH" metadata::trusted true || echo "⚠️  Warning: Could not trust the desktop shortcut."
        ;;
    *KDE*|*)
        echo "βœ… Detected KDE or another desktop. Setting executable permissions."
        chmod +x "$MENU_FILE_PATH"
        chmod +x "$DESKTOP_FILE_PATH"
        ;;
esac
echo "βœ… Both shortcuts are now ready to launch."
echo ""
echo "πŸŽ‰ Installation complete! You can now launch GeForce NOW from your desktop OR your application menu."
echo ""
echo "ℹ️  NOTE: To uninstall, you can delete the application and manually remove the files added by this script with:"
echo "   flatpak uninstall --user com.nvidia.geforcenow"
echo "   sudo rm '$SUDOERS_FILE'"
echo "   rm '$LAUNCHER_SCRIPT_PATH' '$MENU_FILE_PATH' '$DESKTOP_FILE_PATH'"```

Hi Dear, can u please create script for ubuntu?

Thank you

@d4vid1
Copy link

d4vid1 commented Jan 3, 2026

I found the issue. In the install script, geforce now is installed with the user flag. However on Debian, the downgrade to the version you need root permission, which is why running flatpak update --noninteractive -y --user --commit=0d56... did not actually downgrade the version. For me it worked installing and then downgrading with the --system flag and not the --user flag.

Hi Dear, after downgrade over terminal i become working version without network problem, but with no 4k and 120hz option , max 1080p60hz , iam ultimate user.

Can u modify ubuntu script with right (working 4k and 120hz version) please?

@LeonardPuettmann
Copy link

@d4vid1 For me this worked:

Installing:

flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install --noninteractive -y --system flathub org.freedesktop.Platform//24.08 || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Sdk//24.08 || true
flatpak remote-add --system --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo 
flatpak install --noninteractive -y --system GeForceNOW com.nvidia.geforcenow 
flatpak update --noninteractive -y --system --commit=0d56051d6c9c81177f685a988d666fa12b647ca25f994e9bb378d4c9305b10c2 com.nvidia.geforcenow
flatpak mask --system com.nvidia.geforcenow

Then I start geforce now with this script:

#!/bin/bash

echo "Starting GeForce NOW with SteamOS os-release file and SSL certs..."

flatpak run --system --command=bash com.nvidia.geforcenow -c '
    set -e

    mkdir -p /run/host/etc/ssl

    cat > /run/host/etc/os-release << EOF
NAME="SteamOS"
PRETTY_NAME="SteamOS"
VERSION_CODENAME=holo
ID=steamos
ID_LIKE=arch
ANSI_COLOR="1;35"
HOME_URL="https://www.steampowered.com/"
DOCUMENTATION_URL="https://support.steampowered.com/"
SUPPORT_URL="https://support.steampowered.com/"
BUG_REPORT_URL="https://support.steampowered.com/"
LOGO=steamos
VARIANT_ID=steamdeck
VERSION_ID=3.7.13
BUILD_ID=20250630.1
STEAMOS_DEFAULT_UPDATE_BRANCH=stable
EOF

    cp -r /etc/ssl /run/host/etc/

    echo "Launching GeForce NOW..."
    /app/bin/GeForceNOW
'

echo "GeForce NOW session ended."

That's really all I did. It is really important that you use the flatpak update to downgrade the app, otherwise it will still be on a newer version. Afterwards you can use the mask command to fix the current version to avoid auto upgrading. Hope that helps.

@d4vid1
Copy link

d4vid1 commented Jan 4, 2026

@d4vid1 For me this worked:

Installing:

flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install --noninteractive -y --system flathub org.freedesktop.Platform//24.08 || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Sdk//24.08 || true
flatpak remote-add --system --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo 
flatpak install --noninteractive -y --system GeForceNOW com.nvidia.geforcenow 
flatpak update --noninteractive -y --system --commit=0d56051d6c9c81177f685a988d666fa12b647ca25f994e9bb378d4c9305b10c2 com.nvidia.geforcenow
flatpak mask --system com.nvidia.geforcenow

Then I start geforce now with this script:

#!/bin/bash

echo "Starting GeForce NOW with SteamOS os-release file and SSL certs..."

flatpak run --system --command=bash com.nvidia.geforcenow -c '
    set -e

    mkdir -p /run/host/etc/ssl

    cat > /run/host/etc/os-release << EOF
NAME="SteamOS"
PRETTY_NAME="SteamOS"
VERSION_CODENAME=holo
ID=steamos
ID_LIKE=arch
ANSI_COLOR="1;35"
HOME_URL="https://www.steampowered.com/"
DOCUMENTATION_URL="https://support.steampowered.com/"
SUPPORT_URL="https://support.steampowered.com/"
BUG_REPORT_URL="https://support.steampowered.com/"
LOGO=steamos
VARIANT_ID=steamdeck
VERSION_ID=3.7.13
BUILD_ID=20250630.1
STEAMOS_DEFAULT_UPDATE_BRANCH=stable
EOF

    cp -r /etc/ssl /run/host/etc/

    echo "Launching GeForce NOW..."
    /app/bin/GeForceNOW
'

echo "GeForce NOW session ended."

That's really all I did. It is really important that you use the flatpak update to downgrade the app, otherwise it will still be on a newer version. Afterwards you can use the mask command to fix the current version to avoid auto upgrading. Hope that helps.

Hi bro,

i follow ur howto, but i become this

LANG=C flatpak update --noninteractive -y --system --commit=0d56051d6c9c81177f685a988d666fa12b647ca25f994e9bb378d4c9305b10c2 com.nvidia.geforcenow

Nothing to do.

i think that commit doesn’t exist more..
it will not downgrade version.

thnx in advance

@laurentpayot
Copy link

Hopefully GFN will natively support Linux soon πŸ™ https://videocardz.com/newz/nvidia-geforce-now-to-gain-native-linux-support

@anthrgk
Copy link

anthrgk commented Jan 7, 2026

Updated script for fedora, with the right geforce client version, the latest update broke everyhting.

# https://gist.github.com/Mihitoko/bd76340e56e78ec972c8a1365abb0d55?permalink_comment_id=5840016#gistcomment-5840016
# GPU check: Verify that the graphics card is from AMD
if ! lspci | grep -i 'VGA' | grep -qi 'amd\|advanced micro devices'; then
    echo "⚠️ This script requires an AMD GPU. Exiting."
    exit 1
fi
echo ""
echo "βœ… AMD GPU detected. So far, so good."
echo ""
# Check if dnf is installed, it should if it's a Fedora distro:
if ! command -v dnf &> /dev/null; then
    echo "⚠️ This script is designed for Fedora and Fedora-based distributions."
    echo "   'dnf' command not found. Exiting."
    exit 1
fi
echo ""
# Exit immediately if a command exits with a non-zero status.
set -e

# --- Configuration ---
# Path for the custom launcher script
LAUNCHER_DIR="$HOME/.local/bin"
LAUNCHER_SCRIPT_PATH="$LAUNCHER_DIR/geforce-now-launcher.sh"

# Define the file name and the two key locations
DESKTOP_FILE_NAME="com.nvidia.geforcenow.desktop"
LOCAL_SHARE_APPLICATIONS="$HOME/.local/share/applications"
MENU_FILE_PATH="$HOME/.local/share/applications/$DESKTOP_FILE_NAME" # The "source" file for the app menu
# Find the user's desktop directory, falling back to "$HOME/Desktop" if the command fails
DESKTOP_DIR=$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop")
# Define the full path for the desktop shortcut
DESKTOP_FILE_PATH="$DESKTOP_DIR/$DESKTOP_FILE_NAME"
# --- NEW: Define sudoers file for passwordless mounting ---
SUDOERS_FILE="/etc/sudoers.d/99-geforcenow-spoof"

echo ""
echo "Before we start we will need to install Flatpak, which requires root permissions to get it installed"
echo ""
if dnf list installed flatpak &> /dev/null; then
    echo "βœ… Flatpak is already installed. Good!"
else
    echo "Flatpak is not installed. We will need to install it, which requires root permissions."
    sudo dnf install -y flatpak
    echo "βœ… Flatpak has been successfully installed."
fi
echo ""

# --- Installation Steps ---
echo "πŸš€ Starting GeForce NOW Installer for AMD Linux Systems..."
echo "1. Adding Flathub repo and installing required Flatpak runtimes..."
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Platform//24.08 || true
flatpak install --noninteractive -y --system flathub org.freedesktop.Sdk//24.08 || true
echo "βœ… Required runtimes installed"

echo "2. Adding the GeForce NOW Flatpak repository..."
flatpak remote-add --user --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo || true
echo "βœ… GeForce NOW repo added"

echo "3. Installing GeForce NOW..."
flatpak uninstall --noninteractive -y --user com.nvidia.geforcenow &>/dev/null || echo "βœ… GeForce NOW not found. Ready for a fresh installation."
flatpak install --noninteractive -y --user GeForceNOW com.nvidia.geforcenow || echo "βœ… App installed. In the next steps we'll apply some custom tweaks so it can work."

# --- MODIFICATION START: Force Specific Version ---
echo "⬇️  Downgrading to requested version: 2.0.78.147..."
flatpak update --noninteractive -y --user --commit=0d56051d6c9c81177f685a988d666fa12b647ca25f994e9bb378d4c9305b10c2 com.nvidia.geforcenow
echo "πŸ”’ Locking version to prevent auto-updates..."
flatpak mask --user com.nvidia.geforcenow
# --- MODIFICATION END ---

mkdir -p "$HOME/.local/share/icons/hicolor/512x512/apps"
curl -sL -o "$HOME/.local/share/icons/hicolor/512x512/apps/com.nvidia.geforcenow.png" https://gitlab.com/anthrgk/geforcenow-installer-linux/-/raw/main/arch/img/com.nvidia.geforcenow.png
echo "βœ… GeForce NOW installed. Tweaking few things so it can launch succesfully..."
echo "4. Applying required Flatpak overrides..."
flatpak override --user --nosocket=wayland com.nvidia.geforcenow
flatpak override --user --nofilesystem=host-etc com.nvidia.geforcenow
echo "βœ… Flatpak overrides applied"

# --- NEW STEP: Configure passwordless sudo for the mounting commands ---
echo "5. Configuring passwordless sudo for automatic system value spoofing..."
echo ""
echo "   This next step is optional, but required if you want to enable up to 4K 120FPS streaming."
echo "   If you agree, your device's system information (product, vendor, and board name) will be temporarily"
echo "   'spoofed' or disguised to look like a different device while GeForce NOW is running."
echo ""
echo "   ⚠️ IMPORTANT: Because of this temporary change, it is strongly recommended NOT to perform"
echo "   any system or software updates while GeForce NOW is open."
echo "   Proceed at your own risk."
echo ""
read -p "   Do you want to proceed? (y/N) " -n 1 -r
echo # Move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
    # Define the exact commands that will be allowed without a password
    SUDOERS_CONTENT="
# Allow user $USER to run mount/umount for GeForce NOW DMI spoofing
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_product_name /sys/class/dmi/id/product_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_sys_vendor /sys/class/dmi/id/sys_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_board_vendor /sys/class/dmi/id/board_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/mount --bind /tmp/fake_board_name /sys/class/dmi/id/board_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/product_name
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/sys_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/board_vendor
$USER ALL=(ALL) NOPASSWD: /usr/bin/umount /sys/class/dmi/id/board_name
"
    # Use tee with sudo to write the file, as we need root privileges
    echo "$SUDOERS_CONTENT" | sudo tee "$SUDOERS_FILE" > /dev/null
    sudo chmod 0440 "$SUDOERS_FILE"
    echo "βœ… Sudoers file created successfully."
else
    echo "⚠️  Skipping sudoers configuration. The launcher will not be able to spoof DMI values."
fi


echo "6. Creating the custom launcher script..."
# Ensure the local bin directory exists
mkdir -p "$LAUNCHER_DIR"
# --- HEAVILY MODIFIED: Create the new launcher script with spoofing and cleanup ---
cat > "$LAUNCHER_SCRIPT_PATH" << 'EOF'
#!/bin/bash
# The first section toggles the GeForce NOW TV Mode.
# It will obviously skip the modification if the directory or config file is not found,
# allowing the rest of the launch script to continue.

# 1. Define the base directory.
CONFIG_JSON_DIR="$HOME/.local/share/flatpak/app/com.nvidia.geforcenow/x86_64/master/"
# 2. Attempt to find the config file path.
CONFIG_FILE=$(find "$CONFIG_JSON_DIR" -type f -name "config.json" -print -quit 2>/dev/null)

# 3. Proceed with modifications ONLY if the config file was found.
if [ -n "$CONFIG_FILE" ]; then
    echo "Found config file: $CONFIG_FILE"

    # Check if we are on a Steam Deck Gaming Mode or we launched the GeForce NOW via Steam, and apply the appropriate setting so it launches with tv layout.
    if [ -n "$SteamDeck" ] && [ "$SteamDeck" -eq 1 ]; then
        echo "App launched via Steam. Enabling TV Mode..."
        sed -i 's/"tvMode": false,/"tvMode": true,/' "$CONFIG_FILE"
        echo "βœ… 'tvMode' set to 'true'."
    else
    # If we aren't on Steam Deck Gaming Mode nor launched GeForce NOW via Steam, it will set GFN with the desktop layout.
        echo "Standard environment detected. Disabling TV Mode..."
        sed -i 's/"tvMode": true,/"tvMode": false,/' "$CONFIG_FILE"
        echo "βœ… 'tvMode' set to 'false'."
    fi
else
    echo "GeForce NOW config not found. Skipping modification."
fi
echo ""
# This section of the script performs two main functions:
# 1. DMI Spoofing: Mounts temporary files to pretend the system is a Steam Deck.
# 2. Flatpak Spoofing: Runs GeForce NOW inside a Flatpak sandbox with a fake os-release.
# It automatically cleans up the DMI mounts when the application is closed.

# --- Function to clean up the mounts and temp files ---
cleanup() {
    echo "GeForce NOW closed. Cleaning up DMI spoof..."
    # Unmount in reverse order, ignoring errors if they are already unmounted
    sudo umount /sys/class/dmi/id/board_name &>/dev/null || true
    sudo umount /sys/class/dmi/id/board_vendor &>/dev/null || true
    sudo umount /sys/class/dmi/id/sys_vendor &>/dev/null || true
    sudo umount /sys/class/dmi/id/product_name &>/dev/null || true

    # Remove the temporary files
    rm -f /tmp/fake_product_name /tmp/fake_sys_vendor /tmp/fake_board_vendor /tmp/fake_board_name
    echo "βœ… Cleanup complete."
}

# --- Trap the exit signal to ensure cleanup always runs ---
# This makes sure the 'cleanup' function is called when the script exits for any reason.
trap cleanup EXIT

# --- Step 1: Perform DMI Spoofing on the host system ---
echo "πŸš€ Applying DMI spoof so we can mimic another device and enable 4k 120FPS with HDR.."
echo "83L3" > /tmp/fake_product_name
echo "Lenovo" > /tmp/fake_sys_vendor
echo "Lenovo" > /tmp/fake_board_vendor
echo "8ARP1" > /tmp/fake_board_name

# Use sudo for the mount commands (passwordless due to sudoers config)
sudo mount --bind /tmp/fake_product_name /sys/class/dmi/id/product_name
sudo mount --bind /tmp/fake_sys_vendor /sys/class/dmi/id/sys_vendor
sudo mount --bind /tmp/fake_board_vendor /sys/class/dmi/id/board_vendor
sudo mount --bind /tmp/fake_board_name /sys/class/dmi/id/board_name
echo "βœ… DMI values spoofed. Launching GeForce NOW..."

# --- Step 2: Launch GeForce NOW with Flatpak Spoofing ---
# The rest of this is the original flatpak sandboxed launch command
flatpak run --user --command=bash com.nvidia.geforcenow -c '
    # Exit immediately if a command exits with a non-zero status.
    set -e

    # Create the directory that holds the os-release and SSL certs
    mkdir -p /run/host/etc/ssl

    # Create the SteamOS os-release file
    cat > /run/host/etc/os-release << EOL
NAME="SteamOS"
PRETTY_NAME="SteamOS"
VERSION_CODENAME=holo
ID=steamos
ID_LIKE=arch
ANSI_COLOR="1;35"
HOME_URL="https://www.steampowered.com/"
DOCUMENTATION_URL="https://support.steampowered.com/"
SUPPORT_URL="https://support.steampowered.com/"
BUG_REPORT_URL="https://support.steampowered.com/"
LOGO=steamos
VARIANT_ID=steamdeck
VERSION_ID=3.7.13
BUILD_ID=20250630.1
STEAMOS_DEFAULT_UPDATE_BRANCH=stable
EOL

    # Recursively copy the host system'\''s SSL certificates into the sandbox
    cp -r /etc/ssl /run/host/etc/

    # Launch GeForce NOW (this command blocks until the app is closed)
    /app/bin/GeForceNOW
'
EOF

# Make the launcher script executable
chmod +x "$LAUNCHER_SCRIPT_PATH"
echo "βœ… Custom launcher script created at: $LAUNCHER_SCRIPT_PATH"

echo "7. Creating and modifying the main application menu shortcut..."
mkdir -p "$LOCAL_SHARE_APPLICATIONS"
cat > "$MENU_FILE_PATH" << EOF
[Desktop Entry]
Version=1.0
Name=NVIDIA GeForce NOW
GenericName=NVIDIA GeForce NOW
Exec=$LAUNCHER_SCRIPT_PATH
Icon=com.nvidia.geforcenow
Type=Application
Categories=Network;Game;
EOF
echo "βœ… Main menu shortcut modified to use the custom launcher script."

echo "8. Creating/Updating the desktop shortcut and if possible adding GeForce NOW to Steam..."
cp "$MENU_FILE_PATH" "$DESKTOP_FILE_PATH"
echo "βœ… Desktop shortcut created and synchronized with the main menu entry."
if command -v steamos-add-to-steam >/dev/null 2>&1; then
  steamos-add-to-steam "$MENU_FILE_PATH" || steamos-add-to-steam com.nvidia.geforcenow || true
  echo "βœ… GeForce NOW shortcut added to Steam as well."
elif command -v xdg-open >/dev/null 2>&1; then
  xdg-open "steam://AddNonSteamGame" >/dev/null 2>&1 || true
fi

echo "9. Making shortcuts launchable..."
case "$XDG_CURRENT_DESKTOP" in
    *GNOME*|*Cinnamon*|*MATE*|*Budgie*)
        echo "   Detected a GNOME-based desktop. Using 'gio' to trust files."
        /usr/bin/gio set "$MENU_FILE_PATH" metadata::trusted true || echo "⚠️  Warning: Could not trust the main menu shortcut."
        /usr/bin/gio set "$DESKTOP_FILE_PATH" metadata::trusted true || echo "⚠️  Warning: Could not trust the desktop shortcut."
        ;;
    *KDE*|*)
        echo "βœ… Detected KDE or another desktop. Setting executable permissions."
        chmod +x "$MENU_FILE_PATH"
        chmod +x "$DESKTOP_FILE_PATH"
        ;;
esac
echo "βœ… Both shortcuts are now ready to launch."
echo ""
echo "πŸŽ‰ Installation complete! You can now launch GeForce NOW from your desktop OR your application menu."
echo ""
echo "ℹ️  NOTE: To uninstall, you can delete the application and manually remove the files added by this script with:"
echo "   flatpak uninstall --user com.nvidia.geforcenow"
echo "   sudo rm '$SUDOERS_FILE'"
echo "   rm '$LAUNCHER_SCRIPT_PATH' '$MENU_FILE_PATH' '$DESKTOP_FILE_PATH'"```

Hey, does this updated version of the script work to get 4k 120fps on Fedora with the latest app version? If so I'll update it in my gitlab repo :)

By the way, apologies to everyone if I'm slow updating https://gitlab.com/anthrgk/geforcenow-installer-linux
I know the batocera and fedora version are outdated there, but I only use Arch so I rather be cautious before updating the installer (unless someone here provides the full script and explicitly confirms that it works with the latest app version AND with 4k 120fps)

Apologies

@KadaGuetouache
Copy link

yes, it's already written by me there: https://gitlab.com/anthrgk/geforcenow-installer-linux/-/tree/main/ubuntu

I'm having a screen tearing issue on Ubuntu tried messing with vsync setting but all the same result it usual one or two lines a top half of the screen

@KadaGuetouache
Copy link

somebody able to run these app on integrated intel VGA?

as 8 Jan 2026 I have intel HD 530 (integrated gpu) and it work out of the box but I have a screen tearing issue on 60hz monitor with fps set to 60 and tried all vsync settings but no luck.

@dawiisss
Copy link

Does anyone have any fixes to the scrolling issue? It seems that now scrolling doesn't work and also if you use two monitors it doesn't capture your mouse inside of the game unless you do the virtual keyboard & mouse through CTRL + G.

@oogetyboogety
Copy link

Does anyone have any fixes to the scrolling issue? It seems that now scrolling doesn't work and also if you use two monitors it doesn't capture your mouse inside of the game unless you do the virtual keyboard & mouse through CTRL + G.

You can fix this with the --force-grab-cursor in the gamescope command

@laurentpayot
Copy link

laurentpayot commented Jan 30, 2026

Hopefully GFN will natively support Linux soon πŸ™ https://videocardz.com/newz/nvidia-geforce-now-to-gain-native-linux-support

GeForce now is now officially supported on linux desktops by Nvidia πŸŽ‰ You can download the beta here.
It works perfectly on my Ubuntu 25.10 machine. Just do a flatpak uninstall geforcenow before launching the Nvidia setup if you already installed the binary following this gist instructions.

@Mihitoko Thanks for this gist, it has been very useful πŸ‘

@robertswiecki
Copy link

robertswiecki commented Jan 31, 2026

Tip: you can remap controller buttons (specifically to swap A/B and X/Y) by setting the SDL_GAMECONTROLLERCONFIG environment variable. The example below is for the 8BitDo Pro 3 Receiver, but you will need to generate a unique mapping string if you are using a different controller (eg. with jstest-sdl)

Note: GeForceNow uses an embedded version of libSDL2.so. So, the mapping string required here might differ from strings generated, if your tools use SDL3 or an SDL3-to-2 shim.

alias gfnow='flatpak run "--env=SDL_GAMECONTROLLERCONFIG=03000000c82d00000b31000000010000,*,a:b1,b:b0,x:b3,y:b2,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,crc:b6f6,platform:Linux" com.nvidia.geforcenow'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment