# ydb-embedded-ui

Local viewer for YDB clusters

- [Docs for users](https://ydb.tech/en/docs/maintenance/embedded_monitoring/ydb_monitoring)
- [Project Roadmap](ROADMAP.md)

## Preview

You can preview working UI using YDB docker image. It will be UI with the latest stable ydb version.

Run on a machine with Docker installed:

```
docker pull ghcr.io/ydb-platform/local-ydb:nightly
docker run -dp 8765:8765 ghcr.io/ydb-platform/local-ydb:nightly
```

Open http://localhost:8765 to view it in the browser.

## Development

1. Run on a machine with Docker installed:

   ```
   docker run --rm -ti --name ydb-local -h localhost \
      -p 8765:8765 \
      -e MON_PORT=8765 \
      ghcr.io/ydb-platform/local-ydb:nightly
   ```

   On macOS with Colima on Apple Silicon, `ghcr.io/ydb-platform/local-ydb:nightly` can require `linux/amd64` emulation. Start Colima with Rosetta and run the container with an explicit platform:

   ```
   colima start --vm-type vz --vz-rosetta --cpu 4 --memory 8
   docker context use colima
   docker run --rm -ti --name ydb-local -h localhost --platform linux/amd64 \
      -p 8765:8765 \
      -e MON_PORT=8765 \
      ghcr.io/ydb-platform/local-ydb:nightly
   ```

2. Install dependencies with `npm ci`
3. Run the frontend app in the development mode, via invoking `npm run dev`
4. Open [localhost:3000](http://localhost:3000) to view it in the browser. The page will reload if you make edits.\
   You will also see any lint errors in the console.

For API reference, open Swagger UI on http://localhost:8765/viewer/api/.

### AI-assisted local development

[Local YDB Toolkit](https://github.com/astandrik/local-ydb-toolkit) bundles an MCP server for local YDB tools with a `local-ydb` skill for the recommended workflows and checks.

For Codex, install the plugin once:

```bash
codex plugin marketplace add astandrik/local-ydb-toolkit
codex plugin add local-ydb-toolkit@local-ydb-toolkit
```

Using another agent? The toolkit also supports [Claude Code](https://github.com/astandrik/local-ydb-toolkit#claude-code-plugin), [Gemini CLI and Antigravity](https://github.com/astandrik/local-ydb-toolkit#gemini-cli--antigravity-plugin), and [other MCP clients that support local stdio servers](https://github.com/astandrik/local-ydb-toolkit#nodejs-mcp-server).

Start a new Codex session after installation. A basic `/local` database needs no config file. The agent can manage YDB and seed test data with managed SQL, or use the existing Playwright request mocks for UI-only tests. Mutating tools require explicit confirmation.

### YDB docker images

[Docs on YDB docker images](https://ydb.tech/en/docs/getting_started/self_hosted/ydb_docker)

To test new features, you can use ydb version built from `main` brunch with `ghcr.io/ydb-platform/local-ydb:nightly` image.
Also you can set specific version like `ghcr.io/ydb-platform/local-ydb:24.1`

### Custom configuration in dev mode with .env file

You can run the app with your own params by adding `.env` file to project root. There is an example in `.env.example`.

1. Add `.env` file to project root by copying example

```shell script
cp .env.example .env
```

2. Set your own set of params in `.env`
3. Run `npm run start`. Your custom params from `.env` file will be applied

#### Custom backend in dev mode

YDB docker represents a single node cluster with only one version, small amount of storage groups, PDisks and VDisks. It may be not enough for development purposes. If you have your own development cluster with sufficient amount of entities, you can run the app in the dev mode with this cluster as backend. To do it, alter `REACT_APP_BACKEND` param in your `.env` file:

```
REACT_APP_BACKEND=http://your-cluster-host:8765
REACT_APP_META_BACKEND=undefined
META_YDB_BACKEND=undefined
```

#### Meta backend in dev mode (multi cluster)

If you have meta backend for multi cluster version, you can run the app in dev mode with this backend by setting `REACT_APP_META_BACKEND` param in `.env`:

```
REACT_APP_BACKEND=undefined
REACT_APP_META_BACKEND=http://your-meta-host:8765
META_YDB_BACKEND=undefined
```

If you need to connect to the meta backend from a server, you need to set `META_YDB_BACKEND` param in `.env`:

```
REACT_APP_BACKEND=undefined
REACT_APP_META_BACKEND=undefined
META_YDB_BACKEND=http://your-meta-host:8765
```

## E2E Tests

For e2e tests we use `@playwright/tests`. Tests configuration is in `playwright.config.ts`. Tests are set up in `tests` dir.

### Commands

Install all Playwright dependencies and chromium to run tests.

```
npm run test:e2e:install
```

Run tests. If `PLAYWRIGHT_BASE_URL` is provided, tests run on this url, otherwise Playwright `webServer` is started with `npm run dev` on `http://localhost:3000` and all tests run there. If `PLAYWRIGHT_APP_BACKEND` is provided, tests will be use this url as backend, otherwise `http://localhost:8765` will be used.

```
npm run test:e2e
```

Run tests in Playwright Docker against a separately started backend. `PLAYWRIGHT_APP_BACKEND` is required; loopback URLs are forwarded from the Playwright container to the host automatically.

```
docker run --rm -d -p 8765:8765 ghcr.io/ydb-platform/local-ydb:nightly
PLAYWRIGHT_APP_BACKEND=http://localhost:8765 npm run test:e2e:docker
```

Run tests in Playwright Docker and then serve the generated HTML report locally at `http://127.0.0.1:9323`. You can override host and port with `PLAYWRIGHT_HTML_HOST` and `PLAYWRIGHT_HTML_PORT`.

```
PLAYWRIGHT_APP_BACKEND=http://localhost:8765 npm run test:e2e:docker:report
```

### CI

E2E tests are run in CI in the `e2e_tests` job. Each shard starts `ghcr.io/ydb-platform/local-ydb:nightly` in root topology through `setup-local-ydb`, then passes the action monitoring URL to the Playwright Docker flow.

## Making a production bundle.

### Web Workers for package consumers

The computation graph calculates its layout in a Web Worker. By default, the package uses the native bundler pattern:

```ts
new Worker(new URL('./graphLayout.worker', import.meta.url));
```

Bundlers that support this pattern, including Rsbuild and Rspack, emit the worker as a separate asset automatically. The emitted worker script must be deployed with the application, served from the application origin, and allowed by the application's Content Security Policy:

```http
Content-Security-Policy: worker-src 'self'
```

If application chunks are loaded from a CDN, configure the bundler to keep native worker scripts on the application origin. For example, with Rspack:

```ts
export default {
  output: {
    workerPublicPath: '/build/',
  },
};
```

Consumers that need to resolve the worker URL at runtime can provide a worker factory before rendering `SingleClusterApp` or `MultiClusterApp`. The factory must return a new worker instance on every call:

```ts
import {configureUIFactory} from 'ydb-embedded-ui';

configureUIFactory({
  createGraphLayoutWorker: () =>
    new Worker(window.runtimeConfig.ydbGraphLayoutWorkerUrl, {
      name: 'ydb-graph-layout',
    }),
});
```

Use `ydb-embedded-ui/dist/graphLayout.worker.js` as the worker entry in the consumer build. Process this entry with the consumer's bundler rather than copying it as an unbundled static file. Publish the resulting worker bundle at the URL returned by the runtime configuration.

If the browser cannot create or load the worker, the graph retries the layout on the main thread. This fallback preserves functionality, but consumers should configure worker delivery to keep expensive layout work off the UI thread.

Base command `npm run build` builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.

To test production bundle with latest YDB backend release, do the following:

1. Install dependencies with `npm ci`
2. Build a production bundle with a few tweaks for embedded version: `npm run build:embedded`.
3. Invoke `docker run -it --hostname localhost -dp 2135:2135 -p 8765:8765 -v ~/projects/ydb-embedded-ui/build:/ydb_data/node_1/content/monitoring ghcr.io/ydb-platform/local-ydb:nightly`
4. Open [embedded YDB UI](http://localhost:8765/monitoring) to view it in the browser.

### Testing production bundle with specific cluster host

If you want to test embedded version in production mode, but YDB docker is not enough and you have your own ydb development cluster, you can manually update UI for the specific cluster host.

It also could be usefull for development purposes, because some operations, that are not 'read-only', like some update queries or tablets restart could be allowed by CORS only for the same origin and so could not be executed in dev mode.

1. Install dependencies with `npm ci`
2. Create production bundle with `npm run build:embedded`
3. Copy your build files from `build` folder to `/content/monitoring` folder on desired cluster host
4. Open `http://your-cluster-host:8765/monitoring` to see updated UI

It's assumed, that you have all the necessary access rights to update files on the host.
