SQLRooms

SQLRoomsBuild data-centric apps with DuckDB

An open source React toolkit for human + agent collaborative analytics apps

Local Analytics, No Backend Required

Leverage DuckDB's powerful SQL capabilities, enabling fast in browser data processing without a backend

Own Your Data

Data remains on your local device for maximum privacy, sub-second analytics on large datasets, and offline functionality

Privacy-Preserving AI Integration

Use agents that can write and execute SQL queries, and generate insights without sharing your data with model providers

Modular Architecture

Pick and choose the functionality you need for composable, extensible applications, with integrations for popular data visualization libraries.

Modern UI Components

Comprehensive set of React components including data tables, layouts, and visualization tools for building beautiful analytics interfaces

Offline Use

Work with your data, run queries, and analyze results even without an internet connection. SQLRooms supports offline workflows using persistent storage via OPFS.


Get Started in Minutes

To create a new project from the minimal example, run:

sh

npx giget gh:sqlrooms/examples/minimal my-minimal-app/
cd my-minimal-app
npm install
npm run dev

Manual setup

Set up a simple room that loads and queries a single data table:

tsx

import {
  createRoomShellSlice,
  createRoomStore,
  RoomShellSliceState,
  RoomShell,
} from '@sqlrooms/room-shell';
import {useSql} from '@sqlrooms/duckdb';

type RoomState = RoomShellSliceState;

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

export const MyRoom = () => (
  <RoomShell roomStore={roomStore}>
    <MyComponent />
  </RoomShell>
);

function MyComponent() {
  const isTableReady = useRoomStore((state) =>
    Boolean(state.db.findTableByName('earthquakes')),
  );
  const queryResult = useSql<{maxMagnitude: number}>({
    query: `SELECT max(Magnitude) AS maxMagnitude FROM earthquakes`,
    enabled: isTableReady,
  });
  if (!isTableReady) return 'Loading…';
  const row = queryResult.data?.toArray()[0];
  return `Max earthquake magnitude: ${row?.maxMagnitude}`;
}

Complete example on GitHub →

That's it! You've just built an app with a flexible store and UI that can be extended with various analytics, visualization and AI modules — all powered by client-side DuckDB with no backend required.

For a more comprehensive guide, see Key Concepts and the Getting Started page.