Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Complete code example for blogpost "Using JSX for your own lightweight declarative library":
// Using an IIFE to hide some implementation details.
// If you use a bundler this should be it's own file.
const createElement = (function() {
const isEvent = (k, v) => k.startsWith("on") && typeof v === "function";
const eventName = k => k.substr(2).toLowerCase();
const isString = s => typeof s === "string";
const isFunction = s => typeof s === "function";
function attrs(el, props) {
// Remember, JSX sets props to `null` if nothing is defined, so in that case we just return el
if (!props) {
return el;
// For every passed prop, we get key and value
for (let [k, val] of Object.entries(props)) {
// Check if it starts with `on`. Then we assume it is an event and add an event listener.
if (isEvent(k)) {
el.addEventListener(eventName(k), val);
// If the key is class, we use classList to add one or many CSS classes
else if (k === "class") {
const classes = Array.isArray(val) ? val : [val];
// Of finally, if not class nor event, we set attribute using the setAttribute function.
else {
el.setAttribute(k, val);
return el;
return function createElement(tag, props, ...children) {
if (isFunction(tag)) {
return tag({ ...props, children });
const el = attrs(document.createElement(tag), props);
children.flat().forEach(child => {
const node = !isString(child) ? child : document.createTextNode(child);
return el;
function Header({ id, children }) {
return <h1 id={id}>Title: {children}</h1>;
const list = (
<Header id="myHeader">My important title</Header>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment