Google Sheets Database
sheets-database is a JavaScript/TypeScript library designed to enable developers to use Google Sheets as a lightweight, no-cost database or content management system. Currently at version 1.0.4, it provides a simple and intuitive API for common database operations like creating, reading, updating, and deleting (CRUD) tables and their entries. The library offers multiple authentication methods, including Service Account, OAuth, Access Token, and API Key, and includes features to optimize memory and network usage for suitable use cases. While it handles internal synchronization with Google Sheets, it is explicitly positioned for small applications and datasets, warning against its use for applications with many entries or complex joins where traditional databases are more appropriate. Release cadence appears to be minor patches within the 1.0.x range, indicating stability and ongoing maintenance.
Common errors
-
Error: Invalid Credentials
cause Incorrect or expired Google API credentials (e.g., Service Account private key, OAuth token).fixDouble-check your `GOOGLE_SERVICE_ACCOUNT_EMAIL` and `GOOGLE_PRIVATE_KEY` environment variables. Ensure the private key correctly handles newline characters (e.g., replace `\n` with `\n`). Regenerate credentials if necessary. -
Error: The requested document was not found.
cause The provided Google Sheet ID is incorrect, or the authenticated account does not have permission to view it.fixVerify the `GOOGLE_SHEET_ID` environmental variable or literal string matches the ID from the Google Sheet URL. Confirm the authenticated Google account (Service Account or OAuth) has at least read access to the sheet. -
SyntaxError: await is only valid in async functions and the top level bodies of modules
cause Using `await` outside an `async` function or a module context (when `"type": "module"` is set in `package.json`) in Node.js.fixWrap all `await` calls within an `async` function, or configure your Node.js project to use ES Modules by adding `"type": "module"` to your `package.json` file and using `.mjs` or `.js` files when appropriate. -
Error: You do not have permission to access this spreadsheet.
cause The authenticated Google account lacks the necessary permissions (e.g., read, write) for the target Google Sheet.fixShare the Google Sheet directly with the email address of your Service Account or the Google account used for OAuth, granting appropriate permissions (e.g., Editor for write access).
Warnings
- gotcha The package examples often use top-level `await` for brevity. This feature is not enabled by default in most Node.js environments and requires wrapping `await` calls in an `async` function or configuring Node.js for ES Modules (`"type": "module"` in `package.json`).
- gotcha This library is explicitly designed for small applications and datasets. It is not suitable as a replacement for traditional databases in scenarios involving many entries, complex queries, or frequent, high-volume operations due to Google Sheets API limitations and performance characteristics.
- gotcha When using a Service Account for authentication, ensure that the Google Service Account has editor permissions on the specific Google Sheet document you are trying to access. Common issues arise from insufficient sharing permissions on the sheet itself.
- gotcha Google Sheets API imposes rate limits. Excessive read/write operations within a short period can lead to `429 Too Many Requests` errors. While the library might have some internal optimizations, developers should be mindful of their usage patterns.
Install
-
npm install sheets-database -
yarn add sheets-database -
pnpm add sheets-database
Imports
- SheetDatabase
const { SheetDatabase } = require('sheets-database');import { SheetDatabase } from 'sheets-database'; - Auth Options (e.g., useServiceAccount)
db.useServiceAccount({...}); // Missing awaitawait db.useServiceAccount({...});
Quickstart
import { SheetDatabase } from 'sheets-database';
// Initialize the Database with doc ID (long id in the sheets URL)
const db = new SheetDatabase(process.env.GOOGLE_SHEET_ID ?? '');
async function run() {
// Initialize Auth using a Service Account for robust server-side access.
// Ensure GOOGLE_SERVICE_ACCOUNT_EMAIL and GOOGLE_PRIVATE_KEY are set in your environment variables.
// The private key may need newline characters replaced if loaded from a single-line environment variable.
await db.useServiceAccount({
client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL ?? '',
private_key: (process.env.GOOGLE_PRIVATE_KEY ?? '').replace(/\\n/g, '\n'),
});
await db.sync(); // Connects with the sheet and fetches initial data
// ADDING TABLES
const table1 = await db.addTable('products', ['id', 'name', 'price']);
console.log('Table "products" added.');
// Insert some data
await table1.insertOne({ 'id': 1, 'name': 'Laptop', 'price': 1200 });
await table1.insert([
{ 'id': 2, 'name': 'Mouse', 'price': 25 },
['3', 'Keyboard', 75]
]);
console.log('Data inserted into products table:', table1.getData());
// RENAMING TABLES
await table1.rename('inventory');
console.log('Table renamed to "inventory".');
// Update entries
await db.inventory.updateRowsWhere(
(currentData) => currentData.name === 'Laptop',
(data) => ({ ...data, price: 1250 })
);
console.log('Updated inventory data:', db.inventory.getData());
// DELETING TABLES (Commented out to prevent accidental deletion in quickstart)
// await db.inventory.drop();
// console.log('Table "inventory" dropped.');
}
run().catch(console.error);