
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
It is a micro vanilla Javascript project of 1.4kB to help to write reactive UI based on event-driven programming.
This project was made to handle arrays and calculate the diff on the data, as demonstrated in the "JS-framework" bench test and the todoMVC. The performance is very close to the dedicated Javascript code written for this test. It uses event-driven programming: you write to the state and this triggers events with callbacks.
It uses an immutable state and computes the diff to render the desired DOM elements.
You write HTML as strings with normal interpolation.
It uses state variables. They have the following properties:
.val which is a setter and a getter,.target which sets the DOM element which will receive the event triggered by a state change,.resp which sets the desired rendering.Instead of writing "event" listeners in your HTML (where "event" can be "click" or "submit" or "change" or "input"), you write a dataset and reference a function. For example, data-change="compute".
It uses the key "stateVariable".resp to set the rendered DOM elements.
It relies on unique keys; you need to use the key attribute in the HTML to identify each element of the rendered DOM array. You need to pass to the state variable the unique identifier you use in your data (eg key: "id"). Both "key" are different.
Limitations: it is not fully reactive in the sense that you need to create a separate state variable for computed state. For example, you have a list of todos, completed or not. Suppose you have a counter on the total completed todos as a state variable. In the action where you change the completion of a todo, you need to modify of the counter state accordingly for the counter to be reactive. The "todoMVC" demonstrates this.
You get state and Actions from the package. You instantiate your state and action functions.
import B from "binyjs"
const todos = B.state({val: [], key: "id"})
const actions = B.Actions({remove: ()=> ...})
We want to render this HTML string:
app.innerHTML = `<div>
<h1>Hello biny</h1>
<div>
<button id="counter" type="button" data-click="inc">
^^^
<span data-change="display" id="count"></span>
^^^
</button>
</div>
</div>
`;
We build the state variable "counter", pass the actions into the "Actions" function and set up the target for this state variable. We render an HTML string when we pass it to the .resp key of the state variable.
const counter = B.state({ val: 0 }),
actions = B.Actions({
inc: () => (counter.val += 1),
display: () => {
// this action targets the "#count" element
counter.target = count;
^^^
counter.resp = `<span>binyJS state: ${counter.val}</span>`;
^^^
},
});
// display the initial state on load.
window.onload = () => actions.display();
The state is required to be immutable. The main ingredients are:
[{id: 1, label: "..."},...], then data.val is a setter and getter. When your data is an array, set the unique identifier used by your data to the key "key".const todoState = B.state({val: [], key: "id"})
data.val = ...
B.Actions. You need to set the target to the state variable used in the action.const actions = B.Actions({
removeLi: ()=> {
// the action targets the element "#ulis"
todoState.target = ulis;
...
},
...
})
key in the HTML string when you render a collection: you need to declare key="${id}" if your data uses "id" as unique identifier. Note that the "is important for the querySelectors. Use it in your selectors.const TodoItem = ({ id, label }) =>
`<li key="${id}">
^^ ^ ^
<span style="display:flex;">
<label style="margin-right:10px;">${label}</label>
<input type="checkbox"/>
</span>
</li>`;
[data-event] Biny uses the convention data-event for an "event" listener. This means you use data-click="addItem" when the element emits a click event that should run the "addITem" action declared in your "Actions".
You can use global listeners (element.addEventListener).
[target] Inside your listener, you must declare the target for each reactive state variable. It looks like data.target=tbody. You can also declare extra dependencies via a dataset if your component requires to read data hardcoded in the DOM and read them.
[state.resp] You need to return the data, normally HTML strings in the key ".resp".
[data-change] is the default callback. For example, you have a form with a data-submit:
<form id="fm" data-submit="addItem"></form>
This triggers the action below:
addItem: (e) => {
e.preventDefault();
todoState.target = ulis;
todoState.val = [...todoState.val, { id: ++i, label: inputState.val }];
fm.reset(), (inputState.val = "");
},
Since we send a new state, we want to render this new state. The target element "#ulis" contains a data-change="display":
<ul id="ulis" data-change="display"></ul>
Biny will run the callback "display":
display: () => {
todoState.target = ulis;
todoState.resp = todoState.val.map((todo) => TodoItem(todo));
},
We use the simple event loop and a "diffing function" to detect the 6 following changes made to the state: "assign", "append", "clear", "remove", "update" and "swap" (rows).
The performance is close to the Vanilla JS code specific for this test to which we compare the Biny package.
The code for the examples:
the famous counter: https://github.com/ndrean/binyJS/blob/main/examples/button.js
a Select and Datalist: https://github.com/ndrean/binyJS/blob/main/examples/select.js
a basic "todo" list: https://github.com/ndrean/binyJS/blob/main/examples/todo.js
the famous TODOMVC: https://github.com/ndrean/binyJS/blob/main/examples/todoMVC/todoMVC.js
the bench JS-framework test: https://github.com/ndrean/binyJS/blob/main/examples/jsbench/bench.js.
FAQs
yet another reactive components library
The npm package binyjs receives a total of 3 weekly downloads. As such, binyjs popularity was classified as not popular.
We found that binyjs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.