Resolve production issues, fast. An open source observability platform unifying session replays, logs, metrics, traces and errors powered by ClickHouse and OpenTelemetry.
Find a file
Elizabet Oliveira 1e0f8ec79b
feat: Enable horizontal scrolling on search results table (#1871)
## Summary

Closes HDX-2701

Enables horizontal scrolling on the search results table so that column content is no longer clipped when the viewport is narrower than the total column widths, and improves table header styling, resize interactions, and scrollbar aesthetics.

### Changes

- **Dynamic `minWidth` on the table element** — Computes the sum of all column widths from TanStack Table's sizing state (substituting a 200px minimum for the flexible last column) and sets it as an inline `min-width` on the `<table>`. When the container is narrower than this threshold, the table overflows and the wrapper scrolls horizontally. When wider, `width: 100%` ensures the table fills the container normally.
- **Dynamic last column width** — Uses a `ResizeObserver` to track container width and computes the last column size as the remaining space after all other columns, instead of using the `UNDEFINED_WIDTH` sentinel. This ensures the last column fills remaining space responsively while respecting a 200px minimum.
- **Minimum column width** — Added `MIN_COLUMN_WIDTH` (50px) via TanStack Table's `defaultColumn.minSize` to prevent columns from being resized below a usable size. Explicitly set `minSize: 32` on the expand button column to prevent it from inheriting the 50px default.
- **Last column resizing** — Removed the `!isLast` guard so the last column now has a resize handle, making all columns consistently resizable.
- **Resize handle redesign** — Replaced the `IconGripVertical` drag icon with a minimal 1px vertical line using a CSS `::after` pseudo-element, styled with the new `--color-border-emphasis` token.
- **`min-width: 0` on flex containers** — Added `miw={0}` to the `DBSearchPage` results and pattern containers so flex children can shrink below their content size, allowing overflow to trigger scrolling.
- **Consolidate utility classes into SCSS module** — Moved `overflow: auto`, `height: 100%`, and `font-size` from inline Bootstrap utility classes into `.tableWrapper`, and moved `width: 100%` into `.table` in `LogTable.module.scss`.
- **Replace `Button` with `UnstyledButton` for sort headers** — Replaced Mantine `Button` with `UnstyledButton` for column sort headers, with custom SCSS that only darkens text on hover (no background).
- **Consolidate header styles into `TableHeader.module.scss`** — Moved `.cursorColResize` from `Table.module.scss` and `.headerCellWithAction`/`.headerRemoveButton` from `LogTable.module.scss` into a new `TableHeader.module.scss`, co-located with `TableHeader.tsx`.
- **Refactor `CsvExportButton`** — Removed the `UnstyledButton` wrapper around `CSVDownloader` to eliminate invalid `<a>` inside `<button>` markup. The `CSVDownloader` is now the root element with inline flex styling.
- **New `--color-border-emphasis` design token** — Added a slightly more prominent border color token for UI elements like resize handles, defined across HyperDX and ClickStack themes in both light and dark modes.
- **Global thin scrollbar styling** — Added app-wide custom scrollbar styles in `globals.css` for both WebKit and Firefox, providing thin (6px), rounded, semi-transparent scrollbars using theme color tokens.

### Files changed

- `packages/app/src/components/DBRowTable.tsx` — Added `containerWidth` tracking via `ResizeObserver`; added `tableMinWidth` and `lastColumnWidth` computations; set inline `minWidth` on table; added `defaultColumn.minSize`; moved utility classes to SCSS
- `packages/app/src/DBSearchPage.tsx` — Added `miw={0}` to results and pattern container Flex wrappers
- `packages/app/src/components/DBTable/TableHeader.tsx` — Replaced `Button` with `UnstyledButton`; removed `IconGripVertical`; enabled last column resizing; consolidated all style imports to `TableHeader.module.scss`
- `packages/app/src/components/DBTable/TableHeader.module.scss` *(new)* — Styles for `.sortButton`, `.resizer` (with `::after` pseudo-element line), `.headerCellWithAction`, and `.headerRemoveButton`
- `packages/app/src/components/CsvExportButton.tsx` — Removed `UnstyledButton` wrapper; `CSVDownloader` is now the root element with flex layout
- `packages/app/src/components/ExpandableRowTable.tsx` — Added `minSize: 32` to expand button column to prevent inheriting 50px default
- `packages/app/src/components/Table.module.scss` — Removed `.cursorColResize` (moved to `TableHeader.module.scss`)
- `packages/app/src/tableUtils.tsx` — Added `MIN_LAST_COLUMN_WIDTH` and `MIN_COLUMN_WIDTH` constants
- `packages/app/src/theme/themes/hyperdx/_tokens.scss` — Added `--color-border-emphasis` token
- `packages/app/src/theme/themes/clickstack/_tokens.scss` — Added `--color-border-emphasis` token
- `packages/app/src/theme/semanticColorsGrouped.ts` — Registered `color-border-emphasis` in borders group
- `packages/app/styles/LogTable.module.scss` — Added `overflow`, `height`, `font-size` to `.tableWrapper`; added `width: 100%` to `.table`; removed header styles (moved to `TableHeader.module.scss`)
- `packages/app/styles/globals.css` — Added global thin scrollbar styles for WebKit and Firefox

## Test plan

- [x] Open the Search page with multiple columns selected (e.g. Timestamp, ServiceName, SeverityText, Body, ScopeName)
- [x] Narrow the browser window — verify a horizontal scrollbar appears and columns are not cut off
- [x] Scroll horizontally — verify all column content is accessible
- [x] Widen the browser window — verify the table fills the container and no unnecessary scrollbar appears
- [x] Verify the last column still expands to fill remaining space on wide viewports
- [x] Resize columns via drag handles — verify horizontal scroll adjusts dynamically and columns cannot be resized below ~50px
- [x] Resize the **last** column — verify it now has a resize handle and works correctly
- [x] Verify the resize handle appears as a thin vertical line (not the old grip icon)
- [x] Hover over column sort headers — verify text darkens with no background change
- [x] Hover over column headers with remove button — verify remove button appears on hover
- [x] Click "Download table as CSV" — verify it works without layout issues
- [x] Verify scrollbars across the app are thin, rounded, and semi-transparent
- [x] Verify wrap lines toggle still works correctly
- [x] Switch to Event Patterns analysis mode — verify no layout regressions
- [x] Check the table in other contexts (Dashboard tiles, Pattern side panel) to confirm no layout regressions
2026-03-16 20:38:21 +00:00
.changeset feat: Enable horizontal scrolling on search results table (#1871) 2026-03-16 20:38:21 +00:00
.claude chore: add playwright agents for cursor and claude (#1847) 2026-03-05 15:16:18 +00:00
.cursor chore: add playwright agents for cursor and claude (#1847) 2026-03-05 15:16:18 +00:00
.github chore: skip claude code review on draft PRs (#1889) 2026-03-12 12:42:14 +01:00
.husky chore: Add automatic api doc generation (#1397) 2025-11-21 21:14:02 +00:00
.vex build(deps): add security resolutions for vulnerable npm packages (#1740) 2026-02-26 02:14:24 +00:00
.vscode add back linting prettier via eslint (#1463) 2025-12-11 12:00:31 -07:00
.yarn/releases feat: move more codes 2024-11-21 21:44:33 -08:00
agent_docs Enable parallel integration testing across multiple worktrees (#1917) 2026-03-16 19:42:08 +00:00
docker feat: Attach service version to all internal telemetry (#1891) 2026-03-12 16:50:46 +00:00
packages feat: Enable horizontal scrolling on search results table (#1871) 2026-03-16 20:38:21 +00:00
proxy feat: add subpath config (#1236) 2025-10-17 14:43:58 -07:00
scripts chore: Use local clickhouse instance for playwright tests (#1711) 2026-02-13 15:43:12 +00:00
smoke-tests/otel-collector fix(otel-collector): improve log level extraction with word boundaries in regex (#1747) 2026-02-18 22:16:07 +00:00
.env Release HyperDX (#1832) 2026-03-10 18:14:11 -07:00
.gitattributes first commit 2023-09-12 20:08:05 -07:00
.gitignore chore: add playwright agents for cursor and claude (#1847) 2026-03-05 15:16:18 +00:00
.kodiak.toml feat: support HYPERDX_LOG_LEVEL env var (#66) 2023-10-18 19:01:44 +00:00
.mcp.json chore: add playwright agents for cursor and claude (#1847) 2026-03-05 15:16:18 +00:00
.nvmrc chore: Update to next 16, react 19, add react compiler (#1434) 2025-12-04 23:40:59 +00:00
.prettierignore Search Relative Time Queries (#1305) 2025-10-29 15:49:10 +00:00
.prettierrc first commit 2023-09-12 20:08:05 -07:00
.yarnrc.yml feat: move more codes 2024-11-21 21:44:33 -08:00
AGENTS.md Migrate agent instructions to AGENTS.md for multi-agent support (#1925) 2026-03-16 20:27:25 +00:00
CLAUDE.md Migrate agent instructions to AGENTS.md for multi-agent support (#1925) 2026-03-16 20:27:25 +00:00
CONTRIBUTING.md chore: add playwright agents for cursor and claude (#1847) 2026-03-05 15:16:18 +00:00
DEPLOY.md update docs spelling (#1365) 2025-11-14 15:04:26 +00:00
docker-compose.ci.yml Enable parallel integration testing across multiple worktrees (#1917) 2026-03-16 19:42:08 +00:00
docker-compose.dev.yml chore: update clickhouse version for compose files to 26.1 (#1791) 2026-02-24 15:24:43 -05:00
docker-compose.yml chore: update clickhouse version for compose files to 26.1 (#1791) 2026-02-24 15:24:43 -05:00
LICENSE first commit 2023-09-12 20:08:05 -07:00
LOCAL.md chore: pull images from custom registry domain (#523) 2024-12-09 20:18:18 -08:00
Makefile Enable parallel integration testing across multiple worktrees (#1917) 2026-03-16 19:42:08 +00:00
nx.json chore: enable nx caching on common-utils builds during dev (#1880) 2026-03-11 02:19:33 +00:00
package.json build(deps): add security resolutions for vulnerable npm packages (#1740) 2026-02-26 02:14:24 +00:00
README.md chore: Update docs for ClickStack and HyperDX v2 Launch (#878) 2025-05-29 16:32:47 +00:00
tsconfig.base.json revert: api esbuild (#1280) 2025-10-21 09:27:47 +00:00
version.sh chore: align all versions on 2.0.0 (#886) 2025-06-03 20:48:08 +00:00
yarn.lock chore: Bump ai sdk to v6 (#1898) 2026-03-13 14:44:01 +00:00

hyperdx logo


HyperDX

HyperDX, a core component of ClickStack, helps engineers quickly figure out why production is broken by making it easy to search & visualize logs and traces on top of any ClickHouse cluster (imagine Kibana, for ClickHouse).

DocumentationChat on DiscordLive DemoBug ReportsContributingWebsite

  • 🕵️ Correlate/search logs, metrics, session replays and traces all in one place
  • 📝 Schema agnostic, works on top of your existing ClickHouse schema
  • 🔥 Blazing fast searches & visualizations optimized for ClickHouse
  • 🔍 Intuitive full-text search and property search syntax (ex. level:err), SQL optional!
  • 📊 Analyze trends in anomalies with event deltas
  • 🔔 Set up alerts in just a few clicks
  • 📈 Dashboard high cardinality events without a complex query language
  • { Native JSON string querying
  • Live tail logs and traces to always get the freshest events
  • 🔭 OpenTelemetry supported out of the box
  • ⏱️ Monitor health and performance from HTTP requests to DB queries (APM)

Search logs and traces all in one place

Spinning Up HyperDX

HyperDX can be deployed as part of ClickStack, which includes ClickHouse, HyperDX, OpenTelemetry Collector and MongoDB.

docker run -p 8080:8080 -p 4317:4317 -p 4318:4318 docker.hyperdx.io/hyperdx/hyperdx-all-in-one

Afterwards, you can visit http://localhost:8080 to access the HyperDX UI.

If you already have an existing ClickHouse instance, want to use a single container locally, or are looking for production deployment instructions, you can view the different deployment options in our deployment docs.

If your server is behind a firewall, you'll need to open/forward port 8080, 8000 and 4318 on your firewall for the UI, API and OTel collector respectively.

We recommend at least 4GB of RAM and 2 cores for testing.

Hosted ClickHouse Cloud

You can also deploy HyperDX with ClickHouse Cloud, you can sign up for free and get started in just minutes.

Instrumenting Your App

To get logs, metrics, traces, session replay, etc into HyperDX, you'll need to instrument your app to collect and send telemetry data over to your HyperDX instance.

We provide a set of SDKs and integration options to make it easier to get started with HyperDX, such as Browser, Node.js, and Python

You can find the full list in our docs.

OpenTelemetry

Additionally, HyperDX is compatible with OpenTelemetry, a vendor-neutral standard for instrumenting your application backed by CNCF. Supported languages/platforms include:

  • Kubernetes
  • Javascript
  • Python
  • Java
  • Go
  • Ruby
  • PHP
  • .NET
  • Elixir
  • Rust

(Full list here)

Once HyperDX is running, you can point your OpenTelemetry SDK to the OpenTelemetry collector spun up at http://localhost:4318.

Contributing

We welcome all contributions! There's many ways to contribute to the project, including but not limited to:

Motivation

Our mission is to help engineers ship reliable software. To enable that, we believe every engineer needs to be able to easily leverage production telemetry to quickly solve burning production issues.

However, in our experience, the existing tools we've used tend to fall short in a few ways:

  1. They're expensive, and the pricing has failed to scale with TBs of telemetry becoming the norm, leading to teams aggressively cutting the amount of data they can collect.
  2. They're hard to use, requiring full-time SREs to set up, and domain experts to use confidently.
  3. They requiring hopping from tool to tool (logs, session replay, APM, exceptions, etc.) to stitch together the clues yourself.

We hope you give HyperDX in ClickStack a try and let us know how we're doing!

Contact

HyperDX Usage Data

HyperDX collects anonymized usage data for open source deployments. This data supports our mission for observability to be available to any team and helps support our open source product run in a variety of different environments. While we hope you will continue to support our mission in this way, you may opt out of usage data collection by setting the USAGE_STATS_ENABLED environment variable to false. Thank you for supporting the development of HyperDX!

License

MIT