Skip to content

Instantly share code, notes, and snippets.

@andrescera
Last active October 23, 2025 19:00
Show Gist options
  • Save andrescera/13c422a07c50257e44b4f73d7fccb2d5 to your computer and use it in GitHub Desktop.
Save andrescera/13c422a07c50257e44b4f73d7fccb2d5 to your computer and use it in GitHub Desktop.
Install cursor on Linux, tested on Ubuntu 25.04
#!/usr/bin/env bash
# inspired by https://gitrollup.com/r/install-cursor.sh
set -euo pipefail
# =========================
# Cursor (Patched) Installer
# =========================
INSTALL_DIR="/opt"
APP_DIR_NAME="Cursor-patched"
FINAL_APP_PATH="$INSTALL_DIR/$APP_DIR_NAME"
EXECUTABLE_SYMLINK="/usr/local/bin/cursor"
ICON_NAME="cursor-ai.png"
ICON_PATH="/usr/share/icons/hicolor/512x512/apps/$ICON_NAME"
ICON_URL="https://img.icons8.com/nolan/512/cursor-ai.png"
DESKTOP_ENTRY_NAME="cursor-patched.desktop"
DESKTOP_ENTRY_PATH="/usr/share/applications/$DESKTOP_ENTRY_NAME"
ARCH_DEFAULT="$(uname -m)"
case "$ARCH_DEFAULT" in
x86_64) ARCH="x64" ;;
aarch64|arm64) ARCH="arm64" ;;
*) ARCH="x64" ;;
esac
ARCH="${ARCH:-x64}"
PATCH_MARKETPLACE="${PATCH_MARKETPLACE:-0}"
DOWNLOAD_PAGE="https://cursor.com/download"
UA="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/126 Safari/537.36"
TEMP_DOWNLOAD_DIR="$(mktemp -d)"
APPIMAGE_PATH="$TEMP_DOWNLOAD_DIR/Cursor.AppImage"
cleanup() { rm -rf "$TEMP_DOWNLOAD_DIR" >/dev/null 2>&1 || true; }
trap cleanup EXIT
require_root() {
if [ "${EUID:-$(id -u)}" -ne 0 ]; then
echo "Please run this script as root (e.g., sudo)." >&2
exit 1
fi
}
ensure_deps() {
echo "--> Ensuring dependencies..." >&2
if command -v apt-get >/dev/null 2>&1; then
apt-get update -y >/dev/null 2>&1 || true
apt-get install -y curl wget libfuse2 gtk-update-icon-cache >/dev/null 2>&1 || true
fi
command -v curl >/dev/null || { echo "curl is required" >&2; exit 1; }
command -v wget >/dev/null || { echo "wget is required" >&2; exit 1; }
}
resolve_cursor_appimage() {
local arch="${1:-x64}"
local html url file ver
echo "--> Fetching $DOWNLOAD_PAGE ..." >&2
html="$(curl -fSsSL -A "$UA" --max-time 25 "$DOWNLOAD_PAGE")"
url="$(printf "%s" "$html" \
| grep -oE "https://downloads\.cursor\.com/[^\"']+/linux/${arch}/[^\"']+\.AppImage" \
| head -n1 || true)"
if [ -z "$url" ]; then
echo "Error: could not locate a Linux/${arch} AppImage link." >&2
exit 1
fi
file="$(basename "$url")"
ver="$(printf "%s" "$file" | grep -oE '(?<=Cursor-)[0-9]+(\.[0-9]+){1,3}([-_a-zA-Z0-9]+)?' || true)"
echo "--> Found AppImage:" >&2
echo " URL: $url" >&2
[ -n "$ver" ] && echo " Version: $ver" >&2 || echo " Version: (unparsed)" >&2
# stdout → just the URL
printf '%s\n' "$url"
}
download_appimage() {
local url="$1"
echo "--> Downloading AppImage..." >&2
curl -fL -A "$UA" "$url" -o "$APPIMAGE_PATH"
chmod +x "$APPIMAGE_PATH"
}
extract_appimage() {
echo "--> Extracting AppImage to $FINAL_APP_PATH ..." >&2
rm -rf "$FINAL_APP_PATH"
( cd "$TEMP_DOWNLOAD_DIR" && "$APPIMAGE_PATH" --appimage-extract )
mv "$TEMP_DOWNLOAD_DIR/squashfs-root" "$FINAL_APP_PATH"
}
maybe_patch_marketplace() {
local product_json
product_json="$(find "$FINAL_APP_PATH" -type f -path '*/resources/app/product.json' | head -n1 || true)"
if [ -z "$product_json" ]; then
echo " product.json not found. Skipping marketplace patch." >&2
return
fi
if [ "$PATCH_MARKETPLACE" = "1" ]; then
echo "--> Applying legacy VS Code marketplace patch..." >&2
sed -i 's|"serviceUrl": "https://marketplace.cursorapi.com/_apis/public/gallery"|"serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery"|g' "$product_json"
sed -i 's|"itemUrl": "https://marketplace.cursorapi.com/items"|"itemUrl": "https://marketplace.visualstudio.com/items"|g' "$product_json"
sed -i 's|"resourceUrlTemplate": "https://marketplace.cursorapi.com/{publisher}/{name}/{version}/{path}"|"resourceUrlTemplate": "https://{publisher}.vscode-unpkg.net/{publisher}/{name}/{version}/{path}"|g' "$product_json"
else
echo " Skipping marketplace patch (PATCH_MARKETPLACE=0)." >&2
fi
}
install_icon_and_launcher() {
echo "--> Installing icon and launcher..." >&2
mkdir -p "$(dirname "$ICON_PATH")"
wget -q -O "$ICON_PATH" "$ICON_URL" || true
gtk-update-icon-cache /usr/share/icons/hicolor >/dev/null 2>&1 || true
ln -sf "$FINAL_APP_PATH/AppRun" "$EXECUTABLE_SYMLINK"
cat > "$DESKTOP_ENTRY_PATH" <<EOL
[Desktop Entry]
Name=Cursor (Patched)
Comment=The AI-first Code Editor
Icon=$ICON_NAME
StartupWMClass=Cursor
Exec=$EXECUTABLE_SYMLINK %U
Type=Application
Categories=Development;IDE;
Terminal=false
EOL
}
main() {
require_root
ensure_deps
echo "--> Target architecture: ${ARCH}" >&2
url="$(resolve_cursor_appimage "$ARCH")"
download_appimage "$url"
extract_appimage
maybe_patch_marketplace
install_icon_and_launcher
echo "✅ Installation complete. Run 'cursor' or find it in your app menu." >&2
}
main "$@"

Cursor Patched Installer

This script provides a system-wide installer for Cursor, the AI-first code editor.
It was originally inspired by install-cursor.sh, but as Cursor's release page and API changed, the original script no longer works reliably.
We adapted and improved the script to ensure it stays functional with the latest Cursor releases.


Improvements Over the Original Script

  • Dynamic scraping of the official downloads page (https://cursor.com/download) to always fetch the latest Linux AppImage (x64 or arm64).
  • Robust error handling with proper exit codes and sanity checks.
  • Architecture detection (x86_64x64, aarch64arm64).
  • System-wide installation to /opt/Cursor-patched.
  • Symlink in PATH at /usr/local/bin/cursor for easy launching.
  • Desktop entry + icon installation for menu integration.
  • Optional legacy VS Code marketplace patch (disabled by default).

Quick Install

Run directly from the gist:

curl -sSL https://gist.githubusercontent.com/andrescera/13c422a07c50257e44b4f73d7fccb2d5/raw/install-cursor-on-linux.sh | sudo bash

This will:

  • Detect your architecture (x64 or arm64).
  • Scrape the latest Cursor AppImage URL from the official downloads page.
  • Extract and install Cursor under /opt/Cursor-patched.
  • Create a symlink /usr/local/bin/cursor.
  • Install a system-wide icon and .desktop launcher.

Usage

After installation, launch Cursor:

  • From your application menu → Cursor (Patched)
  • Or run directly in the terminal:
cursor

Optional Settings

  • Force architecture (if detection fails):

    ARCH=arm64 curl -sSL https://gist.githubusercontent.com/andrescera/13c422a07c50257e44b4f73d7fccb2d5/raw/install-cursor-on-linux.sh | sudo bash
  • Enable VS Code Marketplace patch (not guaranteed to work on latest builds):

    PATCH_MARKETPLACE=1 curl -sSL https://gist.githubusercontent.com/andrescera/13c422a07c50257e44b4f73d7fccb2d5/raw/install-cursor-on-linux.sh | sudo bash

Notes

  • Requires curl, wget, libfuse2, and gtk-update-icon-cache (installed automatically on Debian/Ubuntu).
  • If the downloads page HTML changes significantly, the regex inside the script may need updating.
  • Unlike the old JSON API method, this approach should remain stable as it scrapes the actual public release page.

License

This installer is provided as-is, without warranty.
Inspired by install-cursor.sh and improved for reliability with current Cursor releases.

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