npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@obinexusltd/obix-jsx-adapter

v0.1.0

Published

Core JSX factory and runtime for OBIX components — zero dependencies, zero overhead

Readme

@obinexusltd/obix-jsx-adapter

JSX Hyperscript Factory for OBIX Components

NPM Version License: MIT TypeScript


What Is This?

@obinexusltd/obix-jsx-adapter is the JSX compilation target for OBIX. It provides:

  1. h() hyperscript factory — Converts JSX to OBIX component objects
  2. Fragment symbol — Groups components without a wrapper
  3. Type helpersComponentPropsOf, ComponentStateOf, etc.
  4. Zero dependencies — Just JSX compilation, nothing else

The Bridge

JSX Input (React Spec)
    ↓ (TypeScript Compiler)
h() Function Calls
    ↓ (@obinexusltd/obix-jsx-adapter)
OBIX Data Objects
    ↓ (@obinexusltd/obix-jsx-components)
HTML/CSS/JS Output

Installation

npm install @obinexusltd/obix-jsx-adapter

Quick Start

Configure TypeScript

{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "h",
    "jsxFragmentFactory": "Fragment"
  }
}

Use It

/** @jsx h */
/** @jsxFrag Fragment */

import { h, Fragment } from '@obinexusltd/obix-jsx-adapter';
import { obixButton, obixInput } from '@obinexusltd/obix-jsx-components';

// JSX syntax (what you write)
const button = <obix-button label="Save" />;

// ↓ (Compiler converts to)

// Function calls (what's executed)
const button = h(obixButton, { label: "Save" });

// Result: Pure OBIX data object
// {
//   name: 'Button',
//   state: { label: 'Save', ... },
//   actions: { ... },
//   render: (state) => '<button>Save</button>',
//   aria: { ... }
// }

API

h(component, props, ...children)

Hyperscript factory that converts JSX elements to OBIX components.

function h<T extends ComponentFactory>(
  component: T | typeof Fragment,
  props: PropsFor<T> | null,
  ...children: (ObixComponent | string | null | undefined)[]
): ObixComponent | ObixComponent[]

Parameters:

  • component — Factory function or Fragment symbol
  • props — Component configuration object (null for defaults)
  • children — Child components or text (optional, spread)

Returns:

  • Single ObixComponent if component is a factory
  • Array of ObixComponent[] if component is Fragment

Examples:

// Simple button
const btn = h(obixButton, { label: 'Save' });

// Button with children (form items)
const form = h(obixForm, { label: 'Login' },
  h(obixInput, { name: 'email' }),
  h(obixInput, { name: 'password' }),
  h(obixButton, { label: 'Sign In' })
);

// Fragment (no wrapper)
const fragment = h(Fragment, null,
  h(obixInput, { label: 'First' }),
  h(obixInput, { label: 'Last' })
);

Fragment

Symbol for grouping components without a wrapper element.

export const Fragment = Symbol.for('ObixFragment');

// Usage
const group = h(Fragment, null,
  h(obixButton, { label: 'Button 1' }),
  h(obixButton, { label: 'Button 2' })
);
// Returns: [button1, button2] (array, not wrapped)

Type Helpers

Extract types from component factories.

// Get props type
type ButtonProps = ComponentPropsOf<typeof obixButton>;

// Get state type
type ButtonState = ComponentStateOf<typeof obixButton>;

// Get actions type
type ButtonActions = ComponentActionsOf<typeof obixButton>;

Interface: ObixComponent<S, A>

Every component created by h() returns this shape:

interface ObixComponent<S = unknown, A = unknown> {
  // Data
  name: string;                      // 'Button', 'Input', 'Form', etc.
  state: S;                          // Current component state
  actions: A;                        // State-modifying functions
  aria?: Record<string, any>;        // ARIA attributes metadata
  children?: ObixComponent[];        // Child components
  
  // Methods
  render: (state: S) => string;      // Render state to HTML
  lifecycle?: 'CREATED' | 'UPDATED' | 'HALTED' | 'DESTROYED';
  revisions?: S[];                   // State history (optional)
  halt?: () => void;                 // Pause component (optional)
  resume?: () => void;               // Resume component (optional)
  destroy?: () => void;              // Cleanup (optional)
  undo?: () => void;                 // Undo last state (optional)
}

JSX Pragma Comment

For per-file JSX configuration:

/** @jsxRuntime classic */
/** @jsx h */
/** @jsxFrag Fragment */

import { h, Fragment } from '@obinexusltd/obix-jsx-adapter';

// JSX works here
function MyComponent() {
  return <obix-button label="Click" />;
}

How It Works

1. JSX Syntax (Input)

<obix-button label="Save" variant="primary" />

2. TypeScript Compilation

The compiler transforms JSX to function calls:

h(obixButton, { label: "Save", variant: "primary" })

3. Factory Execution

The h() function:

  • Validates the component is a factory function
  • Processes children (filters null, flattens arrays)
  • Calls the factory with props
  • Attaches children to component
  • Returns OBIX component object

4. Component Object

{
  name: 'Button',
  state: {
    label: 'Save',
    variant: 'primary',
    disabled: false,
    loading: false,
    // ... more state
  },
  actions: {
    setLabel: (state, label) => ({ ...state, label }),
    setDisabled: (state, disabled) => ({ ...state, disabled }),
    // ... more actions
  },
  render: (state) => '<button>Save</button>',
  aria: { label: 'Save' }
}

5. Rendering

const html = button.render(button.state);
// "<button class="obix-button obix-button--primary">Save</button>"

document.getElementById('app').innerHTML = html;

Key Features

Zero Dependencies — No virtual DOM, no React runtime
React Spec Compliant — Standard JSX compilation
Type-Safe — Full TypeScript support
Fragment Support<>...</> syntax works
Children Processing — Automatic null/undefined filtering
XSS Protection — Built-in HTML escaping
Tiny — 3-5 KB minified


Examples

Vanilla JavaScript

<script type="module">
  import { h } from '@obinexusltd/obix-jsx-adapter';
  import { obixButton } from '@obinexusltd/obix-jsx-components';
  
  const button = h(obixButton, { label: 'Click me' });
  document.getElementById('app').innerHTML = button.render(button.state);
</script>

TypeScript with JSX

/** @jsx h */
import { h } from '@obinexusltd/obix-jsx-adapter';
import { obixForm, obixInput, obixButton } from '@obinexusltd/obix-jsx-components';

function LoginForm() {
  return (
    <obix-form label="Login">
      <obix-input name="email" type="email" label="Email" required />
      <obix-input name="password" type="password" label="Password" required />
      <obix-button label="Sign In" variant="primary" />
    </obix-form>
  );
}

Functional Programming

import { h, Fragment } from '@obinexusltd/obix-jsx-adapter';
import { obixButton } from '@obinexusltd/obix-jsx-components';

// Reusable component factory
const Counter = (props: { count: number }) => (
  <obix-button label={`Count: ${props.count}`} variant="primary" />
);

// Compose
const buttons = h(Fragment, null,
  Counter({ count: 0 }),
  Counter({ count: 1 }),
  Counter({ count: 2 })
);

Integration Points

With TypeScript Compiler

  • Configures jsxFactory: "h"
  • Compiles JSX to function calls
  • No runtime JSX parsing needed

With Component Factories

  • h() calls component factory functions
  • Factories return OBIX component objects
  • No factory-specific logic in adapter

With DOP Adapter

  • Not imported here (zero dependency)
  • Adapters work on output objects
  • Separate bridge in obix-jsx-integration

Constraints (Non-Negotiable)

✅ Pure function — no side effects
✅ No DOM access — no document, window
✅ No framework imports — zero dependencies
✅ Immutable output — never mutates inputs
✅ Type-safe — all generics properly bound
✅ XSS-safe — escapes HTML in strings


Performance

| Operation | Time | |-----------|------| | h() call | <1ms | | Render 100 components | <5ms | | Compile JSX | Build-time (not runtime) | | Bundle size | 3-5 KB minified |


Browser Support

| Browser | Version | |---------|---------| | Chrome | 90+ | | Firefox | 88+ | | Safari | 14+ | | Edge | 90+ | | Node.js (SSR) | 18+ |


Related Packages


License

MIT © 2026 Nnamdi Okpalan / OBINexus Computing