smart-industrial
v27.1.0
Published
Smart.Industrial: 54 UI components for browser HMI and SCADA applications, built as standards-based Custom Elements with no third-party dependencies. ISA-101 themes, ISA-18.2 alarms, SPC, DSP, PackML, model outputs (forecast bands, anomaly markers, heatma
Maintainers
Keywords
Readme
Smart.Industrial - Web Components for Browser HMI and SCADA
smart-industrial is a commercial UI component library of 54 standards-based custom elements
for HMI, SCADA and test and measurement applications: faceplates, alarm management, process
mimics, trends, instrument displays, statistical process control, machine state and 21 CFR Part 11
electronic signatures. It has no third-party dependencies and works in plain HTML or with Angular,
React, Vue and Blazor.
Live demos · Documentation · Product page · Pricing and licensing

Contents
- What is Smart.Industrial?
- Installation
- Quick start
- What is in the package
- Components
- Modules
- Themes
- Localization
- TypeScript
- Frameworks
- Standards
- Security
- Performance
- Relationship to Smart UI
- FAQ
- License
What is Smart.Industrial?
Smart.Industrial is a library of UI components for industrial applications, built as native custom elements on the Smart UI framework. It includes control loop faceplates, ISA-18.2 alarm summaries and banners, P&ID mimics, strip charts and historian trends, oscilloscope and spectrum displays, PackML and ISA-88 state machines, test sequence editors, pendant controls, anomaly heatmaps and root-cause trees for model outputs, and the electronic signature and audit trail components a regulated record needs.
The engineering calculations used by the components (FFT and window functions, Shewhart control limits and run rules, series reduction, unit conversion and a hash-chained audit log) are also available as plain functions that can be used without the components.
Installation
npm install smart-industrialThe package does not depend on smart-webcomponents and can be installed next to it. The two
packages register different elements and can be loaded on the same page.
Quick start
Load a theme, the Industrial elements stylesheet and the bundle, then use the elements:
<link rel="stylesheet"
href="node_modules/smart-industrial/source/styles/smart.default.css" />
<link rel="stylesheet"
href="node_modules/smart-industrial/source/styles/smart.industrial-elements.css" />
<script src="node_modules/smart-industrial/source/smart.industrial.js"></script>
<smart-faceplate tag="TIC-101" description="Reactor temperature" unit="°C"
process-value="72.4" setpoint="75" output="41.2" mode="auto"></smart-faceplate>Or load one component as a self-contained ES module, with the same two stylesheets:
<link rel="stylesheet"
href="node_modules/smart-industrial/source/styles/smart.default.css" />
<link rel="stylesheet"
href="node_modules/smart-industrial/source/styles/smart.industrial-elements.css" />
<script type="module"
src="node_modules/smart-industrial/source/modules/smart.alarmgrid.js"></script>
<smart-alarm-grid id="alarms"></smart-alarm-grid>Every file under source/modules/ is a self-contained ES module, so a page can load only the
components it uses without loading the bundle. A module carries the component's script, not its
styles: without the two stylesheets the components are unstyled and some grow to many thousands
of pixels.
What is in the package
| Path | What it is |
| --- | --- |
| source/smart.industrial.js | The whole line in one file: the framework, the base classes the elements extend, all 54 elements and every module below. |
| source/modules/smart.<name>.js | One self-contained ES module per component. |
| source/modules/smart.industrial.*.js | The Connect, AI, Audit and Units modules, and the SPC, DSP and decimation maths, as ES modules. |
| source/smart.industrial.locale.<lang>.js | Locale packs - German, French, Spanish and Chinese - as plain scripts, for a page that loads the bundle with a script tag. |
| source/modules/smart.industrial.locale.<lang>.js | The same packs as self-contained ES modules, for a bundler. |
| source/components/smart.ui.<name>.js | One component with its stylesheet, the theme and the line's tokens inlined, rendering in shadow DOM as <smart-ui-…> (smart.ui.stacklight.js defines <smart-ui-stack-light>): for a page that cannot load the stylesheets itself, or must not let them reach the rest of the page. |
| source/styles/smart.default.css | The base theme the line sits on: the variables, the base styles, and the suite components several Industrial components are built on (the Table under the alarm grid, the Tank under the knob). |
| source/styles/smart.industrial-elements.css | Styles for the 54 components. Load it after the theme. |
| source/styles/smart.industrial.css, smart.industrial-dark.css | The two ISA-101 themes. |
| source/styles/default/smart.<name>.css | Per-component stylesheets, for loading one at a time. |
| source/typescript/smart.industrial.d.ts | TypeScript definitions for the line, and one file per component beside it. |
| source/locales/<lang>/table.json | The Table messages the alarm grid inherits. |
| react/ | The React wrappers: smart-industrial/react/<name> for one component, smart-industrial/react for all 54. |
| angular/ | The Angular wrappers: smart-industrial/angular/<name> (<Name>Module) for one component, smart-industrial/angular (SmartIndustrialModule) for all 54. |
Import the wrappers per component. smart-industrial/react is one bundle of every component,
about 2.5 MB minified. Each Angular module carries its own copy of the framework, so
SmartIndustrialModule puts about 9 MB into the application's bundle.
Components
54 components ship in the package. Each name links to its documentation.
Alarms and status
Alarm Grid · Alarm Banner · Annunciator · Status Tile · Multi-State Indicator
Operator screens and process graphics
HMI Shell · Faceplate · Device Control · Mimic · Mimic Symbol · Pipe
Trends and signals
Trend · Strip Chart · Scope · Spectrum · Control Chart · Comparison Chart
Test and measurement
Waveform Graph · Intensity Graph · Digital Waveform · Bode Plot · Polar Plot · Octave Bands · Resource Picker
The displays of a test station and the front panel of a test-and-measurement application: the waveform and XY graph with cursors and stacked scales, the intensity graph and chart, the digital waveform with buses, the Bode plot with stability margins, the polar and orbit plot, the octave band analyser with A and C weighting, and the VISA and DAQ resource picker. The front panel guide maps each front panel control to a component.
Model outputs
Anomaly Heatmap · Root Cause Tree
The Trend component draws forecast bands and anomaly markers on the pen they belong to, the heatmap shows anomaly scores across a unit over time, and the tree shows a ranked root-cause analysis. The models that produce these outputs are part of the application.
Production floor
Stack Light · State Timeline · Downtime Log · Shift Log
Recipes, orders and scheduled jobs
Recipe Panel · Order Queue · Job Panel
Maintenance and sites
Safety and interlocks
Cause and Effect Matrix · Permissive
Instrument readouts and controls
Seven Segment · Bar Graph · Thermometer · Panel Meter · Knob · Bit Field · Numeric Keypad · Touch Keyboard · Momentary Button · Selector Switch · Jog Panel
Machine state, sequences and sessions
State Machine · Sequence Editor · Terminal
Electronic records (21 CFR Part 11)
E-Signature · Signature Block · Audit Trail
Modules
The bundle exposes the shared modules under Smart.Industrial and the maths under their own
namespaces. The functions do not use the DOM, so the maths, Units and Audit modules (and the
bundle) also load in a Worker and under Node.js:
// a classic Worker: the modules define the global Smart
importScripts('node_modules/smart-industrial/source/modules/smart.dsp.js');
const level = Smart.DSP.rms(samples);
// a module Worker, or a bundler: the import defines self.Smart
import 'smart-industrial/source/modules/smart.dsp.js';
// Node.js: require() returns Smart
const Smart = require('smart-industrial/source/modules/smart.dsp.js');
Smart.DSP.rms([3, 4, 3, 4]);| Namespace | What it does |
| --- | --- |
| Smart.Industrial.Connect | Tag subscriptions from a data source to elements, with rate limiting, quality propagation and unit scaling. Adapters for polling, WebSocket and simulated sources. |
| Smart.Industrial.Units | Unit systems and conversion: SI, US customary and a plant's own, applied to whole screens through Connect. |
| Smart.Industrial.Audit | A hash-chained audit log, signature records and verification, the record the E-Signature and Audit Trail elements produce and read. |
| Smart.Industrial.ai | Context reduction for an operator copilot: alarms, trends and state condensed to what a model needs. |
| Smart.Industrial.spc | X-bar/R, X-bar/S, I-MR and the attribute charts, Nelson and Western Electric rules, Cp/Cpk/Pp/Ppk. |
| Smart.DSP | FFT, windows with their gains, one-sided spectrum, Welch PSD, RMS, THD, peak finding. |
| Smart.Utilities.Decimate | Min/max, LTTB and step-preserving reduction for series longer than the screen. |
| Smart.Industrial.applyLocale() | Applies a loaded locale pack to every Industrial element under a root. |
Themes
Two ISA-101 themes ship beside the base theme. Load a theme, then the elements stylesheet:
<link rel="stylesheet" href="node_modules/smart-industrial/source/styles/smart.default.css" />
<link rel="stylesheet" href="node_modules/smart-industrial/source/styles/smart.industrial-elements.css" />
<link rel="stylesheet" href="node_modules/smart-industrial/source/styles/smart.industrial.css" />
<link rel="stylesheet" href="node_modules/smart-industrial/source/styles/smart.industrial-dark.css" />
<body theme="industrial-dark">smart.industrial.css is the light, grey-scale ISA-101 palette that reserves colour for
abnormal conditions; smart.industrial-dark.css is the same palette for a dark control room.
Switch between them with the theme attribute on <body>: industrial or industrial-dark.
The components also render under every other Smart UI theme, since they are built from the same
tokens.
Localization
English is built in. German, French, Spanish and Chinese are shipped as separate files. After the bundle, load a pack with a script tag:
<script src="node_modules/smart-industrial/source/smart.industrial.js"></script>
<script src="node_modules/smart-industrial/source/smart.industrial.locale.de.js"></script>
<script>
Smart.Industrial.applyLocale(document, 'de');
</script>With a bundler, import the pack's ES module instead:
import 'smart-industrial/source/modules/smart.industrial.locale.de.js';A locale pack translates the messages of the Industrial components. A few texts still stay in
English, or in the language a component was created in, after a switch at run time; the Languages
line of each component's documentation names them. Numbers, dates and units are formatted through
the platform's Intl in the current locale.
TypeScript
The TypeScript definitions are modules. Import a type from the union file or from the component's
own file, with import type: the definitions have no code to import, and a project with
verbatimModuleSyntax (the Vite default) rejects a plain import of a type.
import type { Trend } from 'smart-industrial/source/typescript/smart.industrial';
// or: import type { Trend } from 'smart-industrial/source/typescript/smart.trend';
const trend = document.querySelector('smart-trend') as Trend;
trend.pens = [{ field: 'temperature', label: 'Reactor temperature', unit: '°C', min: 0, max: 150 }];
trend.pushMany([{ timestamp: Date.now(), temperature: 72.4 }]);The modules that are not components are typed in smart.industrial.modules.d.ts, which the
union file includes: an import from either declares the global Smart with Smart.DSP,
Smart.Utilities.Decimate, Smart.Industrial.spc, Units, Audit, Connect and its adapters,
ai, the presets and applyLocale() typed. That file uses no DOM types, so a Worker or a Node.js
project can include it. The React and Angular wrappers type the detail of each event, for example
onSetpointChange receives a CustomEvent<{ value: number; tag: string }>.
Frameworks
The components are custom elements and can be used in any framework. Typed React and Angular wrappers are included in this package as separate entry points:
| Framework | Import |
| --- | --- |
| Angular | import { FaceplateModule } from 'smart-industrial/angular/faceplate'; The wrappers are NgModules: an NgModule application lists the module in its imports (Angular 13 and later), a standalone component lists it in its own imports (Angular 14 and later). |
| React | import { Faceplate } from 'smart-industrial/react/faceplate'; React 18 and later: the wrappers use react-dom/client. |
| Vue | No wrapper is needed: Vue's compiler passes smart-* tags through to the DOM. Import a module and the styles from smart-industrial/source/. |
| Blazor | Smart.Blazor.Industrial (NuGet), e.g. <Faceplate Tag="TIC-101" /> with @using Smart.Blazor.Industrial; in a Blazor Web App (.NET 8 and later) the page needs an interactive render mode such as @rendermode InteractiveServer, or the components render empty |
The faceplate raises its requests (setpointChange, outputChange, modeChange) only while
interactive is set, so the samples set it.
// Angular 14 and later: a standalone component imports the NgModule
import { Component } from '@angular/core';
import { FaceplateModule } from 'smart-industrial/angular/faceplate';
@Component({
selector: 'app-loop',
standalone: true,
imports: [FaceplateModule],
template: `<smart-faceplate tag="TIC-101" [processValue]="pv" [setpoint]="sp" [interactive]="true"
(onSetpointChange)="onSetpoint($event)"></smart-faceplate>`
})
export class LoopComponent {
pv = 72.4;
sp = 75;
onSetpoint(event: CustomEvent) {
// write event.detail.value to the plant, then set sp from the value the plant reports
console.log('requested', event.detail.value);
}
}// React 18 and later
import 'smart-industrial/source/styles/smart.default.css';
import 'smart-industrial/source/styles/smart.industrial-elements.css';
import { Faceplate } from 'smart-industrial/react/faceplate';
export function Loop() {
// write event.detail.value to the plant, then set setpoint from the value the plant reports
return <Faceplate tag="TIC-101" processValue={72.4} setpoint={75} interactive
onSetpointChange={(event: CustomEvent) => console.log('requested', event.detail.value)} />;
}Angular counts the stylesheets in its "initial" bundle budget: smart.default.css and
smart.industrial-elements.css are about 1.7 MB, above the 1 MB error budget a new Angular
project sets, so ng build stops until the budget in angular.json is raised.
Every component has the same demo in Angular, React and Vue as in plain HTML, linked from the component's documentation page.
Each wrapper imports its element from source/modules/ in this package, so nothing else has to
be installed. React and Angular are optional peer dependencies: a plain JavaScript project installs
the package without them. The Blazor components are in the Smart.Blazor.Industrial NuGet
package, which includes the runtime in its wwwroot and can be used with or without
Smart.Blazor.
Standards
The components support the following standards. The documentation includes a conformance statement for each one, listing what the components provide and what remains the responsibility of the application:
- ISA-101 - the two themes and the HMI shell follow its display hierarchy and use of colour.
- ISA-18.2 - the alarm grid, banner and annunciator implement the alarm states, including returned-to-normal-unacknowledged, and the §16 performance metrics.
- ISA-88 and PackML / ISA-TR88.00.02 - the state machine includes both models.
- 21 CFR Part 11 - the E-Signature, Signature Block and Audit Trail implement the client-side parts of §11.10, §11.50, §11.70, §11.200 and §11.300. The Part 11 statement lists clause by clause what the components provide and what the system has to provide.
- ISO 10816-3 and IEC 61850 - the vibration evaluation zones and the sequence-of-events timestamp resolution used by the screen templates.
- IEC 61511 / ISA-84 - the cause and effect matrix displays a safety system's chart, its live state and the discrepancies between the two. The logic, bypasses and trips remain in the safety system.
- IEC 62443 - the security statement maps each foundational requirement of IEC 62443-4-2 to what the library provides and what the application provides.
- WCAG 2.2 Level AA - a conformance report in VPAT form, measured rather than inspected, which also covers the web clauses of EN 301 549 and Section 508.
Security
The components are client-side UI code with no runtime dependencies. They make no network
requests of their own - the license key is checked on the device - and the data sessions the
application opens through Smart.Industrial.Connect
and the AI module when the application configures it are the only outbound connections. Every
value a component displays is rendered as text; a test in the suite sets every string property and
record field of every component to an HTML payload and fails if any of it is rendered as markup.
No inline scripts or eval are needed; under a Content Security Policy the components require
style-src 'unsafe-inline'.
The package ships SECURITY.md (how to report a vulnerability, supported versions) and
sbom.cdx.json (a CycloneDX bill of materials). The full
security statement lists the network and
storage behaviour, the Content Security Policy directives and the IEC 62443 mapping.
Performance
The charts that receive continuous data draw once per animation frame and reduce the records to one column per pixel before painting, so the rate of incoming data does not multiply the rate of rendering. Measured in headless Chrome on a laptop: the strip chart accepts 180,000 samples per second while drawing at 60 frames per second, the scope processes 1.8 million samples per second with the trigger running, the trend takes in 100,000 records and draws them, reduced to the width of the plot, in under 100 ms, and the terminal appends 25,000 lines per second with the view following. The performance page lists every figure and the machine it was measured on.
Relationship to Smart UI
Smart.Industrial is built on the Smart UI framework and shares its themes and CSS variables, but
it is a separate package with a separate license. smart-webcomponents does not contain the
Industrial components, and this package does not contain the Grid, the Scheduler or the rest of
the suite. An application that needs both installs both packages.
Browser support
Current versions of Chrome, Edge, Firefox and Safari, on desktop and on panel PCs and tablets.
The components are standard custom elements without polyfills, and the themes use CSS custom
properties. The default values of the Industrial CSS variables use color-mix() (Chrome 111,
Safari 16.2, Firefox 113 and later); older browsers fall back to the theme's text colour for
those variables.
FAQ
Which frameworks are supported? JavaScript and TypeScript, Angular 13+ (the wrappers are
NgModules; a standalone component imports the module, Angular 14+), React 18+, Vue 3.2.38+ (earlier
versions of Vue 3 do not deliver camelCase events such as setpointChange) and Blazor (.NET 6+). The Angular and React wrappers are in this package; Blazor is the
Smart.Blazor.Industrial NuGet package.
Does it connect to OPC UA, MQTT or Modbus? A browser cannot speak these protocols directly.
Smart.Industrial.Connect routes tags from a WebSocket, SSE or HTTP gateway, or from your own
client, into component properties, with quality and staleness. It includes payload mappers for
OPC UA and Sparkplug gateways.
Is it ISA-101 compliant? The two themes and the HMI shell follow ISA-101's use of colour and display hierarchy. A theme cannot conform on its own; the ISA-101 statement lists what the application still has to do.
Does it support 21 CFR Part 11? The E-Signature, Signature Block and Audit Trail components provide the client-side parts: the signing dialog, the manifestation, and a hash-chained, time-stamped audit trail. Identity verification, retention and the server-side copy are the system's; the Part 11 statement lists this clause by clause.
Does it phone home? No. The library makes no request of its own: the license key is checked on the device. See the security statement.
Can it be used offline or air-gapped? Yes. The components run without any connection, and the license key is checked on the device, so a station that never has Internet access runs licensed like any other.
Does it work on touch panels? Yes, with some care. A touch density (density="touch") makes
the HMI shell's targets at least 44 px, and the momentary button, numeric keypad, selector switch,
jog panel, e-signature and audit trail have a touch density of their own, set on each of them.
The touch keyboard and the numeric keypad are made for a touch panel. The other components keep
their desk size inside a touch shell.
How is it licensed? Per developer, perpetual and royalty free, separately from the Smart UI suite, with a free 30-day evaluation. Terms and pricing: htmlelements.com/license.
License
Smart.Industrial is commercial software, not open source. Installing it from npm or NuGet does
not license it: the terms are the Smart.Industrial EULA, EULA.pdf in the package (the same
text is in EULA.txt), and htmlelements.com/license
has the pricing. Without a license key the components run in evaluation mode and show a
watermark. The 30-day evaluation is free and includes technical support.
The EULA does not allow forking the components, republishing them under another name or on another registry, or building a competing component library or HMI/SCADA design tool from them. It also reserves text and data mining (Article 4(3) of Directive (EU) 2019/790): the package, its source, documentation and examples may not be used to train, fine-tune or index AI models. Using an AI coding assistant to build your own application with Smart.Industrial is allowed, as long as the assistant does not train on what you give it.
Applying your license key
Set the key once, before the first element renders. On a page that loads the bundle with a script
tag, set it before the script, or put it on <body>:
<script>window.Smart = { License: 'YOUR-KEY' };</script>
<script src="node_modules/smart-industrial/source/smart.industrial.js"></script><body smart-license="YOUR-KEY">window.Smart.License = 'YOUR-KEY' before the bundle has loaded throws, because window.Smart
does not exist yet. In an application built with a bundler (Angular, React, Vue), the imports run
first and create window.Smart, so set the property in the bootstrap file (main.ts,
index.tsx or main.js), after the imports and before the first component renders:
window.Smart.License = 'YOUR-KEY';In Blazor, set
Smart.Blazor.Industrial.License.Key = "YOUR-KEY"; in Program.cs. A single element can also
be given the key through its unlockKey property.
Support
Technical support is included with a license and with the evaluation: [email protected] or the forum. When reporting an issue, include the component, the framework, the package version and, if possible, a page that reproduces it. The demos, each with its source in HTML, Angular, React and Vue, are a good starting point.
