Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/i-like-robots/hyperons
🔥 The fastest JSX to string renderer on the server and in the browser.
https://github.com/i-like-robots/hyperons
html hyperscript jsx
Last synced: 4 days ago
JSON representation
🔥 The fastest JSX to string renderer on the server and in the browser.
- Host: GitHub
- URL: https://github.com/i-like-robots/hyperons
- Owner: i-like-robots
- License: mit
- Created: 2018-04-09T07:56:31.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2024-03-19T09:00:59.000Z (8 months ago)
- Last Synced: 2024-04-14T04:48:56.598Z (7 months ago)
- Topics: html, hyperscript, jsx
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/hyperons
- Size: 577 KB
- Stars: 44
- Watchers: 2
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/i-like-robots/hyperons/blob/main/LICENSE) ![build status](https://github.com/i-like-robots/hyperons/actions/workflows/test.yml/badge.svg?branch=main) [![Coverage Status](https://coveralls.io/repos/github/i-like-robots/hyperons/badge.svg?branch=main)](https://coveralls.io/github/i-like-robots/hyperons?branch=main) [![npm version](https://img.shields.io/npm/v/hyperons.svg?style=flat)](https://www.npmjs.com/package/hyperons)
The fastest and smallest JSX to string renderer on the server and in the browser.
## Installation
This is a [Node.js][node] module available through the [npm][npm] registry. Before installing, download and install Node.js. Node.js 14 or higher is required.
Installation is done using the [npm install][install] command:
```sh
$ npm install -S hyperons
```[node]: https://nodejs.org/en/
[npm]: https://www.npmjs.com/
[install]: https://docs.npmjs.com/getting-started/installing-npm-packages-locally## Features
- [The fastest](#benchmarks) JSX to string renderer and tiny code size (1.2kb gzipped)
- Render components on the server and in the browser
- Works with class components and functional components, even ones that use [hooks](#hooks)
- Support for context, CSS stringification, boolean attributes, void elements, fragments, and more## Usage
This module provides two functions; one to create elements and one to render them. If you've worked with [React][react] or React-like libraries before then they're the equivalent to `React.createElement()` and `ReactDOM.renderToString()`.
The example below shows how to render a simple component using Hyperons with vanilla JavaScript:
[react]: https://reactjs.org/
```js
import { h, render } from 'hyperons'const Welcome = () =>
h(
'div',
{ className: 'welcome-banner' },
h('h1', null, 'Hello World!'),
h('p', null, 'This component was rendered with Hyperons')
)render(Welcome())
```Although you can use Hyperons without a compilation step, I'd recommend using [JSX](#jsx) to more succinctly describe your markup. Here is the same component as before but rewritten to use JSX syntax:
```jsx
import { h, render } from 'hyperons'const Welcome = () => (
Hyperons
This component was rendered with Hyperons
)render()
```## API
### `Hyperons.h()` / `Hyperons.createElement()`
```js
Hyperons.h(type[, props][, ...children])
```Returns an element with the given `props`. It accepts the following arguments:
- `type` The type of element to create which can be the name of an HTML element (such as `"div"`), a [component](#components), or a [fragment](#fragments).
- `props` An object containing data to pass to a component or HTML attributes to render. See the [props documentation](#props) for more information.
- `...children` Any number of child elements which may be simple values or other elements. See the [children documentation](#children) for more information.### `Hyperons.render()` / `Hyperons.renderToString()`
```js
Hyperons.render(element)
```Returns the rendered `element` as a string. It accepts the following arguments:
- `element` An element created with `Hyperons.h()`
### `Hyperons.Component`
Components can be defined as classes or functions. Components written as classes should extend `Hyperons.Component`:
```jsx
import { h, Component } from 'hyperons'class Welcome extends Component {
render() {
returnHello, {this.props.name}
}
}
```The only method you must define for a class component is `render()`. See the [component syntax](#components) documentation for more information.
### `Hyperons.Fragment`
A `Fragment` is a special component which enables multiple elements to be rendered without a wrapper. See the [using fragments](#fragments) documentation for more information.
```jsx
import { h, Fragment } from 'hyperons'const DescriptionList = () => {
return (
- {item.title}
- {item.description}
{props.definitions.map((item) => (
))}
)
}
```
### `Hyperons.Suspense`
`Suspense` is a special component which renders a fallback for lazy-loaded or async children. Hyperons only renders static HTML so this component exists only for compatibility purposes and will not render its children.
```jsx
import { h, Suspense } from 'hyperons'
const AsyncComponent = () => {
return (
}>
)
}
```
### `Hyperons.createContext`
Creates a new [context](#context) object. Components which subscribe to this context will read the current context value from the closest matching context provider above it in the tree. Hyperons largely supports the same [context API](https://reactjs.org/docs/context.html) as React including accessing context via the `Class.contextType` property and `useContext()` [hook](#hooks).
```jsx
import { h, createContext } from 'hyperons'
const MyContext = createContext()
const ChildComponent = () => {
return {(ctx) =>
{ctx.text}
}}
const ParentComponent = () => {
return (
)
}
```
### Hooks
React v16.8 introduced hooks which enable developers to add state, persistent data, and hook into lifecycle events from functional components. Hyperons renders static HTML so there is no state nor lifecycle methods but shims for the following hooks are currently supported:
| Hook | Behavior |
| --------------- | -------------------------------------------------------------------- |
| useCallback | Returns the given function |
| useContext | Fully functional, see [context](#context) |
| useEffect | No op |
| useLayoutEffect | No op |
| useMemo | Invokes the given function and returns the value |
| useReducer | Returns the given value and a no op function, calls init if provided |
| useRef | Returns the given value wrapped in an object |
| useState | Returns the given value and a no op function |
```jsx
import { h, useCallback, useState } from 'hyperons'
function Counter() {
const [count, setCount] = useState(0)
const onIncrement = useCallback(() => setCount(count + 1), [count])
const onDecrement = useCallback(() => setCount(count - 1), [count])
return (
-
+
)
}
```
## Syntax
### Components
Components are reusable pieces of UI which can be composed in useful ways. There are two types of components supported by Hyperons:
- Functional components which are regular JavaScript functions which accept `props` and return elements.
- Class components, which are ES6 classes extending `Hyperons.Component` and have a `render()` method which returns elements.
Here is an example showing the same component written using a function and as a class:
```jsx
import { h, Component } from 'hyperons'
// Functional component
function SubmitButtonFn(props) {
return {props.text}
}
// Class component
class SubmitButtonClass extends Component {
render() {
return {this.props.text}
}
}
```
When using React or React-like libraries class components are usually used to add extra functionality such as hooking into lifecycle methods and maintain state. Hyperons renders static HTML so there is no state nor lifecycle methods.
### Props
Props are objects either containing data to share with components or [HTML attributes](#html-attributes) for a HTML element. A component should never modify the props it receives.
```js
// Pass data to a component as props
Hyperons.createElement(SubmitButton, { text: 'Submit' })
// Render props as HTML attributes
Hyperons.createElement('button', { type: 'submit' })
```
Default prop values can be defined on components by adding a `defaultProps` property. These will be combined with any props received by the component:
```jsx
// Functional component
function SubmitButtonFn(props) {
// ...
}
SubmitButtonFn.defaultProps = {
text: 'Submit'
}
// Class component
class SubmitButtonClass extends Hyperons.Component {
// ...
static get defaultProps() {
return {
text: 'Submit'
}
}
}
```
### HTML Attributes
When props are used to render [attributes] some property names and values will be treated differently by Hyperons:
- Because `class` and `for` are [reserved words][words] in JavaScript you may use the aliases `className` and `htmlFor` instead.
- Boolean attributes, such as `hidden` or `checked`, will only be rendered if assigned a [truthy][truthy] value.
- Enumerated attributes which accept the values `"true"` or `"false"`, such as `contenteditable`, will be rendered with their assigned value.
- Any attributes requiring hyphens, such as `aria-*` and `data-*` should be written with hyphens.
- Framework specific props such as `key` and `ref` will not be rendered.
- Attributes with a function value, such as event handlers, will not be rendered.
[attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
[words]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords
[truthy]: https://developer.mozilla.org/en-US/docs/Glossary/Truthy
### Styles
The `style` attribute accepts a JavaScript object containing CSS properties and values.
CSS Properties may be written in camelCase for consistency with accessing the properties with JavaScript in the browser (e.g. `element.style.marginBottom`). Vendor prefixes other than `ms` should always begin with a capital letter (e.g. `WebkitHyphens`).
Hyperons will automatically append a `px` suffix to number values but certain properties will remain unit-less (e.g. `z-index` and `order`). If you want to use units other than `px`, you should specify the value as a string with the desired unit. For example:
```jsx
// Input:
const styles = {
display: 'flex',
order: 2,
width: '50%',
marginBottom: 20,
WebkitHyphens: 'auto',
}
Hyperons.render(
)// Output: