A production-ready React library for consuming real-time telemetry data through WebSocket connections. Built for SCADA systems, IoT dashboards, and industrial monitoring applications.
The library is published to npm and can be installed in any React project:
npm install scadableRequirements:
- React 18.0.0 or higher
- React DOM 18.0.0 or higher
The fastest way to visualize real-time data:
import { LiveTelemetryLineChart } from 'scadable';
function App() {
return (
<LiveTelemetryLineChart
apiKey="your-api-key"
deviceId="your-device-id"
title="Temperature Monitor"
xAxisLabel="Time"
yAxisLabel="Temperature (Β°C)"
xDataPath=".timestamp"
yDataPath=".data.temperature"
yMin={0}
yMax={50}
lineColor="#8884d8"
/>
);
}For custom implementations with full control:
import { Facility, Device, useLiveTelemetry } from 'scadable';
const facility = new Facility("your-api-key");
const device = new Device(facility, "your-device-id");
function App() {
const { telemetry, isConnected, error } = useLiveTelemetry(device);
return (
<div>
<h1>Status: {isConnected ? 'Connected' : 'Disconnected'}</h1>
{error && <p>Error: {error}</p>}
{telemetry && <pre>{JSON.stringify(telemetry, null, 2)}</pre>}
</div>
);
}- π Real-Time Visualization: Live line charts with smooth scrolling data
- π WebSocket Integration: Automatic connection management and reconnection
- βοΈ React Hooks: Simple
useLiveTelemetryhook for custom implementations - π‘οΈ TypeScript Support: Full type safety with comprehensive definitions
- π¨ Customizable Charts: Configurable colors, scales, and dimensions
- π§ͺ Production Ready: Comprehensive tests and error handling
- π± Framework Agnostic: Works with Next.js, Create React App, Vite, and more
Manages API authentication for WebSocket connections.
import { Facility } from 'scadable';
const facility = new Facility("your-api-key");Methods:
connect(deviceId: string): WebSocket- Creates a WebSocket connectionisValid(): boolean- Validates the API key
Manages device connections and message handling.
import { Facility, Device } from 'scadable';
const facility = new Facility("your-api-key");
const device = new Device(facility, "device-id");
// Connect to WebSocket
device.connect();
// Subscribe to messages
device.onMessage((data) => console.log(data));
// Handle errors
device.onError((error) => console.error(error));
// Monitor connection status
device.onStatusChange((status) => console.log(status));
// Disconnect when done
device.disconnect();Methods:
connect()- Establishes WebSocket connectiondisconnect()- Closes WebSocket connectiononMessage(handler)- Subscribe to telemetry messagesonError(handler)- Subscribe to connection errorsonStatusChange(handler)- Subscribe to connection status changesgetConnectionStatus()- Get current connection statusisConnected()- Check if currently connected
React hook for consuming real-time telemetry data with automatic lifecycle management.
import { useLiveTelemetry } from 'scadable';
const { telemetry, isConnected, error } = useLiveTelemetry(device);Returns:
telemetry- Latest telemetry data receivedisConnected- Connection status (boolean)error- Error message if connection fails
Ready-to-use real-time line chart component.
import { LiveTelemetryLineChart } from 'scadable';
<LiveTelemetryLineChart
apiKey="your-api-key" // API key for authentication
deviceId="your-device-id" // Device ID to connect to
title="Temperature Monitor" // Chart title
xAxisLabel="Time" // X-axis label
yAxisLabel="Temperature (Β°C)" // Y-axis label
xDataPath=".timestamp" // JSON path to X value
yDataPath=".data.temperature" // JSON path to Y value
yMin={0} // Minimum Y-axis value
yMax={50} // Maximum Y-axis value
lineColor="#8884d8" // Optional: line color
maxDataPoints={20} // Optional: max data points
width={600} // Optional: chart width
height={400} // Optional: chart height
/>- LiveTelemetryLineChart Documentation - Complete guide to the chart component
- useLiveTelemetry Hook Documentation - Advanced hook usage and patterns
- NPM Package: https://www.npmjs.com/package/scadable
- GitHub Repository: https://github.com/scadable/library-react
- Live Examples: Run
npm run storybooklocally to see interactive examples
'use client';
import { LiveTelemetryLineChart } from 'scadable';
export default function DashboardPage() {
return (
<LiveTelemetryLineChart
apiKey={process.env.NEXT_PUBLIC_SCADABLE_API_KEY}
deviceId="sensor-001"
title="Temperature Monitor"
xAxisLabel="Time"
yAxisLabel="Temperature (Β°C)"
xDataPath=".timestamp"
yDataPath=".data.temperature"
yMin={0}
yMax={50}
/>
);
}import { LiveTelemetryLineChart } from 'scadable';
function App() {
return (
<div className="App">
<LiveTelemetryLineChart
apiKey={process.env.REACT_APP_SCADABLE_API_KEY}
deviceId="sensor-001"
title="Temperature Monitor"
xAxisLabel="Time"
yAxisLabel="Temperature (Β°C)"
xDataPath=".timestamp"
yDataPath=".data.temperature"
yMin={0}
yMax={50}
/>
</div>
);
}import { LiveTelemetryLineChart } from 'scadable';
function App() {
return (
<LiveTelemetryLineChart
apiKey={import.meta.env.VITE_SCADABLE_API_KEY}
deviceId="sensor-001"
title="Temperature Monitor"
xAxisLabel="Time"
yAxisLabel="Temperature (Β°C)"
xDataPath=".timestamp"
yDataPath=".data.temperature"
yMin={0}
yMax={50}
/>
);
}function Dashboard() {
return (
<div>
<LiveTelemetryLineChart
apiKey="your-api-key"
deviceId="temp-sensor-1"
title="Temperature Sensor 1"
xAxisLabel="Time"
yAxisLabel="Β°C"
xDataPath=".timestamp"
yDataPath=".data.temperature"
yMin={0}
yMax={50}
lineColor="#ef4444"
/>
<LiveTelemetryLineChart
apiKey="your-api-key"
deviceId="pressure-sensor-1"
title="Pressure Sensor 1"
xAxisLabel="Time"
yAxisLabel="PSI"
xDataPath=".timestamp"
yDataPath=".data.pressure"
yMin={0}
yMax={150}
lineColor="#22c55e"
/>
</div>
);
}function CustomTelemetryDisplay() {
const facility = new Facility("your-api-key");
const device = new Device(facility, "your-device-id");
const { telemetry, isConnected, error } = useLiveTelemetry(device);
return (
<div className="custom-display">
<div className="status-bar">
<span className={isConnected ? 'connected' : 'disconnected'}>
{isConnected ? 'π’ Live' : 'π΄ Offline'}
</span>
</div>
{error && <div className="error">{error}</div>}
{telemetry && (
<div className="telemetry-data">
<h2>Temperature: {telemetry.data?.temperature}Β°C</h2>
<p>Last Updated: {telemetry.timestamp}</p>
</div>
)}
</div>
);
}If you're experiencing connection problems:
- Verify API Key: Ensure your API key is valid
- Check Device ID: Confirm the device ID exists in your system
- Network: Verify WebSocket connections aren't blocked by firewall
- Browser Console: Check for error messages in the developer console
- Verify JSON Paths: Ensure
xDataPathandyDataPathmatch your data structure - Check Y-axis Range: Make sure
yMinandyMaxencompass your data values - Inspect WebSocket Messages: Use browser DevTools to inspect WebSocket traffic
Ensure you have the latest type definitions:
npm install --save-dev @types/react @types/react-dom- Node.js: v20 or higher
- npm: v8 or higher
- Git: Latest version
-
Clone the repository:
git clone https://github.com/scadable/library-react.git cd library-react -
Install dependencies:
npm install
-
Run Storybook (interactive development environment):
npm run storybook
This opens at
http://localhost:6006with live component examples. -
Run tests:
npm run test # Watch mode npm run test:stories:ci # CI mode
-
Build the library:
npm run build
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User's React Application β
β (Next.js / Create React App / Vite) β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β npm install scadable
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Scadable React Library β
β β
β ββββββββββββββββ ββββββββββββββ ββββββββββββββββββ β
β β Components β β Hooks β β Core Classes β β
β β β β β β β β
β β β’ LiveChart β β β’ useLive β β β’ Facility β β
β β β β Telemetryβ β β’ Device β β
β ββββββββ¬ββββββββ βββββββ¬βββββββ ββββββββββ¬ββββββββ β
β β β β β
β ββββββββββββββββββ΄ββββββββββββββββββββ β
β β β
β ββββββββββΌββββββββββ β
β β WebSocket β β
β β Connection β β
β ββββββββββ¬ββββββββββ β
ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ
β wss://
βΌ
ββββββββββββββββββββββββ
β Scadable Backend β
β WebSocket Server β
ββββββββββββββββββββββββ
library-react/
βββ src/
β βββ core/ # Core business logic
β β βββ Facility.ts # API key & authentication
β β βββ Device.ts # WebSocket connection management
β β βββ types.ts # TypeScript definitions
β β
β βββ hooks/ # React hooks
β β βββ useLiveTelemetry.ts # Main telemetry hook
β β
β βββ components/ # React components
β β βββ LiveTelemetryLineChart.tsx
β β βββ LiveTelemetryLineChart.stories.tsx
β β βββ TelemetryDisplay.tsx
β β
β βββ utils/ # Utilities
β β βββ jsonPath.ts # JSON path extraction
β β βββ parseMessage.ts # Message parsing
β β
β βββ index.ts # Public API exports
β
βββ __tests__/ # Test files
βββ docs/ # Component documentation
βββ .storybook/ # Storybook config
βββ .github/workflows/ # CI/CD pipelines
βββ dist/ # Build output (generated)
βββ package.json
βββ vite.config.ts # Build configuration
βββ tsconfig.json # TypeScript config
LiveTelemetryLineChart
β
useLiveTelemetry Hook
β
Device Class (WebSocket management)
β
Facility Class (Authentication)
β
WebSocket Connection
β
Backend Server
1. User creates component with apiKey + deviceId
β
2. Facility validates API key
β
3. Device establishes WebSocket connection
β
4. useLiveTelemetry hook:
β’ Connects on mount
β’ Subscribes to messages
β’ Updates React state
β’ Cleans up on unmount
β
5. Backend sends WebSocket message
β
6. parseMessage() validates JSON
β
7. Hook updates state β Component re-renders
β
8. jsonPath extracts X/Y values β Chart renders
| Technology | Version | Purpose |
|---|---|---|
| React | ^19.1.1 | UI framework (peer dependency) |
| TypeScript | Latest | Type safety |
| Vite | ^6.3.6 | Build tool and bundler |
| Vitest | ^3.2.4 | Testing framework |
| Recharts | ^3.3.0 | Chart visualization |
| Tool | Purpose |
|---|---|
| Storybook | Interactive component development |
| ESLint | Code linting |
| Testing Library | React testing utilities |
| vite-plugin-dts | TypeScript declarations |
The library builds to three formats:
- CommonJS:
dist/index.js(older bundlers) - ES Modules:
dist/index.mjs(modern bundlers) - TypeScript:
dist/index.d.ts(type definitions)
# Unit tests (watch mode)
npm run test
# Storybook interaction tests
npm run test:stories
# CI mode (all tests)
npm run test:stories:ciTests cover:
- Component rendering
- WebSocket lifecycle (connect, disconnect, reconnect)
- Error handling
- Data parsing and extraction
- Hook behavior
npm run buildOutput in dist/ directory:
index.js(CommonJS)index.mjs(ES Modules)index.d.ts(TypeScript types)
npm version patch # Bug fixes (1.0.0 β 1.0.1)
npm version minor # New features (1.0.0 β 1.1.0)
npm version major # Breaking changes (1.0.0 β 2.0.0)Automated via GitHub Actions:
-
Create a GitHub Release:
- Tag:
v1.0.11(match package.json version) - Title: Same as tag
- Description: Release notes
- Tag:
-
GitHub Actions automatically:
- Runs tests
- Builds package
- Publishes to npm
-
Verify:
npm view scadable version
Runs on every push and pull request:
Steps:
1. Checkout code
2. Setup Node.js 20
3. Install dependencies (npm ci)
4. Lint code
5. Run tests
6. Build packageRuns when GitHub release is created:
Steps:
1. Checkout code
2. Setup Node.js with npm registry
3. Install dependencies
4. Build package
5. Publish to npm (with provenance)NPM_TOKEN: npm authentication token with publish permissions
Create GitHub Release
β
Trigger GitHub Actions
β
Run CI checks (lint, test, build)
β
Build succeeds?
β β
Yes No
β β
Publish Fail
β
npm updated
- NPM: https://www.npmjs.com/package/scadable
- Install:
npm install scadable
- GitHub: https://github.com/scadable/library-react
- Issues: GitHub Issues
- Storybook: Run
npm run storybooklocally
- Package Registry: npm (public)
- CI/CD: GitHub Actions
- Version Control: GitHub
- Fork the repository
- Clone your fork locally
- Create a feature branch:
git checkout -b feature/my-feature
- Make changes with clear commits:
git commit -m "feat: add new feature" - Test your changes:
npm run test npm run build - Push and create a pull request
Follow conventional commits:
feat:New featurefix:Bug fixdocs:Documentationtest:Testschore:Maintenancerefactor:Code refactoring
- Automated CI checks must pass
- At least one maintainer review
- Address feedback
- Merge when approved
rm -rf node_modules package-lock.json
npm install
npm run storybooknpx tsc --noEmit # Check TypeScript errors
rm -rf dist
npm run buildnpm run test -- --reporter=verboseISC License - See LICENSE file for details
- Issues: GitHub Issues
- Questions: Open a discussion on GitHub