@bonsae/nrg

NRG framework — build Node-RED nodes with Vue 3, TypeScript, and JSON Schema
14,272
Install
npm install @bonsae/nrg
Latest Version:0.43.0
Vue:3
License:MIT
Last Updated:Jul 25, 2026
Links: npm
Maintainer: allanoricil

nrg-icon

npm package build status codecov Socket Badge

[!WARNING] While NRG is at v0, breaking changes can land in any release and will not bump the major version. Pin an exact version and review the release notes before upgrading.

NRG

Build Node-RED nodes with Vue 3, TypeScript, JSON Schemas, Vite and Vitest.

Quick Start

Scaffold a new project with everything wired up:

pnpm create @bonsae/nrg

A node is a class (the logic) and a config schema (drives the editor form + validation). Here's a small greeting node — one typed input, one output, and a few config fields:

src/server/nodes/greeting.ts

import { IONode, type Infer, type Input, type Outputs, type Port } from "@bonsae/nrg/server";
import { ConfigsSchema } from "@/schemas/greeting";

type Config = Infer<typeof ConfigsSchema>;
type GreetingInput = Input<Port<{ name: string }>>;
type GreetingOutputs = Outputs<{ greeting: Port<{ text: string }> }>;

export default class Greeting extends IONode<Config, never, GreetingInput, GreetingOutputs> {
  static override readonly type = "greeting";
  static override readonly configSchema = ConfigsSchema;

  override async input(msg: GreetingInput) {
    const { greeting, style, repeat } = this.config;
    const suffix = style === "excited" ? "!" : style === "friendly" ? " :)" : "";
    const text = Array.from({ length: repeat }, () => `${greeting}, ${msg.name}${suffix}`).join(" ");
    this.send("greeting", { text });
  }
}

The class is pure typed logic — config, the input msg, and the send payload are all statically typed. Those config types are inferred from a schema, and that same schema is the single source of truth for the fields' defaults, validation, and the editor form:

src/shared/schemas/greeting.ts

import { SchemaType, defineSchema } from "@bonsae/nrg/schema";

export const ConfigsSchema = defineSchema(
  {
    greeting: SchemaType.String({ default: "Hello", description: "The greeting word placed before the name.", "x-nrg-form": { icon: "comment" } }),
    style: SchemaType.Union(
      [SchemaType.Literal("plain"), SchemaType.Literal("excited"), SchemaType.Literal("friendly")],
      { default: "plain", description: "Tone of the greeting.", "x-nrg-form": { icon: "paint-brush" } },
    ),
    repeat: SchemaType.Number({ default: 1, description: "How many times to repeat the greeting.", "x-nrg-form": { icon: "repeat" } }),
    note: SchemaType.Optional(
      SchemaType.String({ default: "", description: "Optional note shown under the node.", "x-nrg-form": { icon: "pencil" } }),
    ),
  },
  { $id: "GreetingConfigsSchema" },
);

You wrote no editor HTML, no jQuery, no oneditprepare — nrg generates the entire edit dialog from the schema and types above: the style union becomes a dropdown, strings and numbers become validated inputs, every non-Optional field is marked required with a * (so greeting, style, and repeat get one; note, wrapped in Optional, doesn't), and the input/output ports and lifecycle wiring come for free.

The greeting node's editor form, generated by nrg from the schema

A classic Node-RED node hand-writes hundreds of lines of HTML for its edit form and keeps it in sync with the runtime by hand. Here it's derived from your schema and types — so it can't drift, and every field is validated for free.

See the documentation for the full walkthrough — schemas, the generated editor form, testing, and building — or the node-red-salesforce repo for a real-world reference.

License

MIT

Related Packages

@bonsae/nrg-runtime

The runtime for Node-RED nodes built with @bonsae/nrg — node base classes, schem...

6,679
@livx.cc/frame

External infrastructure for Vue.js applications

2,500
homie-dashboard

IoT dashboard for Homie devices

970 14
resuxjs

Experimental resumable web framework with Vue-like SFC routing and a custom SSR/...

9,858 0
vue-json-ui-editor

A Vue 3 JSON Schema based form editor component with TypeScript support

9,776 527

Version History

Version Released Vue License
0.43.0 ^3.5.14 MIT
0.42.1 ^3.5.14 MIT
0.42.0 ^3.5.14 MIT
0.41.1 ^3.5.14 MIT
0.41.0 ^3.5.14 MIT