
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.
A lightweight JavaScript DOM builder library that provides a functional approach to creating and manipulating DOM elements. Zero dependencies, modern ES6+ support, and comprehensive DOM/SVG element creation.
npm install --save jdom
import {domFactory, svgFactory, on, once, off, dispatch, style, $} from 'jdom';
const {
domFactory,
svgFactory,
on,
once,
off,
dispatch,
style,
$,
} = require('jdom');
<script src="https://unpkg.com/jdom@3.2.5/dist/jdom.js"></script>
<script>
const {domFactory, svgFactory} = window.jdom;
</script>
const {DIV, SPAN, BUTTON, INPUT} = domFactory;
// Simple element
const myDiv = DIV({
parent: document.body,
id: 'myDiv',
className: 'container',
textContent: 'Hello World!',
});
// Element with styles and events
const button = BUTTON({
parent: myDiv,
textContent: 'Click me!',
style: {
backgroundColor: '#007bff',
color: 'white',
padding: '10px 20px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
},
click: () => alert('Button clicked!'),
mouseover: e => (e.target.style.backgroundColor = '#0056b3'),
});
// Complex nested structure
const form = DIV({
parent: document.body,
className: 'form-container',
children: [
DIV({
className: 'form-group',
children: [
'Name: ',
INPUT({
type: 'text',
placeholder: 'Enter your name',
dataset: {field: 'name'},
}),
],
}),
BUTTON({
textContent: 'Submit',
type: 'submit',
}),
],
});
const {svg, rect, circle, path, text} = svgFactory;
// Simple SVG with shapes
const mySVG = svg({
parent: document.body,
id: 'mySVG',
width: 300,
height: 200,
viewBox: '0 0 300 200',
style: {border: '1px solid #ccc'},
children: [
// Background rectangle
rect({
fill: '#f0f8ff',
x: 0,
y: 0,
width: 300,
height: 200,
}),
// Colored circle
circle({
fill: '#ff6b6b',
stroke: '#333',
strokeWidth: 2,
cx: 100,
cy: 100,
r: 50,
}),
// Text label
text({
x: 100,
y: 180,
textAnchor: 'middle',
fill: '#333',
fontSize: '16px',
textContent: 'Interactive SVG',
}),
],
});
// Interactive SVG elements
circle({
parent: mySVG,
fill: '#4ecdc4',
cx: 200,
cy: 100,
r: 30,
style: {cursor: 'pointer'},
click: function() {
this.setAttribute('fill', '#ff9f43');
},
});
domFactoryObject containing all HTML element creators (DIV, SPAN, INPUT, etc.)
const {DIV, SPAN, INPUT, BUTTON} = domFactory;
svgFactoryObject containing all SVG element creators (svg, circle, rect, path, etc.)
const {svg, circle, rect, path, text} = svgFactory;
createElement(tag, props, ...children)Low-level element creation function
const div = createElement('div', {id: 'test'}, 'Hello World');
style(element, styles)Apply CSS styles to an element
const element = document.getElementById('myDiv');
style(element, {
color: 'green',
backgroundColor: 'lightblue',
padding: '10px',
borderRadius: '4px',
});
Inputs(inputConfigs)Create a form container with multiple input fields
const formContainer = Inputs([
{
type: 'text',
name: 'username',
placeholder: 'Enter username',
description: 'Username',
required: true,
},
{
type: 'email',
name: 'email',
placeholder: 'Enter email',
description: 'Email Address',
},
{
type: 'select',
name: 'country',
description: 'Country',
options: [
{value: 'us', text: 'United States'},
{value: 'uk', text: 'United Kingdom'},
{value: 'ca', text: 'Canada'},
],
},
{
type: 'checkbox',
name: 'newsletter',
description: 'Subscribe to newsletter',
},
]);
document.body.appendChild(formContainer);
ButtonGroup(buttonConfigs)Create a group of buttons
const buttonGroup = ButtonGroup([
{
text: 'Save',
type: 'submit',
onClick: () => console.log('Save clicked'),
},
{
text: 'Cancel',
type: 'button',
onClick: () => console.log('Cancel clicked'),
},
{
text: 'Reset',
type: 'reset',
},
]);
document.body.appendChild(buttonGroup);
// Check element types
if (isElement(myDiv)) {
console.log('It is a DOM element');
}
if (isObject(myConfig)) {
console.log('It is a plain object');
}
if (isArray(myList)) {
console.log('It is an array');
}
// Get type of any value
console.log(type(myVariable)); // 'String', 'Number', 'Object', etc.
const element = document.getElementById('myElement');
// Check for class
if (hasClass(element, 'active')) {
console.log('Element has active class');
}
// Add class
addClass(element, 'highlight');
// Remove class
removeClass(element, 'old-style');
// Create elements from HTML strings
const element = createElement('<div>Hello World</div>');
const complexElement = createElement(`
<div class="card">
<h2>Title</h2>
<p>Content</p>
</div>
`);
// Get the currently executing script tag
const currentScript = currentScript();
console.log('Current script src:', currentScript.src);
on(element, event, handler, options)Add event listener to element
const button = BUTTON({textContent: 'Click me'});
on(button, 'click', () => console.log('Clicked!'));
once(element, event, handler, options)Add event listener that only fires once
once(button, 'click', () => console.log('First click only'));
off(element, event, handler, options)Remove event listener
off(button, 'click', myHandler);
dispatch(element, event)Trigger an event on element
dispatch(button, 'click');
$(selector)The $ function provides a jQuery-like interface for element selection and manipulation.
// Select elements
const $divs = $('div');
const $byId = $('#myId');
const $byClass = $('.myClass');
// Chainable operations
$('#myButton')
.addClass('active')
.style({color: 'red'})
.on('click', () => console.log('Clicked!'));
// Conditional class management
const $element = $('#myElement');
if ($element.hasClass('foo')) {
$element.removeClass('foo').addClass('bar');
} else {
$element.removeClass('bar').addClass('foo');
}
// Trigger events
$element.dispatch('click');
Event Methods:
on(event, handler) - Add event listeneronce(event, handler) - Add one-time event listeneroff(event, handler) - Remove event listenerdispatch(event) - Trigger eventStyle Methods:
style(styles) - Apply CSS styleshasClass(className) - Check if class existsaddClass(className) - Add CSS classremoveClass(className) - Remove CSS classArray Methods:
filter(), forEach(), map(), pop(), push()shift(), slice(), some(), splice(), unshift()When creating elements, you can specify various properties:
const element = DIV({
// Basic attributes
id: 'myId',
className: 'my-class',
textContent: 'Hello World',
// Styles
style: {
color: 'blue',
fontSize: '16px',
padding: '10px',
},
// Data attributes
dataset: {
userId: '123',
action: 'save',
},
// Event handlers (any DOM event)
click: () => console.log('Clicked'),
mouseover: e => console.log('Mouse over'),
// Parent element (auto-append)
parent: document.body,
// Child elements/text
children: ['Some text', SPAN({textContent: 'Nested element'}), 'More text'],
});
// Create custom element factory
const MyComponent = props =>
DIV({
className: 'my-component',
style: {
padding: '20px',
border: '1px solid #ccc',
borderRadius: '4px',
},
children: [
DIV({className: 'header', textContent: props.title}),
DIV({className: 'content', children: props.children}),
],
});
// Use custom component
const widget = MyComponent({
title: 'My Widget',
children: ['Some content here'],
});
const {svg, circle, animate} = svgFactory;
const animatedSVG = svg({
width: 200,
height: 200,
children: [
circle({
cx: 100,
cy: 100,
r: 50,
fill: 'blue',
children: [
animate({
attributeName: 'r',
values: '50;80;50',
dur: '2s',
repeatCount: 'indefinite',
}),
],
}),
],
});
# Install dependencies
npm install
# Start development server (with live demo)
npm start
# Build for production
npm run build
# Run tests
npm test
# Format code
npm run prettier
The development server includes a comprehensive test page with examples of all JDOM.js features.
FAQs
lightweight dom builder
We found that jdom demonstrated a healthy version release cadence and project activity because the last version was released less than 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.