Skip to content

santojon/Deck-Shelves-API

Repository files navigation

@deck-shelves/api

CI Release npm version npm downloads npm monthly Tests Types Bundle size License Node Platform Plugin host Sponsor Ko-fi

TypeScript API for integrating with Deck Shelves — a Decky plugin that injects configurable shelves into the Steam Deck home screen.

External plugins register sources, smart sources, filter types, sort options, import flows, saved filters, search providers, side-menu entries, context / widget / shelf-renderer / metadata / statistics / recommendation providers through this surface; Deck Shelves consumes the registrations as if they were first-party. Consumers can also read profiles, integrations, settings snapshots and environment info, and react to host load/unload via onReady / onTeardown.

Install

npm install @deck-shelves/api
# or
pnpm add @deck-shelves/api
# or
yarn add @deck-shelves/api

The package is dependency-free (no runtime dependencies, only TypeScript types at build time) and ships both ESM (.mjs) and CJS (.cjs) builds alongside type declarations.

Quick start

import { register } from "@deck-shelves/api";

const off = register({
  name: "my-plugin",
  version: "1.0.0",
  onMount(api) {
    // Register a custom source that other shelves can reference
    api.registerShelfSource({
      id: "my-plugin/recently-rated",
      label: "Recently rated",
      async resolve(limit) {
        const data = await fetch("/api/my-plugin/ratings").then((r) => r.json());
        return data.appids.slice(0, limit);
      },
    });

    // React to focus changes on DS shelves
    api.subscribeFocusedCard((info) => {
      if (!info) return;
      console.log("focused", info.appid, "on shelf", info.shelfId);
    });

    // Build asset URLs without re-implementing Steam's fallback chain
    const heroes = api.getAssetUrls(620, "hero");
    // → ['https://steamloopback.host/assets/620/library_hero.jpg?c=...', ...]
  },
  onUnmount() {
    // Cleanup any cached API references — the api object passed to
    // onMount becomes stale after this.
  },
});

// Call `off()` when your plugin unloads.

How it works

The package handles three timing cases automatically — your code doesn't branch on whether Deck Shelves is already loaded:

  1. DS already loaded → calls register synchronously.
  2. DS loads later → queues your integration and registers it on the deck-shelves:ready event.
  3. Your module loads after the ready event fired → still registers from the pending queue when DS drains.

The returned Unsubscribe works regardless of which case applied.

Capability matrix

Surface Method Snapshot Subscribe
Regular shelf sources registerShelfSource getShelves subscribeShelves
Smart shelf sources registerSmartShelfSource getSmartShelves subscribeSmartShelves
Filter types registerFilterType getRegisteredFilterTypes
Sort options registerSortOption getRegisteredSortOptions
Import / Export types registerImportType / registerExportType getRegisteredImportTypes
Saved filters registerSavedFilter getSavedFilters subscribeSavedFilters
Search providers (v4) registerSearchProvider getRegisteredSearchProviders
Side-menu entries (v4) registerSideMenuProvider getRegisteredSideMenuProviders
Context providers (v4) registerContextProvider getRegisteredContextProviders
Widget providers (v4) registerWidgetProvider getRegisteredWidgetProviders
Shelf renderers (v4) registerShelfRenderer getRegisteredShelfRenderers
Metadata providers (v4) registerMetadataProvider getRegisteredMetadataProviders
Statistics providers registerStatisticsProvider getRegisteredStatisticsProviders
Recommendation providers registerRecommendationProvider getRegisteredRecommendationProviders
Profiles getProfiles / getActiveProfile subscribeProfiles
Integrations getIntegrations subscribeIntegrations
Settings snapshot getSettingsSnapshot subscribeSettingsSnapshot
Focus tracking getFocusedCard subscribeFocusedCard
Asset URLs getAssetUrls(appid, type)
Built-in catalogues listTriggerCatalog / listShelfTemplates / listShortcuts
Environment probes getEnvironment (incl. .os) / hasTabMaster
Lifecycle helpers onReady(cb) / onTeardown(cb) (package exports)

Full surface in src/types.tsDeckShelvesPublicAPI.

Direct API access (advanced)

Most consumers don't need this, but for short-lived scripts (CDP probes, dev tools, one-shot scripts that don't want lifecycle management):

import { getApi, isReady } from "@deck-shelves/api";

if (isReady()) {
  const api = getApi();
  api?.getShelves();
}

Version policy

The version field on DeckShelvesPublicAPI bumps on every breaking change (currently 4). Consumers should check api.version if they need to gate on a specific surface revision.

Development

corepack enable
pnpm install
pnpm run check   # typecheck + lint + test
pnpm run build   # ESM + CJS + .d.ts into dist/

Releases are automated from main: a tag-prefixed PR ([FIX], [FEATURE], [REFACTOR], …) drives the version bump on merge, and the resulting vX.Y.Z tag publishes to npm with provenance.

See CONTRIBUTING.md for the full workflow and SECURITY.md for reporting issues.

License

MIT © santojon

About

Part of Deck Shelves, developed by Jonathan Santos.

ko-fi

About

Deck Shelves data integration API

Resources

License

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors