gaslamp¶
Shedding light on easier data manipulation in Google Apps Script by introducing DataFrame operations and runtime type safety.

gaslamp is a Google Apps Script library for DataFrame operations and runtime type safety.
It illuminates two dark corners of GAS data manipulation: raw spreadsheet data and the absence of runtime types.
Inspired by pandas and polars, it wraps getValues() in a full DataFrame API and provides composable type guards through FlameWright — bringing structure and safety to a JavaScript-only runtime.
Why gaslamp?¶
Google Apps Script runs pure JavaScript at runtime — TypeScript types are erased.
Without extra tooling, data from spreadsheets arrives as any[][], and there is no way to
verify types at runtime.
gaslamp addresses two problems:
- No DataFrame API in GAS —
getValues()returns raw 2D arrays. gaslamp wraps them in aDataFramewithselect,filter,sortBy,groupBy,resampleBy, and more. - No runtime type safety in GAS — gaslamp's
FlameWrightsystem provides composable type guards that narrow types at runtime, not just at compile time.
Features¶
| Category | Description |
|---|---|
| DataFrame | Core schema-free DataFrame named BareFrame and GroupedFrame for grouped operations, LazyFrame for lazy evaluation and |
| FlameFrame | Schema validation gate combining BareFrame and FlameWright — validates data and returns { passed, failed } |
| Flame | FlameWright, FlameGuards — runtime type guards and schema validation |
| Expression | Chainable expression builder for filter conditions |
| Convert | Bidirectional converters between row-oriented and column-oriented data |
| Logger | CategoryLogger, AfterGlow — structured logging with category support |
| Gaslets | Google Sheets, Drive, Calendar, Trigger integration utilities |
| Gears | ClockSmith timing, Counter, JunkPocket caching |
| JestLite | GAS-compatible testing framework (no Node.js required) |
Installation¶
Script ID¶
1l2aZO5RkhmDHUwtR3gnrqDIWw84K_T-NBdLP7-X0-BjcA06YU0nbgCNQ
Setup¶
- Open Libraries in your Google Apps Script project
- Paste the Script ID above
- Select version:
HEAD(latest) or a fixed version for production - Set identifier:
gaslamp - Click Save
Note: Use a fixed version in production.
HEADmay include breaking changes.
Quick Start¶
BareFrame — spreadsheet data as a DataFrame¶
function example() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("master");
// Load sheet data as a BareFrame
const df = gaslamp.BareFrame.fromSheet(sheet);
// Filter rows declaratively
const active = df.filter(row => row.get("status") === "active");
// Display as a table string
console.log(active.toTableString());
}
FlameWright — runtime type guards¶
function validate() {
const value = someExternalInput();
// Narrow the type at runtime
if (gaslamp.FlameGuards.isString(value)) {
console.log(value.toUpperCase()); // value is typed as string here
}
// Schema-style validation
const schema = {
name: gaslamp.FlameGuards.isString,
age: gaslamp.FlameGuards.isNumber,
};
const isUser = gaslamp.FlameWright.fromSchema(schema);
const data = { name: "Alice", age: 30 };
if (isUser(data)) {
console.log(data.name); // data is narrowed to { name: string; age: number }
}
}
FlameFrame — schema-validated data¶
function validateAndProcess() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("master");
const df = gaslamp.BareFrame.fromSheet(sheet);
// Define a validation schema
const schema = {
name: gaslamp.FlameGuards.isString,
score: gaslamp.FlameGuards.isNumber,
};
// Validate and separate valid/invalid rows
const { passed, failed } = gaslamp.FlameFrame.from(df, schema);
if (failed.length > 0) {
console.log("Invalid rows:", failed.display());
} else {
console.log(`All ${passed.length} rows are valid`);
}
}
Expression — reusable filter conditions¶
function filterWithExpression() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("master");
const df = gaslamp.BareFrame.fromSheet(sheet);
// Build a condition as an Expression, then convert to a predicate
const cond = gaslamp.Expression.col("score").ge(80);
const highScorers = df.filter(cond.toFunction());
console.log(highScorers.toTableString());
}
Performance¶
gaslamp is designed for GAS's constraints:
- Column-oriented storage — reduces memory usage for large sheets
- Lazy evaluation —
LazyFramedefers computation until needed - No Node.js dependencies — ES2020 target, GAS-compatible from day one
- Batch sheet operations — minimizes API call overhead
Documentation¶
- Getting Started — Setup and first steps
- User's Guide — In-depth feature explanations
- Developer's Guide — Architecture, extending, and contributing
- API Reference — Complete class and function reference
License¶
LGPL-3.0 — see LICENSE for details.
In short: Improvements to gaslamp must be shared, but projects using gaslamp can remain proprietary.
Links¶
- Repository: GitLab
- Documentation: Read the Docs
- Issues: GitLab Issues
- npm Package: Coming soon
gaslamp — Shedding light on easier data manipulation in Google Apps Script by introducing DataFrame operations and runtime type safety.