The web frontend for thunderstore.io and its reusable UI
packages. The main app, cyberstorm-remix, is a
React Router v7 app. It runs against the
Thunderstore backend, which
serves the API in local development.
- Getting started
- Monorepo layout
- Storybook
- Testing
- Working in the monorepo
- Building for production
- Code style
- Troubleshooting
-
Node
^24.16.0(any 24.x from 24.16 up, set inengines; CI/Docker pin the 24.16.0 floor) and pnpm11.5.3(pinned in thepackageManagerfield of the rootpackage.json). Either enable Corepack (corepack enable), which picks up the pinned version automatically, or install pnpm globally (npm install -g pnpm@11.5.3). -
Font Awesome registry access. The UI uses Font Awesome Pro icons, served from a private registry, so configure auth before installing (see the Font Awesome docs):
npm config set "@fortawesome:registry" https://npm.fontawesome.com/ npm config set "//npm.fontawesome.com/:_authToken" <your-token>
git clone git@github.com:thunderstore-io/thunderstore-ui.git
cd thunderstore-ui
pnpm install
pnpm devpnpm dev starts the React Router dev server (on :3000) together with the build
watchers for the UI packages consumed as dist (@thunderstore/cyberstorm,
@thunderstore/cyberstorm-theme, @thunderstore/ts-uploader), so changes to the
app and those packages are picked up automatically.
The app expects the Thunderstore backend to be running, which serves it at
http://thunderstore.localhost (the dev server also
listens directly on http://localhost:3000). See
apps/cyberstorm-remix/README.md for the full
backend-plus-frontend setup.
apps/*— runnable applications. The main one iscyberstorm-remix(the React Router web app);storybookhosts the component sandbox.packages/*— reusable libraries, such as@thunderstore/cyberstorm(components),@thunderstore/cyberstorm-theme(design system), and the data and uploader packages.
Two tools tie it together:
- pnpm workspaces manage the
packages (see
pnpm-workspace.yamlat the repo root) and handle dependency installation and deduplication. - Preconstruct builds and links the local packages,
so you can import them as
@thunderstore/<pkg>instead of via relative paths. Linking runs automatically in thepostinstallhook (pnpm exec preconstruct dev), so you normally don't need to run it yourself.
Storybook is a sandbox for building UI components in isolation, without starting the whole stack. It also showcases existing components to encourage reuse.
pnpm --filter @thunderstore/storybook run storybookStorybook is then available at http://localhost:6006.
When adding components to @thunderstore/cyberstorm, add stories for them under
apps/storybook/src/stories — see the existing files
for examples. To upgrade Storybook when it reports a new version, run the suggested
npx storybook@latest upgrade command in the apps/storybook directory.
Chromatic runs in CI to host Storybook and detect visual changes to stories. Visual changes must be reviewed before the related PR can merge:
- Push your changes as usual. The
chromatic-deploymentjob in.github/workflows/test.ymlbuilds and uploads Storybook to Chromatic. This step only fails if the build or upload itself fails — component changes are not flagged here. - Open a PR as usual.
- If there were visual changes, GitHub shows a pending check ("UI Tests Pending — N changes must be accepted as baselines"). Open its Details link to review and accept or reject the changes in Chromatic. The PR cannot merge until they are accepted.
pnpm --filter @thunderstore/storybook exec chromatic uploads a Storybook manually
(rarely needed, since CI automates it). The Chromatic CLI reads the project
token from the CHROMATIC_PROJECT_TOKEN environment variable (or pass
--project-token); in CI the token comes from the CHROMATIC_CYBERSTORM_TOKEN
Actions secret.
Frontend tests run in Vitest browser mode (Playwright). To keep the environment consistent, use the dedicated test-runner compose file rather than the dev container.
Prerequisite: ./build-secrets/.npmrc must exist (the same Font Awesome
registry auth required for Docker builds — see
Building for production).
pnpm run test:container # run the tests
pnpm run coverage:container # run with coverageTo type-check the whole monorepo, run pnpm run tsc.
Add a dependency to a specific workspace:
pnpm --filter @thunderstore/cyberstorm add react-table @types/react-tableNew packages are scaffolded with plop. Run
pnpm run plop at the repo root and answer the prompts. The templates live in
./plop/package and the generator config in
./plopfile.mjs; update them if package requirements change.
pnpm run build builds the workspace packages with Preconstruct (assuming pnpm install has already run). To build and serve the app itself:
pnpm run build
pnpm --filter @thunderstore/cyberstorm-remix run build
pnpm --filter @thunderstore/cyberstorm-remix run startBuild configuration for some apps lives in docker-compose.remix.build.yml.
Building requires the Font Awesome private-registry credentials: follow the
Font Awesome docs to generate a
~/.npmrc, then copy it to ./build-secrets/.npmrc.
Build secrets are not supported by the
docker-composePython package — use the built-indocker composesubcommand.
docker compose -f docker-compose.remix.build.yml buildpre-commit enforces code style (Prettier, Stylelint, and
ESLint). Install the hooks once with pre-commit install; they then run
automatically on commit and will block — and often auto-fix — style issues. Re-stage
the fixed files and commit again. CI runs the same checks, so commits that skip them
(--no-verify) will fail there.
Symlink errors after pnpm install on Windows. Enable Developer Mode in Windows
settings. See
preconstruct#381.
Wrong pnpm version. The expected version is pinned in the packageManager
field of the root package.json. With Corepack enabled (corepack enable), the
pinned version is used automatically; otherwise update your global install with
npm install -g pnpm@11.5.3.
