Apache Arrow integration plugin for Stately
npm install @statelyjs/arrow> Apache Arrow data visualization plugin for Stately.


Provides streaming SQL query execution, table visualization, and connector management for Arrow-based data sources.
This package connects your application to a stately-arrow backend (Rust), giving you:
- Arrow Viewer page - Full-featured SQL query editor with streaming results
- Connector management - Browse and register data source connections
- Streaming queries - Execute SQL with real-time result streaming
- Arrow table visualization - High-performance table rendering with pagination and column controls
``bash`
pnpm add @statelyjs/arrow
`typescript
import { stately } from '@statelyjs/stately/schema';
import { type ArrowPlugin, arrowPlugin } from '@statelyjs/arrow';
const schema = stately
.withPlugin(arrowPlugin());
`
`typescript
import { statelyUi } from '@statelyjs/stately';
import { type ArrowUiPlugin, arrowUiPlugin } from '@statelyjs/arrow';
const runtime = statelyUi
schema,
client,
core: { api: { pathPrefix: '/entity' } },
options: { api: { pathPrefix: '/api' } },
}).withPlugin(arrowUiPlugin({
api: { pathPrefix: '/arrow' },
}));
`
`tsx
import { QueryClientProvider } from '@tanstack/react-query';
import { AppStatelyProvider, runtime } from './lib/stately';
function App() {
return (
);
}
`
Import the arrow styles and ensure your @source covers @statelyjs packages:
`css
@import "tailwindcss";
@import "@statelyjs/stately/styles.css";
@import "@statelyjs/arrow/styles.css";
@source "./node_modules/@statelyjs";
`
The plugin provides an ArrowViewer page component. Add it to your router:
`tsx
import { ArrowViewer } from '@statelyjs/arrow/pages';
// Example with React Router
`
All hooks use the arrow API through the plugin context:
Execute SQL queries with streaming results:
`tsx
import { useStreamingQuery } from '@statelyjs/arrow/hooks';
function QueryRunner() {
const { snapshot, execute, isPending, isStreaming } = useStreamingQuery();
const handleRun = () => {
execute({
connector_id: 'my-connector',
sql: 'SELECT * FROM users LIMIT 100',
});
};
return (
Rows: {snapshot.table.numRows}, Bytes: {snapshot.metrics.bytesReceived}
$3
Manage connector state and selection:
`tsx
import { useConnectors } from '@statelyjs/arrow/hooks';function ConnectorPicker() {
const { connectors, currentConnector, setConnectorId } = useConnectors();
return (
value={currentConnector?.id}
onChange={e => setConnectorId(e.target.value)}
>
{connectors.map(c => (
))}
);
}
`$3
Fetch available connectors:
`tsx
import { useListConnectors } from '@statelyjs/arrow/hooks';const { data: connectors, isLoading } = useListConnectors();
`$3
Get registered catalog connections:
`tsx
import { useListRegistered } from '@statelyjs/arrow/hooks';const { data: registrations } = useListRegistered();
`$3
Get details for a specific connector:
`tsx
import { useConnectionDetails } from '@statelyjs/arrow/hooks';const { data: details } = useConnectionDetails(connectorId);
`$3
Register a new connection:
`tsx
import { useRegisterConnection } from '@statelyjs/arrow/hooks';const { mutate: register } = useRegisterConnection();
register({ connectorId: 'postgres-1' });
`$3
List available catalogs:
`tsx
import { useListCatalogs } from '@statelyjs/arrow/hooks';const { data: catalogs } = useListCatalogs();
`Components
Reusable components for building data interfaces:
$3
High-performance table for Arrow data:
`tsx
import { ArrowTable } from '@statelyjs/arrow/components'; data={tableDataView}
isLoading={isStreaming}
/>
`$3
SQL editor with run controls and stats:
`tsx
import { QueryEditor } from '@statelyjs/arrow/components'; sql={sql}
onSql={setSql}
onRun={handleRun}
isExecuting={isPending}
stats={[
{ label: SquareSigma, value: '1,234' },
{ label: Timer, value: '45.2 ms' },
]}
/>
`$3
Pagination controls for tables:
`tsx
import { TablePagination } from '@statelyjs/arrow/components';
`$3
Column visibility toggles:
`tsx
import { TableViewOptions } from '@statelyjs/arrow/components';
`$3
Drawer for viewing row details:
`tsx
import { TableRowDrawer } from '@statelyjs/arrow/components';
`Views
Pre-built view cards for common layouts:
$3
`tsx
import { Connectors } from '@statelyjs/arrow/views';// Connector selection dropdown
connectors={connectors}
currentConnector={selected}
onSelect={handleSelect}
/>
// Connector browser with schema navigation
connectors={connectors}
currentConnector={selected}
onSelectItem={(identifier, type) => { / handle table/schema selection / }}
/>
// Registration card
connectors={connectors}
currentConnector={selected}
/>
`$3
`tsx
import { Query } from '@statelyjs/arrow/views';// Query editor card
sql={sql}
onSql={setSql}
onRun={handleRun}
isExecuting={isPending}
/>
// Results table card
data={tableDataView}
isLoading={isStreaming}
/>
`Pages
$3
Full-featured data exploration page with:
- Connector sidebar with schema browser
- SQL query editor with syntax highlighting
- Streaming results table with pagination
- Query statistics (rows, bytes, elapsed time)
- Responsive layout with collapsible sidebar
`tsx
import { ArrowViewer } from '@statelyjs/arrow/pages';// Basic usage
} />
// With streaming subscription
console.log('Stream event:', event)} />
`Library Utilities
Low-level utilities for custom implementations:
$3
Store for managing Arrow table state:
`typescript
import { createArrowTableStore } from '@statelyjs/arrow/lib';const store = createArrowTableStore();
store.subscribe(snapshot => {
console.log('Table updated:', snapshot.table?.numRows);
});
`$3
Execute streaming queries directly:
`typescript
import { streamQuery } from '@statelyjs/arrow/lib';await streamQuery({
client,
sql: 'SELECT * FROM users',
connectorId: 'my-connector',
onBatch: (table) => console.log('Batch:', table.numRows),
});
`$3
Convert Arrow table to component-friendly format:
`typescript
import { tableToDataView } from '@statelyjs/arrow/lib';const view = tableToDataView(arrowTable);
// { columns: [...], rows: [...] }
`Backend Requirements
This plugin expects a
stately-arrow compatible backend with these endpoints:| Endpoint | Method | Description |
|----------|--------|-------------|
|
/connectors | GET | List available connectors |
| /connectors | POST | Get details for multiple connectors |
| /connectors/{connector_id} | GET | Get connector details |
| /register | GET | List registered connections |
| /register/{connector_id} | GET | Register a connector |
| /catalogs | GET | List available catalogs |
| /query | POST | Execute SQL query (streaming response) |The
/query` endpoint returns Apache Arrow IPC stream format for efficient data transfer.Apache-2.0