Skip to content

Latest commit

 

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trino Query UI

A reusable React component as a query interface for the SQL query engine Trino. Browse connected catalogs, write SQL queries, execute the queries and inspect result data all in a web application connected to your Trino cluster.

The component can be embedded into any React application and configured to proxy requests to a local or remote Trino cluster.

Warning

This package is under heavy development and is not yet recommended for production workloads. Treat the current release as an early-stage demo; production-ready builds and documentation are planned.

Trino Query UI

Implementation details:

  • React TypeScript project with Vite
  • Uses Node.js v24+
  • Monaco editor + ANTLR parser using the Trino language

Features

  • Browse metadata about catalogs, schemas, tables, and more
  • Search across catalogs
  • Set queries session context.
  • Inspect data with generated queries
  • Preview sample data
  • Write queries manually with schema-aware SQL syntax completion and highlighting
  • Use multiple query tabs
  • View schema information in SQL queries via mouse-over hovering
  • Format SQL queries in the editor
  • Copy result set table data to the clipboard
  • Monitor query processing across the Trino cluster

See details in the demo animation.

Installation

npm install @trinodb/trino-query-ui

Quick start

import { QueryEditor } from 'trino-query-ui'
import 'trino-query-ui/dist/index.css'

function MyTrinoApp() {
  return <QueryEditor theme="dark" height={800} />
}

export default MyTrinoApp

Building and shipping in Trino

The Query UI builds just like the existing UI in Trino.

  1. Build the TypeScript into Javascript and CSS
  2. Copy the distributable path into Trino.
  3. Modify Trino to respond to the query ui path.

Building for integration

Swap the defineConfig from debug to production in vite.config.ts

cd precise
npm install
npm run build

Copying into Trino

mkdir -p $TRINO_HOME/core/trino-main/src/main/resources/query_ui_webapp/
cp -r dist/* $TRINO_HOME/core/trino-main/src/main/resources/query_ui_webapp/

Modifying Trino to respond to /query/

Modify $TRINO_HOME/core/trino-main/src/main/java/io/trino/server/ui/WebUiStaticResource.java:

Add /query/ path. Note any path can be used:

    @ResourceSecurity(PUBLIC)
    @GET
    @Path("/query")
    public Response getQuery(@BeanParam ExternalUriInfo externalUriInfo)
    {
        return Response.seeOther(externalUriInfo.absolutePath("/query/")).build();
    }
    
    // asset files are always visible
    @ResourceSecurity(PUBLIC)
    @GET
    @Path("/query/assets/{path: .*}")
    public Response getQueryAssetsFile(@PathParam("path") String path)
            throws IOException
    {
        return getQueryFile("assets/" + path);
    }

    @ResourceSecurity(PUBLIC)
    @GET
    @Path("/query/{path: .*}")
    public Response getQueryFile(@PathParam("path") String path)
            throws IOException
    {
        if (path.isEmpty()) {
            path = "index.html";
        }

        String fullPath = "/query_ui_webapp/" + path;
        if (!isCanonical(fullPath)) {
            return Response.status(NOT_FOUND).build();
        }

        return webUiResource(fullPath);
    }

    private static boolean isCanonical(String fullPath)
    {
        try {
            return new URI(fullPath).normalize().getPath().equals(fullPath);
        }
        catch (URISyntaxException e) {
            return false;
        }
    }

Development

Build and run

  1. Install Node.js (v20 or newer) from https://nodejs.org/en/download/
  2. Ensure Trino is running at the configured URL. Defaults to http://localhost:8080
  3. Install the dependencies and run the dev server:
cd precise
npm install
npm run dev

The local URL is displayed, and you can open it in your browser.

Set up proxying to a local Trino instance

By default vite.config.ts is configured so that queries can be proxied to Trino's query endpoint running on http://localhost:8080. Modify the setting to suit your needs with another URL and updated configuration:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  base: '/query/',
  plugins: [react()],
  server: {
    proxy: {
      '/v1': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        secure: false,
      },
    },
  },
  ...
});

Building the parser

Build the parser, as configured in package.json.

npm run antlr4ng

Linting and code formatting

To check code quality and formatting with ESLint and Prettier, as defined in package.json:

npm run check

Releasing a new version

Releases are automated. The release workflow runs on every push to main. When it detects a changed version in precise/package.json, it publishes the package to npm and then creates a GitHub release with generated release notes. Pushes that leave the version untouched publish nothing.

Publishing runs before the release is created, so a failed publish leaves neither a release nor a tag behind, and the workflow run can be repeated once the cause is fixed.

Bump the version from the precise directory:

npm version 0.1.5 --no-git-tag-version

Use npm version instead of editing package.json by hand, so that package-lock.json records the same version. The two files drift apart otherwise, because the release workflow installs with npm ci, which never writes to the lockfile. The --no-git-tag-version flag skips the commit and tag, since the workflow creates the tag from the merged commit.

Commit both changed files with a Release v0.1.5 message, open a pull request, and merge it after review. The new version then appears on npm.

Publishing uses npm trusted publishing with OpenID Connect, so no npm token is stored in this repository. npm verifies the workflow identity directly and attaches a provenance attestation to each published version. The trusted publisher is configured in the package settings on npmjs.com and must match this repository and the release.yml workflow file name.

A brand new package name is the one case this does not cover. Trusted publishing needs an existing package to attach its configuration to, so the first version under a new or renamed package name has to be published by a maintainer with npm access before the workflow can take over.

Philosophy

This UI's purpose is to provide an environment where, once the cluster is up, you can immediately execute queries and explore data sets. The intended use cases are:

  • Initial proof-of-concept queries.
  • Exploration of data sets.
  • Performance analysis.
  • Ad hoc query execution.
  • Quickly enabling a data engineering team to start work before other integrations are in place.
  • Early demos.

The approach:

  1. Direct integration into the Trino UI
    • No need for an additional authentication hop (although it could be added in the future)
    • Authenticates as the user executing the query when using OAuth2
    • Trino does the heavy lifting
  2. Remove friction so you can simply write a query
    • Autocomplete understands the Trino language, tables, and columns
    • Provides syntax highlighting and validation
    • Offers a comprehensive catalog explorer
  3. Avoid black-box query execution
    • Show progress and execution details. People ask "why is my query slow?" mostly because they only see a spinner for minutes.
    • Link to the Trino Query UI to drill into query performance
    • Show stages and split counts like the Trino console client
  4. Keep the experience easy to navigate

Gaps and future direction

  • Saving queries and using source control require either backend capabilities in the Trino service or leveraging Trino to write queries as tables.
  • No autocomplete for the Trino function list.
  • Basic graphing capabilities are still missing—looking at a table alone is not enough even for inspecting data sets.
  • No LLM copilot integration yet. Many query UIs implement this poorly, but, done well, it could make query crafting fast and help translate from other query languages.
  • Parameters and string replacement are only partly implemented in SubstitutionEditor and should support both SQL parameters and string replacement.

About

Web-based query UI for Trino

Resources

Stars

43 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages