Here is the script I use. It solved the issues I was having with AppImage. Feel free to use it as you wish - but any usage is at your own risk.
#!/usr/bin/env bash
set -euo pipefail
# ——— variables ———
OUT_DIR=$(pwd)
BASE_URL="https://www.cursor.com/download/stable/linux"
ARCH_DL="$(uname -m)" # for the URL
case "$ARCH_DL" in
aarch64|arm64) ARCH_DL="arm64" ;;
x86_64|amd64) ARCH_DL="x64" ;;
*) echo "Unsupported arch: $ARCH_DL"; exit 1 ;;
esac
APP_URL="${BASE_URL}-${ARCH_DL}"
# ——— download + extract ———
BUILD="$(mktemp -d)"
pushd "$BUILD" >/dev/null
echo "Downloading $APP_URL …"
curl --fail --silent --show-error --location --progress-bar \
-o Cursor.AppImage "$APP_URL"
chmod +x Cursor.AppImage
./Cursor.AppImage --appimage-extract # creates squashfs-root/
# ——— version & staging dir ———
VERSION=$(cat squashfs-root/cursor.desktop | grep "Version=" | cut -d'=' -f2)
PKG=cursor
ARCH_DEB=$(dpkg --print-architecture) # amd64, arm64, …
STAGE="${PKG}_${VERSION}_${ARCH_DEB}"
mkdir -p "$STAGE/DEBIAN"
cp -a squashfs-root/usr "$STAGE/"
# ——— control file ———
INSTALLED_SIZE=$(du -ks "$STAGE" | cut -f1) # KiB
cat > "$STAGE/DEBIAN/control" <<EOF
Package: $PKG
Version: $VERSION
Section: editors
Priority: optional
Architecture: $ARCH_DEB
Depends: libc6 (>= 2.31)
Maintainer: $(whoami) <[email protected]>
Homepage: https://cursor.sh
Installed-Size: $INSTALLED_SIZE
Description: Cursor – AI-powered code editor packaged from upstream AppImage.
Cursor ships as an AppImage; this package re-wraps it for easy apt install.
EOF
# post-install hooks
cat > "$STAGE/DEBIAN/postinst" <<'EOF'
#!/bin/sh
set -e
update-desktop-database -q || true
update-icon-caches /usr/share/icons/hicolor || true
EOF
chmod 755 "$STAGE/DEBIAN/postinst"
# ——— build & install ———
fakeroot dpkg-deb --build "$STAGE"
cp "$STAGE.deb" "$OUT_DIR/"
echo "Built $OUT_DIR/$STAGE.deb"
echo "To install: sudo apt install ./$STAGE.deb"
popd >/dev/null