JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2745699
  • Score
    100M100P100Q195384F
  • License ISC

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (iceberg-js) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    iceberg-js

    CI npm version pkg.pr.new

    A small, framework-agnostic JavaScript/TypeScript client for the Apache Iceberg REST Catalog.

    Features

    • Generic: Works with any Iceberg REST Catalog implementation, not tied to any specific vendor
    • Minimal: Thin HTTP wrapper over the official REST API, no engine-specific logic
    • Type-safe: First-class TypeScript support with strongly-typed request/response models
    • Fetch-based: Uses native fetch API with support for custom implementations
    • Universal: Targets Node 20+ and modern browsers (ES2020)
    • Catalog-only: Focused on catalog operations (no data reading/Parquet support in v0.1.0)

    Documentation

    📚 Full API documentation: supabase.github.io/iceberg-js

    Installation

    npm install iceberg-js

    Quick Start

    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,
      },
    })
    
    // Create a namespace
    await catalog.createNamespace({ namespace: ['analytics'] })
    
    // Create a table
    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',
        },
      }
    )

    API Reference

    Constructor

    new IcebergRestCatalog(options)

    Creates a new catalog client instance.

    Options:

    • baseUrl (string, required): Base URL of the REST catalog
    • auth (AuthConfig, optional): Authentication configuration
    • catalogName (string, optional): Catalog name for multi-catalog servers. When specified, requests are sent to {baseUrl}/v1/{catalogName}/.... For example, with baseUrl: 'https://host.com' and catalogName: 'prod', requests go to https://host.com/v1/prod/namespaces
    • fetch (typeof fetch, optional): Custom fetch implementation
    • accessDelegation (AccessDelegation[], optional): Access delegation mechanisms to request from the server

    Authentication types:

    // No authentication
    { type: 'none' }
    
    // Bearer token
    { type: 'bearer', token: 'your-token' }
    
    // Custom header
    { type: 'header', name: 'X-Custom-Auth', value: 'secret' }
    
    // Custom function
    { type: 'custom', getHeaders: async () => ({ 'Authorization': 'Bearer ...' }) }

    Access Delegation:

    Access delegation allows the catalog server to provide temporary credentials or sign requests on your behalf:

    import { IcebergRestCatalog } from 'iceberg-js'
    
    const catalog = new IcebergRestCatalog({
      baseUrl: 'https://catalog.example.com/iceberg/v1',
      auth: { type: 'bearer', token: 'your-token' },
      // Request vended credentials for data access
      accessDelegation: ['vended-credentials'],
    })
    
    // The server may return temporary credentials in the table metadata
    const metadata = await catalog.loadTable({ namespace: ['analytics'], name: 'events' })
    // Use credentials from metadata.config to access table data files

    Supported delegation mechanisms:

    • vended-credentials: Server provides temporary credentials (e.g., AWS STS tokens) for accessing table data
    • remote-signing: Server signs data access requests on behalf of the client

    Namespace Operations

    listNamespaces(parent?: NamespaceIdentifier): Promise<NamespaceIdentifier[]>

    List all namespaces, optionally under a parent namespace.

    const namespaces = await catalog.listNamespaces()
    // [{ namespace: ['default'] }, { namespace: ['analytics'] }]
    
    const children = await catalog.listNamespaces({ namespace: ['analytics'] })
    // [{ namespace: ['analytics', 'prod'] }]

    createNamespace(id: NamespaceIdentifier, metadata?: NamespaceMetadata): Promise<void>

    Create a new namespace with optional properties.

    await catalog.createNamespace({ namespace: ['analytics'] }, { properties: { owner: 'data-team' } })

    dropNamespace(id: NamespaceIdentifier): Promise<void>

    Drop a namespace. The namespace must be empty.

    await catalog.dropNamespace({ namespace: ['analytics'] })

    loadNamespaceMetadata(id: NamespaceIdentifier): Promise<NamespaceMetadata>

    Load namespace metadata and properties.

    const metadata = await catalog.loadNamespaceMetadata({ namespace: ['analytics'] })
    // { properties: { owner: 'data-team', ... } }

    Table Operations

    listTables(namespace: NamespaceIdentifier): Promise<TableIdentifier[]>

    List all tables in a namespace.

    const tables = await catalog.listTables({ namespace: ['analytics'] })
    // [{ namespace: ['analytics'], name: 'events' }]

    createTable(namespace: NamespaceIdentifier, request: CreateTableRequest): Promise<TableMetadata>

    Create a new table.

    const metadata = 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 },
          ],
          'schema-id': 0,
        },
        'partition-spec': {
          'spec-id': 0,
          fields: [
            {
              source_id: 2,
              field_id: 1000,
              name: 'ts_day',
              transform: 'day',
            },
          ],
        },
      }
    )

    loadTable(id: TableIdentifier): Promise<TableMetadata>

    Load table metadata.

    const metadata = await catalog.loadTable({
      namespace: ['analytics'],
      name: 'events',
    })

    updateTable(id: TableIdentifier, request: UpdateTableRequest): Promise<TableMetadata>

    Update table metadata (schema, partition spec, or properties).

    const updated = await catalog.updateTable(
      { namespace: ['analytics'], name: 'events' },
      {
        properties: { 'read.split.target-size': '134217728' },
      }
    )

    dropTable(id: TableIdentifier): Promise<void>

    Drop a table from the catalog.

    await catalog.dropTable({ namespace: ['analytics'], name: 'events' })

    Error Handling

    All API errors throw an IcebergError with details from the server:

    import { IcebergError } from 'iceberg-js'
    
    try {
      await catalog.loadTable({ namespace: ['test'], name: 'missing' })
    } catch (error) {
      if (error instanceof IcebergError) {
        console.log(error.status) // 404
        console.log(error.icebergType) // 'NoSuchTableException'
        console.log(error.message) // 'Table does not exist'
      }
    }

    TypeScript Types

    The library exports all relevant types:

    import type {
      NamespaceIdentifier,
      TableIdentifier,
      TableSchema,
      TableField,
      IcebergType,
      PartitionSpec,
      SortOrder,
      CreateTableRequest,
      TableMetadata,
      AuthConfig,
      AccessDelegation,
    } from 'iceberg-js'

    Supported Iceberg Types

    The following Iceberg primitive types are supported:

    • boolean, int, long, float, double
    • string, uuid, binary
    • date, time, timestamp, timestamptz
    • decimal(precision, scale), fixed(length)

    Compatibility

    This package is built to work in all Node.js and JavaScript environments:

    Environment Module System Import Method Status
    Node.js ESM "type": "module" import { ... } from 'iceberg-js' ✅ Fully supported
    Node.js CommonJS Default const { ... } = require('iceberg-js') ✅ Fully supported
    TypeScript ESM module: "ESNext" import { ... } from 'iceberg-js' ✅ Full type support
    TypeScript CommonJS module: "CommonJS" import { ... } from 'iceberg-js' ✅ Full type support
    Bundlers Any Webpack, Vite, esbuild, Rollup, etc. ✅ Auto-detected
    Browsers ESM <script type="module"> ✅ Modern browsers
    Deno ESM import from npm: ✅ With npm specifier

    Package exports:

    • ESM: dist/index.mjs with dist/index.d.ts
    • CommonJS: dist/index.cjs with dist/index.d.cts
    • Proper exports field for Node.js 12+ module resolution

    All scenarios are tested in CI on Node.js 20 and 22.

    Browser Usage

    The library works in modern browsers that support native fetch:

    import { IcebergRestCatalog } from 'iceberg-js'
    
    const catalog = new IcebergRestCatalog({
      baseUrl: 'https://public-catalog.example.com/iceberg/v1',
      auth: { type: 'none' },
    })
    
    const namespaces = await catalog.listNamespaces()

    Node.js Usage

    Node.js 20+ includes native fetch support. For older versions, provide a custom fetch implementation:

    import { IcebergRestCatalog } from 'iceberg-js'
    import fetch from 'node-fetch'
    
    const catalog = new IcebergRestCatalog({
      baseUrl: 'https://catalog.example.com/iceberg/v1',
      auth: { type: 'bearer', token: 'token' },
      fetch: fetch as any,
    })

    Limitations (v0.1.0)

    This is a catalog client only. The following are not supported:

    • Reading table data (scanning Parquet files)
    • Writing data to tables
    • Advanced table operations (commits, snapshots, time travel)
    • Views support
    • Multi-table transactions

    Development

    # Install dependencies
    pnpm install
    
    # Build the library
    pnpm run build
    
    # Run unit tests
    pnpm test
    
    # Run integration tests (requires Docker)
    pnpm test:integration
    
    # Run integration tests with cleanup (for CI)
    pnpm test:integration:ci
    
    # Run compatibility tests (all module systems)
    pnpm test:compatibility
    
    # Format code
    pnpm run format
    
    # Lint and test
    pnpm run check

    Testing with Docker

    Integration tests run against a local Iceberg REST Catalog in Docker. See TESTING-DOCKER.md for details.

    # Start Docker services and run integration tests
    pnpm test:integration
    
    # Or manually
    docker compose up -d
    npx tsx test/integration/test-local-catalog.ts
    docker compose down -v

    Compatibility Testing

    The test:compatibility script verifies the package works correctly in all JavaScript/TypeScript environments:

    • Pure JavaScript ESM - Projects with "type": "module"
    • Pure JavaScript CommonJS - Traditional Node.js projects
    • TypeScript ESM - TypeScript with module: "ESNext"
    • TypeScript CommonJS - TypeScript with module: "CommonJS"

    These tests ensure proper module resolution, type definitions, and runtime behavior across all supported environments. See test/compatibility/README.md for more details.

    License

    MIT

    Releases

    This project uses release-please for automated releases. Here's how it works:

    1. Commit with conventional commits: Use Conventional Commits format for your commits:

      • feat: for new features (minor version bump)
      • fix: for bug fixes (patch version bump)
      • feat!: or BREAKING CHANGE: for breaking changes (major version bump)
      • chore:, docs:, test:, etc. for non-release commits
    2. Release PR is created automatically: When you push to main, release-please creates/updates a release PR with:

      • Version bump in package.json
      • Updated CHANGELOG.md
      • Release notes
    3. Merge the release PR: When you're ready to release, merge the PR. This will:

      • Create a GitHub release and git tag
      • Automatically publish to npm with provenance (using trusted publishing, no secrets needed)

    Example commits:

    git commit -m "feat: add support for view operations"
    git commit -m "fix: handle empty namespace list correctly"
    git commit -m "feat!: change auth config structure"

    Contributing

    Contributions are welcome! This library aims to be a minimal, generic client for the Iceberg REST Catalog API.