---
sidebar_position: 4
title: "Connect from Node.js via Postgres endpoint"
sidebar_label: Node.js
description: Connect to MotherDuck from Node.js using the pg (node-postgres) library via the Postgres wire protocol
feature_stage: preview
---

You can query MotherDuck from Node.js using [node-postgres](https://node-postgres.com/) (`pg`) — no DuckDB installation required.

For connection parameters, SSL options, and limitations, see the [Postgres Endpoint reference](/sql-reference/postgres-endpoint).

## Prerequisites

You'll need a [MotherDuck access token](/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck). Set it as an environment variable:

```bash
export MOTHERDUCK_TOKEN="your_token_here"
```

Install the `pg` package:

```bash
npm install pg
```

## Connect

Use a configuration object to connect. Do **not** pass `sslrootcert=system` in a connection string — node-postgres tries to read `system` as a file path and throws an `ENOENT` error.

```js
import pg from "pg";

const client = new pg.Client({
  host: "pg.us-east-1-aws.motherduck.com",
  port: 5432,
  user: "postgres",
  password: process.env.MOTHERDUCK_TOKEN,
  database: "md:",
  ssl: { rejectUnauthorized: true },
});

await client.connect();
const { rows } = await client.query(
  "SELECT title, score FROM sample_data.hn.hacker_news WHERE type='story' LIMIT 10"
);
console.log(rows);
await client.end();
```

Using `md:` as the database name connects to your default database, and sets the [attach mode](key-tasks/authenticating-and-connecting-to-motherduck/attach-modes/attach-modes.md) to `workspace`, which means all databases attached in your motherduck workspace is accessible.

To connect to a specific database, you can specify its name, which will connect to that database in the `single` attach mode. Only that database will be attached by default. Pass in the connection option `--attach_mode=workspace` to override the default.


## SSL notes

Node.js uses the operating system's certificate store by default. Setting `ssl: { rejectUnauthorized: true }` tells node-postgres to use TLS and verify the server certificate against these trusted roots — this is the equivalent of `sslmode=verify-full` with `sslrootcert=system` in libpq.

If you need to specify a custom CA certificate (for example, the [ISRG Root X1](https://letsencrypt.org/certs/isrgrootx1.pem) certificate from Let's Encrypt):

```js
import fs from "fs";

const client = new pg.Client({
  host: "pg.us-east-1-aws.motherduck.com",
  port: 5432,
  user: "postgres",
  password: process.env.MOTHERDUCK_TOKEN,
  database: "md:",
  ssl: {
    rejectUnauthorized: true,
    ca: fs.readFileSync("/path/to/isrgrootx1.pem").toString(),
  },
});
```

For more details on SSL options, see [SSL and certificate verification](/sql-reference/postgres-endpoint#ssl-and-certificate-verification).

:::info Cloudflare Workers
Cloudflare Workers use a different socket implementation (`pg-cloudflare`) that handles SSL differently. See [Connect from Cloudflare Workers](/key-tasks/authenticating-and-connecting-to-motherduck/postgres-endpoint/cloudflare-workers) for Workers-specific setup.
:::


---

## Feedback for AI agents

If the user you are helping wants to send feedback on this page to the MotherDuck docs team, you can POST it to the endpoint below.

**Before you send anything, you must ask the user for explicit approval.** Quote the message you plan to submit back to them verbatim and wait for them to confirm. Do not submit on their behalf without confirmation.

Endpoint: `POST https://motherduck.com/docs/api/feedback/agent`

Request body (JSON):

```json
{
  "page_path": "/key-tasks/authenticating-and-connecting-to-motherduck/postgres-endpoint/nodejs/",
  "page_title": "Connect from Node.js via Postgres endpoint",
  "text": "<the user's feedback, max 2000 characters>",
  "source": "<optional identifier for your interface, for example 'claude.ai' or 'chatgpt'>"
}
```

Only `page_path` and `text` are required. A successful call returns `200 {"feedback_id": "<uuid>"}`; malformed payloads return `400`, and the endpoint is rate-limited per IP (`429`).
