An open API service indexing awesome lists of open source software.

https://github.com/tobilg/react-sql-workbench-embedded

A React wrapper component for sql-workbench-embedded, enabling interactive SQL execution environments powered by DuckDB WASM.
https://github.com/tobilg/react-sql-workbench-embedded

duckdb-wasm react sql

Last synced: about 1 month ago
JSON representation

A React wrapper component for sql-workbench-embedded, enabling interactive SQL execution environments powered by DuckDB WASM.

Awesome Lists containing this project

README

          

# react-sql-workbench-embedded

A React wrapper component for [sql-workbench-embedded](https://github.com/tobilg/sql-workbench-embedded), enabling interactive SQL execution environments powered by DuckDB WASM directly in your React applications.

## Features

- **React 18 & 19 Compatible**: Works with both React 18 and React 19
- **Zero Backend Required**: All SQL execution happens in the browser via DuckDB WASM
- **Type-Safe**: Full TypeScript support with comprehensive type definitions
- **Flexible API**: Use as a simple component or with global configuration via Context Provider
- **Customizable**: Support for themes (light/dark/auto), custom themes, and extensive configuration options
- **Modern Development**: Built with Vite, tested with Vitest
- **Privacy-Focused**: No data leaves the browser
- **Multiple Distribution Formats**: Available as ESM and UMD builds for maximum compatibility
- **CDN-Ready**: Can be used directly from CDN without build tools

## Installation

### Via npm

```bash
npm install react-sql-workbench-embedded
```

### Via CDN (UMD)

```html

const { SQLWorkbenchEmbedded } = window.SQLWorkbenchEmbedded;
// Use the component...

```

### Via CDN (ESM with Import Maps)

```html

{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react@18/+esm",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@18/+esm",
"@duckdb/duckdb-wasm": "https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm@1.31.1-dev1.0/+esm",
"react-sql-workbench-embedded": "https://cdn.jsdelivr.net/npm/react-sql-workbench-embedded/dist/react-sql-workbench-embedded.esm.js"
}
}

import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';
// Use the component...

```

## Quick Start

### Basic Usage (npm)

```tsx
import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

function App() {
return (

);
}
```

### With Provider (Global Configuration)

```tsx
import { SQLWorkbenchProvider, SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

function App() {
return (



);
}
```

## API Reference

### `SQLWorkbenchEmbedded` Component

#### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `initialCode` | `string` | `''` | Initial SQL code to display in the workbench |
| `theme` | `'light' \| 'dark' \| 'auto' \| string` | `'auto'` | Theme for the workbench |
| `editable` | `boolean` | `true` | Whether the SQL editor is editable |
| `showOpenButton` | `boolean` | `true` | Show "Open in SQL Workbench" button |
| `className` | `string` | `''` | Custom className for the container element |
| `style` | `React.CSSProperties` | - | Custom styles for the container element |
| `onReady` | `(instance) => void` | - | Callback when workbench is ready |
| `onError` | `(error) => void` | - | Callback when initialization fails |

#### Ref API

```tsx
import { useRef } from 'react';
import { SQLWorkbenchEmbedded, type SQLWorkbenchEmbeddedRef } from 'react-sql-workbench-embedded';

function App() {
const ref = useRef(null);

return (

);
}
```

Methods available via ref:
- `getInstance()`: Get the underlying SQLWorkbench instance
- `getElement()`: Get the container element

### `SQLWorkbenchProvider` Component

Provides global configuration for all SQLWorkbenchEmbedded components.

#### Props

| Prop | Type | Description |
|------|------|-------------|
| `config` | `SQLWorkbenchConfig` | Global configuration options |
| `children` | `ReactNode` | Child components |
| `onReady` | `() => void` | Callback when SQL Workbench is ready |
| `onError` | `(error) => void` | Callback when initialization fails |

#### Configuration Options

```typescript
interface SQLWorkbenchConfig {
selector?: string;
baseUrl?: string;
theme?: 'light' | 'dark' | 'auto' | string;
autoInit?: boolean;
duckdbVersion?: string;
duckdbCDN?: string;
editable?: boolean;
showOpenButton?: boolean;
initQueries?: string[];
customThemes?: Record;
}
```

### `useSQLWorkbench` Hook

Hook to access SQL Workbench context status.

```tsx
import { useSQLWorkbench } from 'react-sql-workbench-embedded';

function MyComponent() {
const { isReady, error } = useSQLWorkbench();

if (error) return

Error: {error.message}
;
if (!isReady) return
Loading...
;

return ;
}
```

## Usage Examples

### 1. Simple Component

The simplest way to use the component:

```tsx
import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
return (


My SQL Workbench




);
}
```

### 2. With Callbacks

Handle initialization events:

```tsx
import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
return (
{
console.log('Workbench ready!', instance);
}}
onError={(error) => {
console.error('Failed to initialize:', error);
}}
/>
);
}
```

### 3. Theme Switching

Allow users to switch themes:

```tsx
import { useState } from 'react';
import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
const [theme, setTheme] = useState<'light' | 'dark' | 'auto'>('auto');

return (


setTheme(e.target.value)}>
Auto
Light
Dark



);
}
```

### 4. Using Provider for Multiple Instances

Share configuration across multiple workbenches:

```tsx
import { SQLWorkbenchProvider, SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
return (


Query 1


Query 2





);
}
```

### 5. Loading DuckDB Extensions

Load extensions for spatial operations:

```tsx
import { SQLWorkbenchProvider, SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
return (



);
}
```

### 6. Read-Only Mode

Create a read-only SQL display:

```tsx
import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
return (

);
}
```

### 7. Using Refs

Access the underlying instance:

```tsx
import { useRef } from 'react';
import { SQLWorkbenchEmbedded, SQLWorkbenchEmbeddedRef } from 'react-sql-workbench-embedded';

export default function App() {
const workbenchRef = useRef(null);

const handleClick = () => {
const instance = workbenchRef.current?.getInstance();
console.log('Current instance:', instance);
};

return (



Get Instance



);
}
```

### 8. Loading Data from URLs

Query CSV files from URLs using httpfs extension:

```tsx
import { SQLWorkbenchProvider, SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
return (



);
}
```

### 9. Custom Styling

Add custom styles to the workbench:

```tsx
import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
return (

);
}
```

### 10. Conditional Rendering with Hook

Use the `useSQLWorkbench` hook to handle loading states:

```tsx
import { SQLWorkbenchProvider, SQLWorkbenchEmbedded, useSQLWorkbench } from 'react-sql-workbench-embedded';

function WorkbenchContent() {
const { isReady, error } = useSQLWorkbench();

if (error) {
return

Error: {error.message}
;
}

if (!isReady) {
return

Loading SQL Workbench...
;
}

return (

);
}

export default function App() {
return (



);
}
```

### 11. Custom Themes

```tsx

```

### 12. Multiple Instances with Different Themes

```tsx
function App() {
return (


Light Theme


Dark Theme




);
}
```

## TypeScript Usage

The library is fully typed. Here's how to use types:

```tsx
import { useState, useRef } from 'react';
import type {
SQLWorkbenchEmbeddedRef,
SQLWorkbenchConfig,
Theme
} from 'react-sql-workbench-embedded';

const config: SQLWorkbenchConfig = {
theme: 'dark',
editable: true,
initQueries: ['INSTALL spatial']
};

function MyComponent() {
const [theme, setTheme] = useState('auto');
const ref = useRef(null);

// ... rest of component
}
```

## Common Patterns

### Error Boundaries

Wrap the component in an error boundary:

```tsx
import { Component, ReactNode } from 'react';

class ErrorBoundary extends Component<
{ children: ReactNode },
{ hasError: boolean }
> {
constructor(props: { children: ReactNode }) {
super(props);
this.state = { hasError: false };
}

static getDerivedStateFromError() {
return { hasError: true };
}

render() {
if (this.state.hasError) {
return

Something went wrong.

;
}
return this.props.children;
}
}

export default function App() {
return (



);
}
```

### Dynamic Code Updates

Update SQL code dynamically:

```tsx
import { useState } from 'react';
import { SQLWorkbenchEmbedded } from 'react-sql-workbench-embedded';

export default function App() {
const [code, setCode] = useState("SELECT 1;");

const queries = [
"SELECT * FROM generate_series(1, 10);",
"SELECT DATE '2024-01-01' + INTERVAL (n) DAY FROM generate_series(0, 6) t(n);",
"SELECT 'Hello', 'World';"
];

return (



{queries.map((query, idx) => (
setCode(query)}>
Query {idx + 1}

))}



);
}
```

## Tips

1. **Force Remount**: Use the `key` prop to force component remount when you want to reset the workbench completely.

2. **Provider vs. Component Config**: Use Provider for shared configuration across multiple instances. Use component props for instance-specific overrides.

3. **Init Queries**: Use `initQueries` to install and load DuckDB extensions. These run once before any user queries.

4. **Theme Priority**: Component prop > HTML attribute > Provider config. Choose the level that makes sense for your use case.

5. **Performance**: The DuckDB WASM runtime is lazy-loaded only when needed, so initial page load stays fast.

## Development

### Setup

```bash
# Clone the repository
git clone https://github.com/tobilg/react-sql-workbench-embedded.git
cd react-sql-workbench-embedded

# Install dependencies
npm install

# Start development server
npm run dev

# Run tests
npm test

# Run tests with UI
npm run test:ui

# Build the library
npm run build
```

### Project Structure

```
react-sql-workbench-embedded/
├── src/
│ ├── components/
│ │ ├── SQLWorkbenchEmbedded.tsx # Main component
│ │ ├── SQLWorkbenchProvider.tsx # Context provider
│ │ └── __tests__/ # Component tests
│ ├── demo/ # Demo application
│ │ ├── App.tsx
│ │ └── main.tsx
│ ├── types.ts # TypeScript types
│ └── index.ts # Main entry point
├── vite.config.ts # Vite configuration
├── vitest.config.ts # Vitest configuration
└── package.json
```

## Requirements

- React 18+ or React 19+
- TypeScript 5.6+ (for development)
- Modern browser with WebAssembly support

## Browser Compatibility

This library requires a modern browser with support for:
- ES Modules (for ESM builds)
- WebAssembly
- Import Maps (for ESM CDN usage)

For the UMD build, all major modern browsers are supported without additional configuration.

## Distribution Formats

This library is distributed in two formats:

### ESM (ES Module)
- **File**: `dist/react-sql-workbench-embedded.esm.js` (~32 KB, ~10 KB gzipped)
- **Use case**: Modern build tools (Vite, Webpack, etc.) or direct browser usage with import maps
- **Dependencies**: Requires React, ReactDOM, and @duckdb/duckdb-wasm to be available

### UMD (Universal Module Definition)
- **File**: `dist/react-sql-workbench-embedded.umd.js` (~31 KB, ~10 KB gzipped)
- **Use case**: Direct browser usage via `` tags or legacy module systems
- **Global**: Exposed as `window.SQLWorkbenchEmbedded`
- **Dependencies**: Requires React and ReactDOM to be loaded first (use React 18 for UMD compatibility)

Both formats:
- Bundle `sql-workbench-embedded` internally (no manual installation needed)
- Externalize React and ReactDOM (expected as peer dependencies)
- Use classic JSX runtime for maximum compatibility
- Include no polyfills (work directly in modern browsers)

## License

MIT