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

> Learn how to add custom platform support to RomM with this developer guide. Integrate new platforms by updating slugs and metadata mappings in the RomM repository.

- Repository: [The RomM Project/romm](https://github.com/rommapp/romm)
- Tags: how-to-guide
- Published: 2026-07-05

---

**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`](https://github.com/rommapp/romm/blob/main/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`](https://github.com/rommapp/romm/blob/main/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`](https://github.com/rommapp/romm/blob/main/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:

```python

# 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`](https://github.com/rommapp/romm/blob/main/backend/handler/metadata/igdb_handler.py) and add an entry to the `IGDB_PLATFORM_MAP` dictionary:

```python

# 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`](https://github.com/rommapp/romm/blob/main/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:

```bash
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`](https://github.com/rommapp/romm/blob/main/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:

```bash
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

- **RomM uses `UniversalPlatformSlug`** in [`backend/handler/metadata/base_handler.py`](https://github.com/rommapp/romm/blob/main/backend/handler/metadata/base_handler.py) as the single source of truth for platform discovery.
- **Add new platforms** by inserting a lowercase, hyphen-separated slug into the enum.
- **Provide metadata** by mapping the slug to provider IDs in handler files like [`backend/handler/metadata/igdb_handler.py`](https://github.com/rommapp/romm/blob/main/backend/handler/metadata/igdb_handler.py).
- **Update documentation** by running [`backend/tools/generate_supported_platforms.py`](https://github.com/rommapp/romm/blob/main/backend/tools/generate_supported_platforms.py) after making changes.
- **Verification** occurs automatically through `get_supported_platforms()` in [`backend/utils/platforms.py`](https://github.com/rommapp/romm/blob/main/backend/utils/platforms.py), which syncs enum entries to the database and serves them via the API.

## 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`](https://github.com/rommapp/romm/blob/main/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`](https://github.com/rommapp/romm/blob/main/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`](https://github.com/rommapp/romm/blob/main/backend/handler/metadata/base_handler.py) serves as the master list, while [`backend/utils/platforms.py`](https://github.com/rommapp/romm/blob/main/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`.