--- title: "JavaScript" slug: "javascript" updated: 2026-10-07T08:42:56Z published: 2026-10-07T08:42:56Z canonical: "portal.doorda.com/javascript" --- > ## Documentation Index > Fetch the complete documentation index at: https://portal.doorda.com/llms.txt > Use this file to discover all available pages before exploring further. # JavaScript A quick-start guide to connecting with the Trino JavaScript client Doorda data is served through Trino, so you can query your tables directly with SQL instead of calling per-table API endpoints. The official Trino client for Node.js handles the connection, paging and results for you. **Connection details** | **Server** | *https://host.doorda.com* | | --- | --- | | **Authentication** | *Username and password (HTTP Basic, over HTTPS)* | | **Access Read-only** | *limited to the tables in your subscription* | | **Client** | *@trinodb/trino-js-client (npm)* | | **Runtime** | *Node.js 24 or newer, running server-side* | ```custom npm install @trinodb/trino-js-client ``` ```custom import { Trino, BasicAuth } from '@trinodb/trino-js-client'; const trino = Trino.create({ server: 'https://host.doorda.com', catalog: '', schema: '', source: 'your-app-name', auth: new BasicAuth( process.env.DOORDA_USER, process.env.DOORDA_PASSWORD ), }); ``` Create one client and reuse it. Keep your credentials in environment variables or a secrets manager, never in source code. *catalog* and *schema* set the defaults for unqualified table names. You can leave them out and use full names in your SQL instead: catalog.schema.table. **About** *source*. This is a free-text label sent with every query (the X-Trino-Source header). If you leave it out, the client sends trino-js-client. Please set it to the name of your application or service, so that we can identify your traffic and help quickly if you raise a support query. ```custom async function runQuery(sql) { const pages = await trino.query(sql); let columns = []; const rows = []; for await (const page of pages) { if (page.error) { throw new Error(`${page.error.errorName}: ${page.error.message}`); } if (page.columns) columns = page.columns.map(c => c.name); for (const values of page.data ?? []) { rows.push(Object.fromEntries(values.map((v, i) => [columns[i], v]))); } } return rows; } const rows = await runQuery('SELECT * FROM LIMIT 10'); console.log(rows); ``` Results arrive in pages. Each page holds rows as arrays of values, with the column names alongside. This helper collects every page and returns plain objects. **Errors** Problems with the query itself (a syntax error, an unknown table, a table outside your subscription) are returned on the result page as *page.error* rather than thrown, which is why the helper checks for it. Connection and login problems, such as a wrong password, are thrown as ordinary HTTP errors by *trino.query()*. ```custom SHOW CATALOGS; SHOW SCHEMAS FROM ; SHOW TABLES FROM .; DESCRIBE ..
; ``` **Good practice** - **Run it on your server**. The client is built for Node.js. Do not call Doorda from browser code, as that would expose your credentials. - **Ask only for what you need**. Name the columns you want, filter with WHERE, and use LIMIT while exploring. Smaller queries return faster. - **Expect analytical response times**. Queries typically take from under a second to several seconds. For lookups inside a live user journey, fetch the data ahead of time and store it on your side. - **Large results.** The helper above holds every row in memory. For big extracts, process each page inside the loop instead of collecting them all. - **Stopping a query**. Every page carries the query id; call trino.cancel(id) to stop a query you no longer need.