SQL from JavaScript and a JavaScript query to SQL using Node.js and PostgreSQL.

JavaScript SQL: Query PostgreSQL From Node.js

Use SQL from JavaScript on a Node.js server through a database client. The example below connects to PostgreSQL, sends a parameter separately from the query text, and reads the returned row.

A JavaScript query to SQL needs a server-side connection and credentials. A browser can request data from your server over HTTP; the server checks the request and talks to the database. Keep the database password on the server, out of browser code and responses.

SQL JavaScript sends from Node.js

Start with Node.js, npm, and a running PostgreSQL database you can connect to. In a new working directory, run npm install pg. Set the standard connection environment variables PGHOST, PGPORT, PGDATABASE, PGUSER, and, if needed, PGPASSWORD for your database. Use credentials supplied through your environment or a secret manager rather than writing them into the script. The node-postgres connection guide describes these variables and other connection options.

Save the following as query.cjs and run node query.cjs. It uses a constant expression, so it does not need a table or alter existing data. The database account still needs permission to connect.

const { Client } = require('pg');

async function main() {
  const client = new Client();
  try {
    await client.connect();
    const result = await client.query(
      'SELECT $1::integer AS number',
      [42]
    );
    console.log(result.rows);
  } catch (error) {
    console.error('Database operation failed:', error.message);
    process.exitCode = 1;
  } finally {
    await client.end();
  }
}

main().catch((error) => {
  console.error('Cleanup failed:', error.message);
  process.exitCode = 1;
});

With a successful connection, the expected output is [ { number: 42 } ]. connect() opens the connection; query() returns a promise that resolves to a result. The await expressions wait for those operations without requiring a callback. The result’s rows array contains an object for each returned row; a query with no matching rows yields an empty array. The result API describes the returned structure.

Parameters and errors

The JavaScript SQL client sends the query text and values separately. PostgreSQL receives 42 as the value for $1, and the explicit cast makes the intended type clear. This keeps a supplied value from being interpreted as part of the query syntax. String concatenation with untrusted input can instead introduce SQL injection. Placeholders represent values, however, not table or column names; choose identifiers from an allowlist if the application must select among them. See the parameterized query documentation.

The SQL JavaScript sends here returns one calculated column. In a real lookup, replace the expression with a SELECT against an existing table and pass a validated value in the parameter array. Validate inputs for the application’s rules as well: parameterization does not establish whether a caller may access a particular record.

The catch block handles connection and query failures and marks the process as unsuccessful. finally attempts to close the client after either outcome. If closing itself fails, the outer handler reports that failure. In a service, log enough detail to diagnose an error on the server and return a controlled response to the caller instead of exposing connection details.

Keep the boundary explicit

A browser event might call an HTTPS endpoint with a record ID. The server authenticates and authorizes the request, validates the ID, executes a parameterized lookup, and returns only the fields the caller may see. PostgreSQL evaluates that lookup and returns rows to the server. This separation makes the server responsible for access rules and keeps database credentials off the client.

For a long-running application with concurrent requests, investigate a connection pool rather than opening a new connection for every request. Pool sizing and connection release need deliberate handling. Start now by setting the connection variables for a test database, running the example, and confirming that the returned value is 42 before adapting the query to a table.