How to Add Custom Platform Support to RomM: A Complete Developer Guide

To add custom platform support to RomM, you must insert a new lowercase, hyphen-separated slug into the UniversalPlatformSlug enum in backend/handler/metadata/base_handler.py and optionally provide metadata mappings in the provider handler files.

RomM discovers its supported platforms through a centralized enumeration that serves as the single source of truth for the entire application. When you need to extend RomM to recognize new or obscure gaming systems, the backend relies on specific enum entries and provider mappings to fetch metadata and populate the API. This guide demonstrates the exact file locations and code modifications required in the rommapp/romm source code to register a custom platform.

Understanding the Platform Discovery Architecture

RomM uses the UniversalPlatformSlug enum defined in backend/handler/metadata/base_handler.py as the definitive registry of all supported platforms. All runtime components—including API endpoints, the web interface, and documentation generators—iterate over this enum to determine available platforms. The system automatically pulls metadata from various provider adapters such as IGDB, MobyGames, ScreenScraper, and RetroAchievements based on mappings defined in their respective handler files.

Step 1: Insert the New Slug into UniversalPlatformSlug

Open backend/handler/metadata/base_handler.py and locate the UniversalPlatformSlug class definition. Add your new platform as an enum member using lowercase, hyphen-separated formatting:


# backend/handler/metadata/base_handler.py

class UniversalPlatformSlug(enum.StrEnum):
    # … existing entries …

    MY_CUSTOM_CONSOLE = "my-custom-console"

The slug must be unique across the enum and follow the kebab-case naming convention (lowercase words separated by hyphens). This identifier becomes the canonical reference used throughout RomM's backend and API.

Step 2: Map Provider Metadata

While the enum entry registers the platform, you must supply metadata mappings to enable rich data fetching from external providers. Each provider maintains a handler file with a mapping dictionary keyed by the slug.

Adding IGDB Support

For IGDB integration, edit backend/handler/metadata/igdb_handler.py and add an entry to the IGDB_PLATFORM_MAP dictionary:


# backend/handler/metadata/igdb_handler.py

IGDB_PLATFORM_MAP = {
    # … existing entries …

    "my-custom-console": {
        "igdb_id": 99999,
        "name": "My Custom Console",
        "url_logo": "https://example.com/logo.png",
    },
}

If a provider does not have data for your platform, you can omit the mapping entirely. RomM will automatically fall back to generic placeholder values generated by backend/utils/platforms.py.

Step 3: Regenerate the Supported Platforms Documentation

After modifying the enum and provider mappings, run the documentation generator script to update the public-facing platform list:

cd backend
uv run python -m tools.generate_supported_platforms > ../docs/Supported-Platforms.md

This script walks the UniversalPlatformSlug enum, gathers the provider IDs you configured, and outputs a Markdown table used in the RomM documentation. The tool requires no additional configuration—it automatically reads your new enum entries.

Database Persistence and UI Verification

When the RomM backend starts, backend/utils/platforms.py calls get_supported_platforms() to synchronize the enum with the database. For any slug not already present in the database, the system creates a Platform model instance with placeholder values via db_platform_handler. No database migration is required unless you want to pre-populate specific fields.

To verify your changes:

  1. Start the backend: uv run main.py
  2. Start the frontend: npm run dev
  3. Query the API endpoint:
curl http://localhost:3000/api/platforms | jq '.[] | select(.slug=="my-custom-console")'

The response should include the IGDB fields you supplied, along with any other provider links. Check the "Platforms" section in the web UI to confirm the new entry appears with the appropriate icons and metadata.

Summary

Frequently Asked Questions

What naming convention should I use for custom platform slugs?

RomM requires kebab-case formatting (lowercase words separated by hyphens) for all platform slugs. For example, use "my-custom-console" rather than "MyCustomConsole" or "my_custom_console". This convention ensures consistency across API endpoints, database queries, and file system operations throughout the application.

Do I need to create a database migration when adding a new platform?

No. RomM automatically persists new platform entries to the database when get_supported_platforms() runs during startup. The function in backend/utils/platforms.py checks for existing database records and creates placeholder entries for any missing slugs defined in UniversalPlatformSlug. You only need a manual migration if you want to pre-populate specific metadata fields beyond the defaults.

Can I add a platform without IGDB or other metadata providers?

Yes. Simply add the slug to UniversalPlatformSlug in backend/handler/metadata/base_handler.py and skip the provider mappings. RomM will display the platform using generic placeholder values generated by the platform utility functions. However, providing at least one provider mapping (such as IGDB) is recommended to ensure rich metadata including logos and release dates.

Where does RomM store the platform definitions after I add them?

RomM stores platform definitions in two locations: the code and the database. The UniversalPlatformSlug enum in backend/handler/metadata/base_handler.py serves as the master list, while backend/utils/platforms.py syncs these entries to the Platform model in the database via SQLAlchemy. The frontend consumes this data through the API at /api/platforms.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →