Apache Iceberg REST Catalog Client
Iceberg.js is a small, framework-agnostic JavaScript and TypeScript client specifically designed for interacting with Apache Iceberg REST Catalogs. It provides a thin HTTP wrapper over the official REST API, making it generic enough to work with any Iceberg REST Catalog implementation without vendor lock-in. The current stable version is `0.8.1`. The project maintains an active release cadence, with multiple minor versions released within short intervals, indicating ongoing development towards a stable 1.0.0. Key differentiators include first-class TypeScript support for strong typing, reliance on the native `fetch` API for universal compatibility (Node.js 20+ and modern browsers), and a focused scope on catalog operations, deliberately excluding data reading or Parquet file support.
Common errors
-
ReferenceError: fetch is not defined
cause The Node.js environment is older than version 20.0.0, which does not include the native `fetch` API.fixUpgrade your Node.js runtime to version 20.0.0 or higher. Alternatively, provide a custom `fetch` implementation in the `IcebergRestCatalog` constructor options if you cannot upgrade Node.js. -
TypeError: IcebergRestCatalog is not a constructor
cause Attempting to use CommonJS `require()` syntax to import the `IcebergRestCatalog` class in a CommonJS module. This library is designed for ESM.fixUse ESM `import { IcebergRestCatalog } from 'iceberg-js'` and ensure your project is configured for ESM (e.g., `"type": "module"` in `package.json`). -
HTTP 401 Unauthorized / HTTP 403 Forbidden
cause The authentication credentials provided in the `auth` option are missing, invalid, or do not have sufficient permissions to access the catalog.fixVerify your `auth` configuration in the `IcebergRestCatalog` constructor. Ensure the token is correct, not expired, and has the necessary permissions on the Iceberg REST Catalog. -
HTTP 404 Not Found
cause The `baseUrl` for the Iceberg REST Catalog is incorrect, or if using a `catalogName`, it is misconfigured, leading to an unreachable endpoint.fixDouble-check the `baseUrl` in your `IcebergRestCatalog` options. If applicable, ensure `catalogName` is set correctly and matches your server's configuration.
Warnings
- breaking Version 0.8.0 introduced changes to match the Iceberg Catalog API's return types and error structure more closely. This might require adjustments to existing code that processes responses or handles errors.
- breaking Version 0.8.1 included an alignment of `IcebergType` with the OpenAPI specification. If your application relies on specific internal type definitions that deviate from the standard, this update might introduce type-related breaking changes.
- gotcha This library is 'Catalog-only' and does not provide functionality for reading or writing data files (e.g., Parquet). It strictly interacts with the Iceberg REST Catalog for metadata operations.
- gotcha The library explicitly targets Node.js version 20.0.0 or higher. Running in older Node.js environments may lead to runtime errors, particularly concerning the native `fetch` API.
- gotcha Incorrect configuration of `baseUrl`, `catalogName`, or `auth` options can lead to 4xx HTTP errors (e.g., 401 Unauthorized, 403 Forbidden, 404 Not Found) when interacting with the Iceberg REST Catalog.
Install
-
npm install iceberg-js -
yarn add iceberg-js -
pnpm add iceberg-js
Imports
- IcebergRestCatalog
const { IcebergRestCatalog } = require('iceberg-js')import { IcebergRestCatalog } from 'iceberg-js' - AuthConfig
import type { AuthConfig } from 'iceberg-js' - AccessDelegation
import type { AccessDelegation } from 'iceberg-js'
Quickstart
import { IcebergRestCatalog } from 'iceberg-js'
const catalog = new IcebergRestCatalog({
baseUrl: 'https://my-catalog.example.com/iceberg/v1',
auth: {
type: 'bearer',
token: process.env.ICEBERG_TOKEN ?? '', // Provide a fallback for process.env
},
})
async function setupIceberg() {
try {
// Create a namespace
console.log('Creating namespace...')
await catalog.createNamespace({ namespace: ['analytics'] })
console.log('Namespace "analytics" created.')
// Create a table
console.log('Creating table "events"...')
await catalog.createTable(
{ namespace: ['analytics'] },
{
name: 'events',
schema: {
type: 'struct',
fields: [
{ id: 1, name: 'id', type: 'long', required: true },
{ id: 2, name: 'timestamp', type: 'timestamp', required: true },
{ id: 3, name: 'user_id', type: 'string', required: false },
],
'schema-id': 0,
'identifier-field-ids': [1],
},
'partition-spec': {
'spec-id': 0,
fields: [],
},
'write-order': {
'order-id': 0,
fields: [],
},
properties: {
'write.format.default': 'parquet',
},
}
)
console.log('Table "events" created in "analytics" namespace.')
} catch (error) {
console.error('Error during Iceberg setup:', error)
}
}
setupIceberg();