npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sqlrooms/kepler

v0.29.0

Published

Kepler.gl integration for SQLRooms.

Readme

Kepler.gl integration for SQLRooms.

Use this package when you want a map-first analytics experience in a SQLRooms app, backed by DuckDB tables and SQL.

What this package provides

  • createKeplerSlice() to add Kepler state/actions to your Room store
  • KeplerMapContainer and KeplerPlotContainer for rendering maps/overlays
  • KeplerSidePanels for layer/filter/interaction UI
  • utilities for map config persistence, dataset synchronization, and migration from legacy Kepler-owned tabs to artifact-backed tabs

Selection model

  • createKeplerSlice() manages Kepler map documents and runtime state keyed by map id, but it does not own host-level map selection.
  • Render maps with explicit ids, for example <KeplerMapContainer mapId={id} />.
  • Use @sqlrooms/artifacts when an app needs multiple user-managed map tabs; artifact state should own the selected map artifact.

Installation

npm install @sqlrooms/kepler @sqlrooms/room-shell @sqlrooms/duckdb @sqlrooms/ui

Quick start

import {useEffect} from 'react';
import {
  createKeplerSlice,
  KeplerMapContainer,
  KeplerSliceState,
} from '@sqlrooms/kepler';
import {
  createRoomShellSlice,
  createRoomStore,
  RoomShell,
  RoomShellSliceState,
} from '@sqlrooms/room-shell';

type RoomState = RoomShellSliceState & KeplerSliceState;

export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
  (set, get, store) => ({
    ...createRoomShellSlice({
      config: {
        dataSources: [
          {
            type: 'url',
            tableName: 'earthquakes',
            url: 'https://huggingface.co/datasets/sqlrooms/earthquakes/resolve/main/earthquakes.parquet',
          },
        ],
      },
    })(set, get, store),
    ...createKeplerSlice()(set, get, store),
  }),
);

function MapPanel() {
  const mapId = useRoomStore((state) => state.kepler.config.maps[0]?.id);
  const addTableToMap = useRoomStore((state) => state.kepler.addTableToMap);
  const isTableReady = useRoomStore((state) =>
    Boolean(state.db.findTable('earthquakes')),
  );

  useEffect(() => {
    if (!isTableReady || !mapId) return;
    void addTableToMap({
      mapId,
      tableName: 'earthquakes',
      options: {
        autoCreateLayers: true,
        centerMap: true,
      },
    });
  }, [isTableReady, mapId, addTableToMap]);

  if (!mapId) return null;

  return <KeplerMapContainer mapId={mapId} />;
}

export function App() {
  return (
    <RoomShell roomStore={roomStore} className="h-screen">
      <MapPanel />
    </RoomShell>
  );
}

Adding tables to maps

Use state.kepler.addTableToMap() to load a DuckDB table into a Kepler map. The preferred API is an object parameter:

await state.kepler.addTableToMap({
  mapId,
  tableName: 'earthquakes',
  options: {
    autoCreateLayers: true,
    centerMap: true,
  },
});

tableName is the SQL table reference to load. It can also be a saved Kepler dataset id when the configured table-selection policy can resolve that id back to a DuckDB table.

For normal add-table flows, omit datasetId. SQLRooms derives the persisted Kepler dataset id from the table-selection policy:

await state.kepler.addTableToMap({
  mapId,
  tableName: 'main.places',
});

Only pass datasetId when you need to load a table under an existing Kepler dataId, such as when restoring a saved map config:

await state.kepler.addTableToMap({
  mapId,
  tableName: savedDataId,
  options: {
    autoCreateLayers: false,
    centerMap: false,
  },
  datasetId: savedDataId,
});

The older positional signature is still accepted for compatibility, but new code should use the object form so the table reference, Kepler options, config, and dataset-id override remain clear at the call site.

Common customization

Pass options to createKeplerSlice():

import {createKeplerTheme, type KeplerThemeOverrides} from '@sqlrooms/kepler';

createKeplerSlice({
  basicKeplerProps: {
    mapboxApiAccessToken: import.meta.env.VITE_MAPBOX_TOKEN,
  },
  keplerTheme: createKeplerTheme({
    modalOverLayZ: 40,
  } satisfies KeplerThemeOverrides),
  modalPortalTarget: 'body',
  actionLogging: false,
});

Notes:

  • basicKeplerProps is for base Kepler registration/component props.
  • keplerTheme (optional) sets the theme passed to Kepler ThemeProvider.
  • modalPortalTarget controls modal portal placement: 'container' (default) or 'body'.

Table selection and dataset ids

tableSelection controls which DuckDB tables Kepler exposes and how those tables are represented in persisted Kepler layer and filter config.

createKeplerSlice({
  tableSelection: {
    defaultDbSchema: {
      database: 'project',
      schema: 'main',
    },
    includeTable: (table) => table.table.database === 'project',
  },
});

By default, tables in defaultDbSchema use bare dataset ids such as places. Tables outside that database/schema use qualified SQL table references. This keeps common main-schema project tables readable while preserving enough identity for tables from other schemas.

Use includeTable to hide tables from Kepler's Add Layer UI and to skip matching saved dataset ids during dataset synchronization. Host apps commonly use this to hide attached databases that will not be available when a project is reopened.

If the default dataset-id policy is not right for your app, provide both getDatasetIdForTable and findTableForDatasetId so new layers and restored layers agree on the same identity scheme:

createKeplerSlice({
  tableSelection: {
    getDatasetIdForTable: (table) =>
      `${table.table.schema}:${table.table.table}`,
    findTableForDatasetId: (tables, datasetId) => {
      const [schema, tableName] = datasetId.split(':');
      return tables.find(
        (table) =>
          table.table.schema === schema && table.table.table === tableName,
      );
    },
    getTableLabel: (table) =>
      [table.table.schema, table.table.table].filter(Boolean).join('.'),
  },
});

getTableLabel only affects display labels in Kepler table selectors. It does not change persisted dataset ids.

Related packages

  • @sqlrooms/artifacts for artifact-backed map tabs
  • @sqlrooms/kepler-config for Zod schemas used by persisted Kepler config
  • @sqlrooms/room-shell for Room store composition and UI shell
  • @sqlrooms/duckdb for DuckDB-backed table loading/querying

Examples

  • Kepler example app: https://github.com/sqlrooms/examples/tree/main/kepler