
@planetscale/database
A Fetch API-compatible PlanetScale database driver
About
A Fetch API-compatible PlanetScale database driver
Live mirror of the GitHub README. Updated whenever the repo's default branch changes.
PlanetScale serverless JavaScript driver for Vitess/MySQL
A Fetch API-compatible PlanetScale Vitess/MySQL database driver for serverless and edge compute platforms that require HTTP external connections, such as Cloudflare Workers or Vercel Edge Functions
[!TIP] Connecting to a PlanetScale Postgres database? We support the Neon serverless driver, read the documentation to connect.
Installation
npm install @planetscale/database
Usage
import { connect } from '@planetscale/database'
const config = {
host: '<host>',
username: '<user>',
password: '<password>'
}
const conn = connect(config)
const results = await conn.execute('select 1 from dual where 1=?', [1])
console.log(results)
Database URL
A single database URL value can be used to configure the host, username, and password values.
import { connect } from '@planetscale/database'
const config = {
url: process.env['DATABASE_URL'] || 'mysql://user:pass@host'
}
const conn = connect(config)
Connection factory
Use the Client connection factory class to create fresh connections for each transaction or web request handler.
import { Client } from '@planetscale/database'
const client = new Client({
host: '<host>',
username: '<user>',
password: '<password>'
})
const conn = client.connection()
const results = await conn.execute('select 1 from dual')
console.log(results)
Transactions
Use the transaction function to safely perform database transactions. If any unhandled errors are thrown during execution of the transaction, the transaction will be rolled back.
The following example is based on the Slotted Counter Pattern.
import { connect } from '@planetscale/database'
const config = {
host: '<host>',
username: '<user>',
password: '<password>'
}
const conn = connect(config)
const results = await conn.transaction(async (tx) => {
const whenBranch = await tx.execute('INSERT INTO branches (database_id, name) VALUES (?, ?)', [42, "planetscale"])
const whenCounter = await tx.execute('INSERT INTO slotted_counters(record_type, record_id, slot, count) VALUES (?, ?, RAND() * 100, 1) ON DUPLICATE KEY UPDATE count = count + 1', ['branch_count', 42])
return [whenBranch, whenCounter]
})
console.log(results)
Custom fetch function
Node.js version 18 includes a built-in global fetch function. When using an older version of Node.js, you can provide a custom fetch function implementation. We recommend the undici package on which Node's built-in fetch is based.
import { connect } from '@planetscale/database'
import { fetch } from 'undici'
const config = {
fetch,
host: '<host>',
username: '<user>',
password: '<password>'
}
const conn = connect(config)
const results = await conn.execute('select 1 from dual')
console.log(results)
To leverage HTTP/2, you can use the fetch-h2 shim. fetch-h2 also supports Node.js 12+.
import { connect } from '@planetscale/database'
import { context } from 'fetch-h2'
const { fetch, disconnectAll } = context()
const config = {
fetch,
host: '<host>',
username: '<user>',
password: '<password>'
}
const conn = connect(config)
const results = await conn.execute('select 1 from dual')
console.log(results)
await disconnectAll()
Custom query parameter format function
Query replacement parameters identified with ? are replaced with escaped values. Named replacement parameters are supported with a colon prefix.
const results1 = await conn.execute('select 1 from dual where 1=?', [42])
const results2 = await conn.execute('select 1 from dual where 1=:id', { id: 42 })
Providing a custom format function overrides the built-in escaping with an external library, like sqlstring.
import { connect } from '@planetscale/database'
import SqlString from 'sqlstring'
const config = {
format: SqlString.format,
host: '<host>',
username: '<user>',
password: '<password>'
}
const conn = connect(config)
const results = await conn.execute('select 1 from dual where 1=?', [42])
console.log(results)
Custom type casting function
Column values are converted to their corresponding JavaScript data types. This can be customized by providing a cast function.
import { connect, cast } from '@planetscale/database'
function inflate(field, value) {
if (field.type === 'INT64' || field.type === 'UINT64') {
return BigInt(value)
}
return cast(field, value)
}
const config = {
cast: inflate,
host: '<host>',
username: '<user>',
password: '<password>'
}
const conn = connect(config)
You can also pass a custom cast function to execute. If present, this will override the cast function set by the connection:
const result = await conn.execute(
'SELECT userId, SUM(balance) AS balance FROM UserBalanceItem GROUP BY userId',
{},
{
cast: (field, value) => {
if (field.name === 'balance') {
return BigInt(value)
}
return cast(field, value)
}
}
)
Row return values
Rows can be returned as an object or an array of column values by passing an as option to execute.
const query = 'select 1 as one, 2 as two where 1=?'
const objects = conn.execute(query, [1], { as: 'object' })
// objects.rows => [{one: '1', two: '2'}]
const arrays = conn.execute(query, [1], { as: 'array' })
// arrays.rows => [['1', '2']]
Development
npm install
npm test
Need help?
Get help from the PlanetScale support team, or join our community on Discord or GitHub discussion board to see how others are using PlanetScale.
License
Distributed under the Apache 2.0 license. See LICENSE for details.
Quick facts
npm install @planetscale/databaseHow Sourcemap Explorer detects @planetscale/database
We catch @planetscale/database from two complementary signals: bundled source paths and the embedded package.json. Modern bundlers (webpack, Vite, esbuild, Rollup, Turbopack) preserve the original node_modules/@planetscale/database/ paths inside the JavaScript sourcemap's sources[] array — that's the canonical signal. When the matching package.json is also captured in sourcesContent[], we read the exact version field — patch number included. No regex guessing, no version inference.
- 1
Confirm the site exposes sourcemaps
In DevTools Network, check the response headers of any application script for `SourceMap` or `X-SourceMap`. Failing that, fetch the script's last 4 KB and look for a `//# sourceMappingURL=` comment.
- 2
Find the package in the bundle
Open DevTools → Network → reload. Click any application script and look at its sourcemap. Inside, search `sources[]` for entries matching `node_modules/@planetscale/database/` — every match confirms the package is bundled. The matching `sourcesContent[i]` for `node_modules/@planetscale/database/package.json` gives you the exact installed version.
- 3
Read the version directly from package.json
Run `jq -r '. as $m | $m.sources | to_entries[] | select(.value | endswith("node_modules/@planetscale/database/package.json")) | $m.sourcesContent[.key] | fromjson | .version' bundle.js.map`. Sourcemap Explorer automates the same query in the popup.
Recent versions
FAQ
What is @planetscale/database used for?
A Fetch API-compatible PlanetScale database driver
How can I tell if a website is using @planetscale/database?
Open the page in Chrome with the Sourcemap Explorer extension installed and read the Stack tab. We catch `@planetscale/database` from two complementary signals: `node_modules/@planetscale/database/` paths inside the JavaScript sourcemap, and the embedded `package.json` we read for exact-version detection. Without the extension you can do the same lookup manually in DevTools — the steps are listed in the "How Sourcemap Explorer detects" section above.
What is the latest version of @planetscale/database?
1.20.1, as published on the npm registry. The "Recent versions" table on this page lists the most recent 8 releases with their release dates. Sourcemap Explorer reports the version actually bundled into a site, which can lag the latest release by months on real-world deployments.
Where can I read more?
Project homepage: https://github.com/planetscale/database-js#readme. Source code: https://github.com/planetscale/database-js. Published on npm: https://www.npmjs.com/package/@planetscale/database. Licensed as Apache-2.0.
Keep reading on Sourcemap Explorer
Practical guides
Detected by Sourcemap Explorer
When a bundle ships sourcemaps, we read the embedded package.json for @planetscale/database and report the precise version. Without sourcemaps, an import / require in the page's scripts is enough to flag it.