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

@superatomai/renderer-react

v0.0.2

Published

SuperAtom Runtime SDK - React components for rendering JSON UI schemas

Downloads

73

Readme

@superatomai/renderer-react

React components for rendering JSON UI schemas from SuperAtom responses.

Table of Contents

Installation

pnpm add @superatomai/renderer-react
# or
npm install @superatomai/renderer-react
# or
yarn add @superatomai/renderer-react

Peer Dependencies

This package requires React 18+:

pnpm add react react-dom

Quick Start

1. Basic Usage

import { useState } from 'react';
import { DSLRenderer } from '@superatomai/renderer-react';

function DashboardPanel() {
  const [uiSchema, setUiSchema] = useState(null);
  const [uiData, setUiData] = useState(null);

  const handleRenderUI = (schema: any, data: any) => {
    setUiSchema(schema);
    setUiData(data || {});
  };

  return (
    <div>
      {uiSchema && (
        <DSLRenderer
          dsl={uiSchema}
          data={uiData}
          handlers={{}}
        />
      )}
    </div>
  );
}

export default DashboardPanel;

2. Report Generation

import { useState } from 'react';
import { DSLRenderer } from '@superatomai/renderer-react';

function ReportGenerator() {
  const [reports, setReports] = useState([]);

  const addReport = (schema: any, data: any) => {
    setReports(prev => [...prev, {
      id: Date.now(),
      schema,
      data: data || {}
    }]);
  };

  return (
    <div className="report-container">
      {reports.map(report => (
        <div key={report.id} className="report-card">
          <DSLRenderer
            dsl={report.schema}
            data={report.data}
          />
        </div>
      ))}
    </div>
  );
}

3. Dashboard with Multiple Panels

import { useState } from 'react';
import { DSLRenderer } from '@superatomai/renderer-react';

interface DashboardPanel {
  id: string;
  title: string;
  schema: any;
  data: any;
}

function Dashboard() {
  const [panels, setPanels] = useState<DashboardPanel[]>([]);

  const addPanel = (title: string, schema: any, data: any) => {
    setPanels(prev => [...prev, {
      id: `panel-${Date.now()}`,
      title,
      schema,
      data
    }]);
  };

  return (
    <div className="grid grid-cols-2 gap-4">
      {panels.map(panel => (
        <div key={panel.id} className="panel-card">
          <h3>{panel.title}</h3>
          <DSLRenderer
            dsl={panel.schema}
            data={panel.data}
          />
        </div>
      ))}
    </div>
  );
}

API Reference

<DSLRenderer>

Main component for rendering JSON UI schemas.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | dsl | UIComponent | Yes | The UI schema to render | | data | Record<string, any> | No | Data context for the UI | | context | Record<string, any> | No | Additional context variables | | handlers | Record<string, Function> | No | Event handlers for components | | onNavigate | (uiid: string, params?: Record<string, any>) => void | No | Navigation handler |

Component Registry

COMP_REGISTRY

Global registry containing all available components (both native and dynamically loaded).

import { COMP_REGISTRY } from '@superatomai/renderer-react';

// Access the registry
console.log(Object.keys(COMP_REGISTRY)); // ['COMP_ECHART', 'COMP_AGGRID', ...]

getComponentStates()

Returns the current state of all components.

import { getComponentStates } from '@superatomai/renderer-react';

const states = getComponentStates();
// Returns: { loaded: string[], loading: string[], failed: string[] }

resetFailedComponent(componentId: string)

Resets the failed state of a specific component, allowing it to be retried.

import { resetFailedComponent } from '@superatomai/renderer-react';

resetFailedComponent('echarts'); // Allows echarts to be loaded again

resetAllFailedComponents()

Resets all failed components.

import { resetAllFailedComponents } from '@superatomai/renderer-react';

const count = resetAllFailedComponents(); // Returns number of components reset

<DynamicComponent>

Low-level component for rendering registry components directly (rarely needed).

import { DynamicComponent } from '@superatomai/renderer-react';

<DynamicComponent
  type="COMP_ECHART"
  props={{ option: {...} }}
/>

Example

<DSLRenderer
  dsl={{
    id: 'chart-component',
    name: 'ChartComponent',
    data: { chartData: [...] },
    render: {
      id: 'render-root',
      type: 'COMP_ECHART',
      props: {
        option: { $bind: 'chartData' }
      }
    }
  }}
  data={{ chartData: [...] }}
  handlers={{
    onChartClick: (params) => console.log('Chart clicked', params)
  }}
/>

Available Components

The SDK includes the following native components:

  • COMP_ECHART - ECharts for data visualization
  • COMP_AGGRID - AG Grid for data tables
  • COMP_HANDSONTABLE - Handsontable for spreadsheets
  • COMP_LEAFLET - Leaflet for maps
  • COMP_MAPBOX - Mapbox GL for advanced maps
  • COMP_VIS_NETWORK - Network/graph visualizations
  • COMP_THREE_SCENE - 3D visualizations with Three.js
  • COMP_PDF_VIEWER - PDF document viewer
  • COMP_LUCKYSHEET - Excel-like spreadsheet
  • COMP_MARKDOWN - Markdown renderer
  • COMP_ICONIFY_ICON - Icon library

Dynamic Component Loading from Bundles

This package supports automatic registration of custom components from external bundles. This allows you to build your own components separately, bundle them, and have them automatically loaded into the component registry at runtime.

How It Works

  1. Package Initialization: When you import @superatomai/renderer-react, it automatically:

    • Sets up an event listener for component loading
    • Exposes window.runtime.componentsLoaded() for bundles to call
    • Watches window.SUPERATOM.COMPONENTS for new components
  2. Bundle Setup: Your bundle calls setup() from @superatomai/sdk-web and triggers the event

  3. Auto-Registration: Components are wrapped and registered in COMP_REGISTRY with keys like COMP_YourComponent

Creating a Bundle with Custom Components

Step 1: Define Your Components

// src/components/DynamicBarChart.tsx
export default function DynamicBarChart({ data, config }) {
  return (
    <div>
      {/* Your custom bar chart implementation */}
    </div>
  );
}

Step 2: Setup Bundle Entry Point

// src/superatom.ts
import { createRoot } from 'react-dom/client';
import { createElement } from 'react';
import { setup } from '@superatomai/sdk-web';
import DynamicBarChart from './components/DynamicBarChart';
import DynamicDataTable from './components/DynamicDataTable';

const COMPONENTS = {
  DynamicBarChart,
  DynamicDataTable,
  // Add your other components...

  // REQUIRED: mount function for React version isolation
  mount: (Component, container, props) => {
    // Use the bundle's own React instance to create a root
    const root = createRoot(container);
    root.render(createElement(Component, props));
    return { unmount: () => root.unmount() };
  }
};

const SUPERATOM = {
  init: async () => {
    // Register components with setup()
    setup(COMPONENTS);

    // Trigger component registration event
    (window as any).runtime?.componentsLoaded();

    // Send metadata to SDK if needed
    const sdkClient = (window as any).SA_WEB_SDK_CLIENT;
    if (sdkClient) {
      sdkClient.sendComponents(componentsMetadata);
    }
  },
  destroy: () => {
    // Cleanup if needed
  }
};

export default SUPERATOM;

Important: The mount function is required for React version isolation. It ensures your bundle's React instance is used to render components, preventing version conflicts with the host application.

Step 3: Build Your Bundle

Use your preferred bundler (Vite, Webpack, etc.) to create a UMD or IIFE bundle that exposes SUPERATOM globally.

Using Bundles in Your Application

Option 1: Load Bundle Script Dynamically

import { useEffect, useState } from 'react';
import { DSLRenderer } from '@superatomai/renderer-react';

function App() {
  const [bundleLoaded, setBundleLoaded] = useState(false);

  useEffect(() => {
    // Load bundle script
    const script = document.createElement('script');
    script.src = 'https://your-cdn.com/bundle.js';
    script.onload = () => {
      // Initialize bundle after package is ready
      if (window.SUPERATOM?.init) {
        window.SUPERATOM.init().then(() => {
          setBundleLoaded(true);
        });
      }
    };
    document.head.appendChild(script);
  }, []);

  return (
    <div>
      {bundleLoaded ? (
        <DSLRenderer
          dsl={{
            id: 'custom-chart',
            render: {
              id: 'chart-root',
              type: 'COMP_DynamicBarChart', // Your custom component
              props: {
                data: { $bind: 'chartData' }
              }
            }
          }}
          data={{ chartData: [...] }}
        />
      ) : (
        <div>Loading components...</div>
      )}
    </div>
  );
}

Option 2: Static Script Tag

<!DOCTYPE html>
<html>
<head>
  <!-- Load your bundle -->
  <script src="/path/to/bundle.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="module">
    import { createRoot } from 'react-dom/client';
    import App from './App';

    // Initialize bundle components
    window.SUPERATOM.init().then(() => {
      createRoot(document.getElementById('root')).render(<App />);
    });
  </script>
</body>
</html>

Important Considerations

⚠️ Loading Order: The npm package must be imported BEFORE calling window.SUPERATOM.init(), otherwise the event listener won't be set up yet.

Best Practice Pattern:

// 1. Import package (sets up event listeners)
import { DSLRenderer } from '@superatomai/renderer-react';

// 2. Load bundle script
// 3. Call SUPERATOM.init() after both are ready
// 4. Render components

Accessing Bundle Components in DSL

Once your bundle is loaded and initialized, components are automatically registered with the COMP_ prefix:

{
  "id": "my-ui",
  "render": {
    "id": "root",
    "type": "COMP_DynamicBarChart",
    "props": {
      "data": { "$bind": "salesData" },
      "config": {
        "title": "Sales by Region"
      }
    }
  }
}

Debugging Bundle Components

import { getComponentStates } from '@superatomai/renderer-react';

// Check component loading status
const states = getComponentStates();
console.log('Loaded components:', states.loaded);
console.log('Loading components:', states.loading);
console.log('Failed components:', states.failed);

// Access the registry directly (for debugging)
console.log('Available components:', window.COMP_REGISTRY);

React Version Isolation

Bundle components are automatically wrapped with BundleComponentWrapper to ensure React version isolation. This means:

  • Your bundle can use its own version of React
  • The wrapper ensures proper rendering in the host application's React tree
  • Each component has isolated error boundaries

JSON Schema Structure

UIComponent Schema

{
  id: string;              // Unique component ID
  name?: string;           // Component name
  props?: Record<string, any>;  // Component props
  states?: Record<string, any>; // Component state
  data?: Record<string, any>;   // Component data
  render: UIElement;       // Root UI element to render
}

UIElement Schema

{
  id: string;              // Unique element ID
  type: string;            // Element type (div, span, COMP_*)
  props?: Record<string, any>;  // Element props
  children?: UIElement[] | string;  // Child elements

  // Conditional rendering
  if?: { $exp: string };
  else?: UIElement;

  // Loop rendering
  for?: {
    in: { $bind: string } | { $exp: string };
    as: string;
    key?: string;
    index?: string;
  };

  // Data binding
  // Use { $bind: 'data.path' } for data binding
  // Use { $exp: 'expression' } for expressions
}

Example: Complete UI Schema

{
  "id": "sales-dashboard",
  "name": "SalesDashboard",
  "data": {
    "salesData": [
      { "region": "North", "sales": 1000 },
      { "region": "South", "sales": 1500 }
    ]
  },
  "render": {
    "id": "root",
    "type": "div",
    "props": {
      "style": { "padding": "20px" }
    },
    "children": [
      {
        "id": "title",
        "type": "h1",
        "children": "Sales Dashboard"
      },
      {
        "id": "chart",
        "type": "COMP_ECHART",
        "props": {
          "option": {
            "xAxis": {
              "type": "category",
              "data": { "$exp": "salesData.map(d => d.region)" }
            },
            "yAxis": { "type": "value" },
            "series": [{
              "type": "bar",
              "data": { "$exp": "salesData.map(d => d.sales)" }
            }]
          },
          "style": { "height": "400px" }
        }
      }
    ]
  }
}

Advanced Usage

Custom Event Handlers

<DSLRenderer
  dsl={schema}
  data={data}
  handlers={{
    onRowClick: (row) => {
      console.log('Row clicked:', row);
      // Handle row click
    },
    onFilterChange: (filters) => {
      console.log('Filters changed:', filters);
      // Update filters
    }
  }}
/>

Navigation Between UIs

<DSLRenderer
  dsl={schema}
  data={data}
  onNavigate={(uiid, params) => {
    console.log('Navigate to:', uiid, 'with params:', params);
    // Load new UI based on uiid
    loadUI(uiid, params);
  }}
/>

Error Handling

import { DSLErrorBoundary } from '@superatomai/renderer-react';

function App() {
  return (
    <DSLErrorBoundary>
      <DSLRenderer dsl={schema} data={data} />
    </DSLErrorBoundary>
  );
}

Component State Management

import { getComponentStates, resetFailedComponent } from '@superatomai/renderer-react';

// Check which components are loaded
const states = getComponentStates();
console.log('Loaded:', states.loaded);
console.log('Failed:', states.failed);

// Reset a failed component to retry loading
resetFailedComponent('echarts');

TypeScript Support

Full TypeScript support with type definitions:

import type {
  UIComponent,
  UIElement,
  DSLRendererProps
} from '@superatomai/renderer-react';

const schema: UIComponent = {
  id: 'my-component',
  render: {
    id: 'root',
    type: 'div',
    children: 'Hello World'
  }
};

Development

# Install dependencies
pnpm install

# Build the package
pnpm build

# Watch mode for development
pnpm dev

# Type checking
pnpm typecheck

License

MIT

Support

For issues and questions: