TTS Workshop

Search the Tabletop Simulator Steam Workshop, fetch full TTS save files, and analyze their contents. A lightweight, client-only pnpm monorepo.

Packages

Package Role Runtime
apps/proxy Hono HTTP server: Workshop search + save fetch Node
packages/tts Fetch save from Steam, BSON-parse to TTSMod Node
packages/extract Analyze a TTSMod: objects, asset refs, downloads Isomorphic
packages/shared Shared types + zod schemas Isomorphic

See docs/architecture.md for the architecture and docs/implementation-plan.md for the plan.

Setup

pnpm install
cp .env.example .env   # then set STEAM_API_KEY
pnpm dev               # runs the proxy at http://localhost:3000

Get a Steam Web API key at https://steamcommunity.com/dev/apikey (free).

API

Method Path Description
GET /health Liveness
GET /search?q=&page= Search the Workshop (scrapes browse page)
GET /items/:id Full parsed TTSMod (BSON save)
GET /items/:id/file Raw save bytes, filename from header

Commands

pnpm dev          # run the proxy (tsx watch)
pnpm build        # compile all packages
pnpm typecheck    # typecheck all packages
pnpm test         # run the unit tests (vitest)
pnpm lint         # lint all packages

How search works

Steam has no official search API. The proxy fetches the Workshop browse page (steamcommunity.com/workshop/browse/?appid=286160) and parses the embedded window.SSR.renderContext JSON (a React Query cache containing a workshop_browse entry with the results). This is more robust than scraping the DOM, but Steam can still change the page structure — if search breaks, that parser is the first place to look.

Notes

  • STEAM_API_KEY is only needed for /items/* (resolving file_url). Search works without it.
  • Each request fetches fresh; there is no caching by design (client-only tool).
  • packages/extract has zero runtime dependencies and runs in browser or Node, ready for a future frontend.
S
Description
No description provided
Readme
2.5 MiB
Languages
TypeScript 98.8%
JavaScript 1%
HTML 0.2%