Skip to main content

steam-shortcuts

A portable Python library and command-line tool for adding non-Steam shortcuts to a local Steam profile without GUI automation.

It edits only Steam's per-user binary userdata/<steam-id>/config/shortcuts.vdf, never localconfig.vdf. Before replacing an existing shortcut file it creates a timestamped sibling backup, uses an atomic replacement, then rereads the VDF and verifies the exact shortcut it added.

Steam must be fully closed before using add. The tool refuses to write if it detects the main steam or steam.exe process. It will not murder Steam for you; that is a feature, not a missing feature.

Status and support

  • Windows is the primary acceptance target for Windows executable paths.
  • Steam discovery supports Windows registry/default locations, common Linux locations (including Flatpak), and macOS.
  • If a Steam root has multiple numeric profiles, --steam-id is required. The tool never guesses an account.
  • The first release intentionally does not add artwork, modify Steam Cloud or localconfig.vdf, restart Steam, launch games, or drive the Steam UI.

Install

Until this distribution is published, install a checkout into an isolated pipx environment:

pipx install .
steam-shortcuts --help

After a published release exists, the equivalent will be:

pipx install steam-shortcuts

After a published release exists, use it as a library in another Python project:

python -m pip install steam-shortcuts

Command-line use

First, inspect the local Steam installation and profiles:

steam-shortcuts detect --json
steam-shortcuts list --steam-id 123456789 --json

Add a Windows executable. Quote the shell argument normally; do not add the internal Steam quotes yourself:

steam-shortcuts add \
  --steam-id 123456789 \
  --name "My Game" \
  --exe "D:\Games\My Game\Game.exe" \
  --start-dir "D:\Games\My Game" \
  --args "--windowed" \
  --tag "Local" \
  --json

Use --dry-run first whenever you are doing something unusual. It validates Steam discovery, profile selection, the executable, duplicates, and the planned fields without writing a VDF or backup:

steam-shortcuts add \
  --steam-id 123456789 \
  --name "My Game" \
  --exe "D:\Games\My Game\Game.exe" \
  --dry-run --json

For portable or nonstandard installs, give the Steam root — the directory that contains userdata, not the VDF file itself:

steam-shortcuts add \
  --steam-root "E:\PortableSteam" \
  --steam-id 123456789 \
  --name "My Game" \
  --exe "D:\Games\My Game\Game.exe"

A successful JSON result includes status, profile_id, shortcuts_path, a 32-bit shortcut ID, steam://rungameid/..., and backup_path. Rerunning the exact name/executable combination returns already_exists and creates no backup. Reusing an executable under a different display name is deliberately a conflict rather than a surprise duplicate.

Restart Steam normally after a successful add so it reloads shortcuts.vdf; then the item should appear in the library.

Python API

from pathlib import Path
from steam_shortcuts import add_shortcut

result = add_shortcut(
    name="My Game",
    executable=Path(r"D:\Games\My Game\Game.exe"),
    start_dir=Path(r"D:\Games\My Game"),
    launch_options="--windowed",
    tags=("Local",),
    steam_id="123456789",  # omit only when exactly one profile exists
)

print(result.status, result.run_game_url, result.backup_path)

The API and CLI run on the same local user account that owns the Steam profile. They do not communicate with a Steam account, web API, or remote computer.

Recovery

For an existing VDF, every successful mutation creates a sibling backup named like:

shortcuts.vdf.bak.20261112T020000Z

If Steam rejects or does not show an added shortcut:

  1. Fully exit Steam.
  2. Preserve the current shortcuts.vdf for investigation instead of deleting it.
  3. Replace it with the timestamped .bak.* file from the same directory.
  4. Start Steam and verify the prior library state.

A malformed VDF is rejected without overwriting it. Keep that file and its error message; it is evidence, not clutter.

Development

python -m venv .venv
.venv/bin/python -m pip install -e ".[dev]"
.venv/bin/python -m pytest -q
.venv/bin/ruff check .
.venv/bin/mypy src
.venv/bin/python -m build

See docs/acceptance-test.md for the real Steam-client validation procedure.

Public releases

Public releases are created by pushing a semantic version tag such as v0.1.0. The release workflow rebuilds the package, runs tests, linting, and type checks, then publishes with PyPI Trusted Publishing through GitHub OIDC. It intentionally contains no long-lived PyPI API token.

Before the first release, configure a pending PyPI trusted publisher for project steam-shortcuts, GitHub owner msrodrigobr, repository steam-shortcuts, workflow filename publish.yml, and the protected GitHub environment pypi. A pending publisher does not reserve a project name; publish promptly after configuration.

Metadata

Release files for steam-shortcuts 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for steam-shortcuts 0.1.0
File Size Uploaded Provenance Actions
steam_shortcuts-0.1.0.tar.gz 21.1 kB Without provenance Details for steam_shortcuts-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for steam-shortcuts 0.1.0
File Interpreter ABI Platform Actions
steam_shortcuts-0.1.0-py3-none-any.whl Python 3 none any Details for steam_shortcuts-0.1.0-py3-none-any.whl

Total release size: 38.6 kB

Release files / steam_shortcuts-0.1.0.tar.gz

Download URL steam_shortcuts-0.1.0.tar.gz
Size 21.1 kB
Tags Source
SHA-256 checksum
How to use checksums
96d0cc0c48ed943e094549ee9ff11936f822e6f8e818c2889fd2960f14061de8
BLAKE2b-256 checksum
How to use checksums
343903a0ad1bf3758446f756030a20f8e760bb7781ff1ea7e975de88d0d8cfe4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.9

Release files / steam_shortcuts-0.1.0-py3-none-any.whl

Download URL steam_shortcuts-0.1.0-py3-none-any.whl
Size 17.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e722a5739356c90b81f858f127203c2360571215faf5c5e53a8b881afe918f1
BLAKE2b-256 checksum
How to use checksums
5dba7652c4b19a7c853b7b90fa68b5fdb6d59dbee777e9a90b174146152c76ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.9

Security for steam-shortcuts 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page