Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM node:24-bookworm

# Install system dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends iptables socat \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /workspace

# Copy entrypoint script
COPY apps/cyberstorm-remix/entrypoint.dev.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["yarn", "workspace", "@thunderstore/cyberstorm-remix", "dev", "--port", "3000", "--host", "0.0.0.0"]
230 changes: 70 additions & 160 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,163 +2,73 @@

[![codecov](https://codecov.io/gh/thunderstore-io/thunderstore-ui/branch/master/graph/badge.svg)](https://codecov.io/gh/thunderstore-io/thunderstore-ui)

Monorepo containing Remix frontend for [thunderstore.io](https://thunderstore.io)
and reusable UI components.

## Monorepo Setup

- [`yarn` workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) manages
the packages in the monorepo (see `packages` key in base `package.json` file)
and handles dependency installation/deduplication.
- [`preconstruct`](https://preconstruct.tools/) automates building and linking
the packages within the monorepo. Instead of using relative paths, local
packages can be imported as if they were installed via a package manager.
- Packages can be linked locally by running `yarn preconstruct dev`, but this
is handled automatically by `postinstall` hook, so developers don't need to
worry about it.

```
// first time setup
git clone git@github.com:thunderstore-io/thunderstore-ui.git thunderstore-ui
cd thunderstore-ui
yarn install

// start Remix dev server
yarn workspace @thunderstore/cyberstorm-remix dev
```

That's it. Changes done to `apps/cyberstorm-remix` and
`packages/cyberstorm` should both be automatically visible at
[http://localhost:3000/].

```
// production build, assumes yarn install has already been run
// build packages/* with preconstruct
yarn build

// build and start Remix prod server
yarn workspace @thunderstore/cyberstorm-remix build
yarn workspace @thunderstore/cyberstorm-remix start
```

### Troubleshooting

#### After runinng `yarn install` on Windows, you see symlinking errors

**Solution**: Enable developer mode in windows settings.
See https://github.com/preconstruct/preconstruct/issues/381 for more details

#### Yarn error `expected workspace package to exist for X`

**Solution**: Downgrade yarn to a working version by running
`yarn policies set-version 1.19.0`. See
https://github.com/yarnpkg/yarn/issues/8405 for more details.

### Adding dependencies

To add new dependencies to existing packages, simply run something like:

```
yarn workspace @thunderstore/cyberstorm add react-table @types/react-table
```

### Adding a new package

**Template**

This repository includes a templated package generation script, powered by
[plop](https://plopjs.com/documentation/). The templates can be found in
[./plop/package](./plop/package) and should be updated if the requirements
for new packages change.

Behavior of plop is controlled in a single JS file at
[./plopfile.mjs](./plopfile.mjs)

**Generating**

To actually generate a new package stub, simply run `yarn run plop` at the
root of the repository. You should be prompted with a handful of questions after
which a new package is created.

![Plop generation example](./docs/plop.png)

### About VS Code...

VS Code may have problem detecting installed packages in this monorepo/workspace
setup. Installing
[Monorepo Workspace extension](https://marketplace.visualstudio.com/items?itemName=folke.vscode-monorepo-workspace)
may solve them.

## Storybook

[Storybook](https://storybook.js.org/docs/react/get-started/introduction)
provides a sandbox to build UI components in isolation, without having to start
up the whole service stack. Additionally it showcases the existing components,
promoting reusability.

To start Storybook, run `yarn workspace @thunderstore/cyberstorm-storybook storybook`.
Storybook can then be accessed at [http://localhost:6006/].

When creating new components for `@thunderstore/cyberstorm`, add stories for
them by creating files under `apps/cyberstorm-storybook/stories`. See the
existing files for examples.

To upgrade Storybook when it informs you about new version being available, run
the given `npx sb@latest upgrade` command in `apps/cyberstorm-storybook`
directory.

### Chromatic

[Chromatic](https://www.chromatic.com/docs/) is used as a part of CI pipeline.
It hosts Storybook, and detects visual changes to any stories. These changes
needs to be reviewed before a related PR can be merged. The workflow is:

1. Commit and push the changes as usual. `storybook-chromatic.yml` Action
builds and uploads a new version of our Storybook to Chromatic. Note that
this step only fails if there's error building or uploading the Storybook -
any changes to components are not important at this point.
2. Create a PR as usual.
3. If there were visual changes, GitHub will show a pending action: _"UI Tests
Pending — 10 changes must be accepted as baselines."_ Clicking the *Details*
link will take you to Chromatic, where you must review and either accept or
reject the changes. The PR can't be merged before the changes are accepted.

`yarn workspace @thunderstore/cyberstorm-storybook chromatic` can be used to
manually upload a Storybook to Chromatic, but this seems unnecessary since we
have it automated. To use the manual method, `CHROMATIC_CYBERSTORM_TOKEN` env
variable needs to be set (in the repo it's stored as a Secret for Actions).

## Docker Compose

The build configuration for some apps is included in the
`docker-compose.build.yml` file, making building of the services simple.

**You will need to ensure all configured secrets are present before building
with docker compose.** Currently the only required secret is the `.npmrc` file,
which should include authentication to the font awesome private registry. See
[Font Awesome documentation](https://fontawesome.com/docs/web/setup/packages)
for more info on how to authenticate with npm, and then copy the `~/.npmrc` file
it generates to the `./build-secrets` directory.

**Build secrets are unsupported in the `docker-compose` python package, you must
use the built-in `docker compose` subcommand instead.**

Once the build-time secrets are available, building the services is as simple as
running:

```bash
docker compose -f docker-compose.build.yml build
```

## pre-commit

[Pre-commit](https://pre-commit.com/) enforces code style practices in this
project. Choose your preferred
[installation method](https://pre-commit.com/#install) and then run `pre-commit
install` to enable Git hook scripts. Pre-commit will now automatically cancel
your commits if any problems are detected, and autofix them. Stage the changed
files to your commit and re-run the commit command.

Pre-commit can be disabled for a single commit with `--no-verify` option, but
note that CI also runs pre-commit and will fail if any problems are encountered
at this stage.
This monorepo contains the frontend applications and shared libraries for [thunderstore.io](https://thunderstore.io).

## 🚀 Key Projects

### [Nimbus (Cyberstorm Remix)](./apps/cyberstorm-remix/README.md)
The next-generation frontend for Thunderstore, built with Remix.
👉 **[Read the Setup Guide](./apps/cyberstorm-remix/README.md)** to get started with the full stack (Frontend + Backend).

### [Storybook](./apps/cyberstorm-storybook)
Component library and design system documentation.
- Run: `yarn workspace @thunderstore/cyberstorm-storybook storybook`
- URL: [http://localhost:6006/](http://localhost:6006/)

## 📦 Packages

Shared libraries located in `packages/`:

### Core UI
- **[`cyberstorm`](./packages/cyberstorm)**: Core React components and design system.
- **[`cyberstorm-forms`](./packages/cyberstorm-forms)**: Form components for Cyberstorm.
- **[`cyberstorm-theme`](./packages/cyberstorm-theme)**: Theme definitions and utilities.

### Data & API
- **[`dapper`](./packages/dapper)**: Data Provider interfaces and types (React Context).
- **[`dapper-ts`](./packages/dapper-ts)**: Production implementation of Dapper using the Thunderstore API.
- **[`dapper-fake`](./packages/dapper-fake)**: Fake implementation of Dapper for testing and development.
- **[`thunderstore-api`](./packages/thunderstore-api)**: Low-level Thunderstore API client.
- **[`ts-api-react`](./packages/ts-api-react)**: React hooks and integration for the API.
- **[`ts-api-react-actions`](./packages/ts-api-react-actions)**: React actions logic for the API.
- **[`ts-api-react-forms`](./packages/ts-api-react-forms)**: React forms logic for the API.

### Utilities
- **[`beta-switch`](./packages/beta-switch)**: Helper for switching between projects on the same domain.
- **[`graph-system`](./packages/graph-system)**: Graph execution system (Nodes/Edges).
- **[`react-dnd`](./packages/react-dnd)**: React drag & drop hooks.
- **[`ts-uploader`](./packages/ts-uploader)**: File upload logic.
- **[`ts-uploader-react`](./packages/ts-uploader-react)**: React components for file uploads.
- **[`typed-event-emitter`](./packages/typed-event-emitter)**: Strongly typed event emitter.
- **[`use-promise`](./packages/use-promise)**: React hook for resolving promises with Suspense support.

## 🛠️ Monorepo Tooling

This project uses:
- **[Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/)**: Dependency management.
- **[Preconstruct](https://preconstruct.tools/)**: Links packages locally so changes are reflected immediately without rebuilding.
- **[Plop](https://plopjs.com/)**: Scaffolding for new packages (`yarn run plop`).

### Common Commands

| Command | Description |
| :--- | :--- |
| `yarn install` | Install dependencies for all packages. |
| `yarn build` | Build all packages using Preconstruct. |
| `yarn workspace <name> <cmd>` | Run a command in a specific package. |

## 🤝 Contributing

### Pre-commit Hooks
We use [pre-commit](https://pre-commit.com/) to enforce code style.
1. Install pre-commit: [Installation Guide](https://pre-commit.com/#install)
2. Enable hooks: `pre-commit install`

### Visual Testing (Chromatic)
Pull requests automatically run visual regression tests via [Chromatic](https://www.chromatic.com/). You may need to accept baseline changes in the Chromatic UI before merging.

### VS Code
Recommended extensions:
- [Monorepo Workspace](https://marketplace.visualstudio.com/items?itemName=folke.vscode-monorepo-workspace) (helps with package detection)
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
19 changes: 0 additions & 19 deletions apps/cyberstorm-remix/Dockerfile.development

This file was deleted.

112 changes: 44 additions & 68 deletions apps/cyberstorm-remix/README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,44 @@
# How to setup and run Nimbus dev environment with local Thunderstore

## Preparations
This quide expects you to have setup your Thunderstore Django project for development on some level. Please setup the Thunderstore project before continuing.

## Setup nginx proxy for local data ingress/egress
1. Add the following to your hosts (on windows, google what how to achive same on other OS')
```
127.0.0.1 thunderstore.temp
127.0.0.1 new.thunderstore.temp
```

2. Boot up the nginx proxy with the following command; `docker compose -f tools/ts-dev-proxy/docker-compose.yml up`

3. Boot up your Thunderstore backend and ensure it's running in port 81 (it's normally 80). The following [line](https://github.com/thunderstore-io/Thunderstore/blob/f06b9b438ea6e990881e60339d34bde1a480d073/docker-compose.yml#L123) in your Thunderstore projects docker-compose, should be `- "127.0.0.1:81:8000"`

## Setup Nimbus for development

1. Clone the repo `git@github.com:thunderstore-io/thunderstore-ui.git`

2. Setup FontAwesome token. One way to do it is to add a `.npmrc` file with the following contents, under `thunderstore-ui/build-secrets/.npmrc`
```
@fortawesome:registry = "https://npm.fontawesome.com/"
//npm.fontawesome.com/:_authToken = YOUR_FA_TOKEN
```

3. Run `yarn install` first on the repo root (`thunderstore-ui` folder) and then again in the `thunderstore-ui/apps/cyberstorm-remix` folder.

4. Add `.env.development` and/or `.env.production` files. You can copy the `.env` file, rename and edit the values to your needs. Here's a example of the file contents:
```
VITE_SITE_URL=http://thunderstore.temp
VITE_BETA_SITE_URL=http://new.thunderstore.temp
VITE_API_URL=http://thunderstore.temp
VITE_COOKIE_DOMAIN=.thunderstore.temp
VITE_AUTH_BASE_URL=http://thunderstore.temp
VITE_AUTH_RETURN_URL=http://new.thunderstore.temp
__VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS=.thunderstore.temp
```

5. Run the build/start server script or the dev server script

Build and start
```
yarn workspace @thunderstore/cyberstorm-remix build
yarn workspace @thunderstore/cyberstorm-remix start --port 3000 --host 0.0.0.0
```

Dev script
```
yarn workspace @thunderstore/cyberstorm-remix dev --port 3000 --host 0.0.0.0
```

## Finally
You should now have the fully local Nimbus dev environment setup and running in `http://new.thunderstore.temp` and the Django site should be running in `http://thunderstore.temp`. You might need to go to `http://new.thunderstore.temp/communities` as Nimbus doesn't have a landing page yet.

# How to setup ts-proxy as a backend for this project
**Keep in mind that when using the ts-proxy, the sessions and actions will be made against the actual production Thunderstore**

1. Open hosts file as administrator (`C:\Windows\System32\drivers\etc`) and add this `127.0.0.1 thunderstore.temp` there
2. Download and install Docker and docker-compose. For windows people, Docker for Windows should be enough.
3. Open up a terminal and navigate to `thunderstore-ui/tools/ts-proxy`
4. Run `docker compose up`
5. Add these to your `.env.development` or `.env.production`
```
PUBLIC_SITE_URL=http://thunderstore.temp
PUBLIC_API_URL=http://thunderstore.temp:81
```
6. Run the Nimbus project normally
# Cyberstorm Remix (Nimbus)

This is the Remix application that powers the new Thunderstore frontend (codenamed Nimbus).

## Quick Start (Docker)

The easiest way to run the full stack (Backend + Frontend) is using Docker.

1. **Clone Repositories**
Ensure you have both `Thunderstore` (Backend) and `thunderstore-ui` (Frontend) cloned side-by-side.
```bash
# Example structure
# C:\projects\Thunderstore
# C:\projects\thunderstore-ui
```

2. **Start Backend**
```bash
cd ../Thunderstore
docker compose up -d
docker compose exec django python manage.py migrate
docker compose exec django python manage.py setup_dev_env
```

3. **Start Frontend**
```bash
cd ../thunderstore-ui
docker compose -f apps/cyberstorm-remix/docker-compose.dev.yml up -d
```

4. **Open Browser**
- **Frontend**: [http://new.localhost](http://new.localhost)
- **Backend**: [http://localhost](http://localhost)

## Manual Setup

If you prefer running Node locally instead of in Docker:

Comment on lines +35 to +38
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states "Read the Setup Guide to get started with the full stack (Frontend + Backend)" but the referenced README only covers Docker setup. Consider adding information about the manual setup prerequisites, such as installing Node.js/Yarn, or clarifying that the manual setup section only covers the frontend portion.

Suggested change
## Manual Setup
If you prefer running Node locally instead of in Docker:
## Manual Frontend Setup
If you prefer running the **frontend** (Remix app) locally instead of in Docker, follow these steps. The backend should still be run via Docker as described above.
### Prerequisites
- [Node.js](https://nodejs.org/) (version 18.x or later recommended)
- [Yarn](https://yarnpkg.com/) (classic, v1.x)
### Steps

Copilot uses AI. Check for mistakes.
1. **Install Dependencies**: `yarn install` (in repo root)
2. **Configure Env**: Copy `.env.example` to `.env` in `apps/cyberstorm-remix`.
3. **Run Dev Server**:
```bash
yarn workspace @thunderstore/cyberstorm-remix dev
```
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export function RouteErrorBoundary() {
if (error && import.meta.env.PROD) {
captureRemixErrorBoundaryError(error);
} else if (error) {
console.log("Error boundary caught error", error);
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate console logging detected - both console.log and console.error are called for the same error. The console.log on line 26 should be removed to avoid redundant output.

Suggested change
console.log("Error boundary caught error", error);

Copilot uses AI. Check for mistakes.
console.error("Error boundary caught error", error);
}
}, [error]);
Expand Down
Loading
Loading