## File: README.md

[](https://github.com/infernojs/inferno/actions)
[](https://coveralls.io/github/infernojs/inferno?branch=master)
[](https://github.com/infernojs/inferno/blob/master/LICENSE.md)
[](https://www.npmjs.com/package/inferno)
[](https://www.npmjs.org/package/inferno)
[](https://discord.gg/SUKuhgaBpF)
[](https://unpkg.com/inferno/dist/inferno.min.js)
[](#backers) [](#sponsors)

Inferno is an insanely fast, React-like library for building high-performance user interfaces on both the client and server.

## Description

The main objective of the InfernoJS project is to provide the fastest possible **runtime** performance for web applications. Inferno excels at rendering real time data views or large DOM trees.

The performance is achieved through multiple optimizations, for example:

- Inferno's own JSX compilers creates monomorphic `createVNode` calls, instead of `createElement` calls.
Optimizing runtime performance of the application. 
  - [SWC plugin inferno](https://github.com/infernojs/swc-plugin-inferno) is a plugin for [SWC](https://swc.rs/). It can compile TSX and JSX
  - [Babel plugin inferno](https://github.com/infernojs/babel-plugin-inferno) is a plugin for [BabelJs](https://babeljs.io/). It can compile JSX.
  - [TS plugin inferno](https://github.com/infernojs/ts-plugin-inferno) is a plugin for [TSC](https://www.typescriptlang.org/). It can compile TSX.
- Inferno's diff process uses bitwise flags to memoize the shape of objects
- Child nodes are normalized only when needed
- Special JSX flags can be used during compile time to optimize runtime performance at application level
- Many micro optimizations

## Features

- Component driven + one-way data flow architecture
- React-like API, concepts and component lifecycle events
- Partial synthetic event system, normalizing events for better cross browser support
- Inferno's [`linkEvent`](https://github.com/infernojs/inferno/blob/master/README.md#linkevent-package-inferno) feature removes the need to use arrow functions or binding event callbacks
- Isomorphic rendering on both client and server with `inferno-server`
- Unlike React and Preact, Inferno has lifecycle events on functional components
- Unlike Preact and other React-like libraries, Inferno has controlled components for input/select/textarea elements
- Components can be rendered outside their current html hierarchy using `createPortal` - API
- Support for [older browsers](https://github.com/infernojs/inferno#browser-support) without any polyfills
- defaultHooks for Functional components, this way re-defining lifecycle events per usage can be avoided
- Inferno supports setting styles using string `` or using object literal syntax ``. For camelCase syntax support see [`inferno-compat`](https://github.com/infernojs/inferno/tree/master/packages/inferno-compat).
- Fragments (v6)
- createRef and forwardRef APIs (v6)
- componentDidAppear, componentWillDisappear and componentWillMove (v8) - class and function component callbacks to ease animation work, see [inferno-animation](https://github.com/infernojs/inferno/tree/master/packages/inferno-animation) package

## Runtime requirements
Inferno v9 requires following features to be present in the executing runtime:

- `Promise`
- `String.prototype.includes()`
- `String.prototype.startsWith()`
- `Array.prototype.includes()`
- `Object.spread()`
- `for ... of`

## Browser support
Since version 4 we have started running our test suite **without** any polyfills.
Inferno is now part of [Saucelabs](https://saucelabs.com/) open source program and we use their service for executing the tests.

InfernoJS is actively tested with browsers listed below, however it may run well on older browsers as well.
This is due to limited support of browser versions in recent testing frameworks. https://github.com/jasmine/jasmine/blob/main/release_notes/5.0.0.md

[](https://app.saucelabs.com/open_sauce/user/Havunen/tests/vdc)

## Migration guides

- [Inferno v4](https://github.com/infernojs/inferno/blob/master/documentation/v4-migration.md)
- [Inferno v6](https://github.com/infernojs/inferno/blob/master/documentation/v6-migration.md)

## Benchmarks

Live examples at [https://infernojs.github.io/inferno](https://infernojs.github.io/inferno)

- [UI Bench](https://localvoid.github.io/uibench/)
- [dbmonster](https://infernojs.github.io/inferno/dbmonster/)
- [JS Web Frameworks Benchmark (current)](https://krausest.github.io/js-framework-benchmark/current.html)
- [Isomorphic-UI-Benchmark](https://github.com/marko-js/isomorphic-ui-benchmarks)
- [1k Components](https://infernojs.github.io/inferno/1kcomponents/)

## Code Example

Let's start with some code. As you can see, Inferno intentionally keeps the same design ideas as React regarding components: one-way data flow and separation of concerns.

In these examples, JSX is used via the [Inferno JSX Babel Plugin](https://github.com/infernojs/babel-plugin-inferno) to provide a simple way to express Inferno virtual DOM. You do not need to use JSX, it's completely **optional**, you can use [hyperscript](https://github.com/infernojs/inferno/tree/master/packages/inferno-hyperscript) or [createElement](https://github.com/infernojs/inferno/tree/master/packages/inferno-create-element) (like React does).
Keep in mind that compile time optimizations are available only for JSX.

```jsx
import { render } from 'inferno';

const message = "Hello world";

render(
  <MyComponent message={ message } />,
  document.getElementById("app")
);
```
Furthermore, Inferno also uses ES6 components like React:

```jsx
import { render, Component } from 'inferno';

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    };
  }
  render() {
    return (
      
        <h1>Header!</h1>
        Counter is at: { this.state.counter }
      
    );
  }
}

render(
  <MyComponent />,
  document.getElementById("app")
);
```

Because performance is an important aspect of this library, we want to show you how to optimize your application even further.
In the example below we optimize diffing process by using JSX **$HasVNodeChildren** and **$HasTextChildren** to predefine children shape compile time.
In the MyComponent render method there is a div that contains JSX expression `node` as its content. Due to dynamic nature of Javascript
that variable `node` could be anything and Inferno needs to go through the normalization process to make sure there are no nested arrays or other invalid data.
Inferno offers a feature called ChildFlags for application developers to pre-define the shape of vNode's child node. In this example case
it is using `$HasVNodeChildren` to tell the JSX compiler, that this vNode contains only single element or component vNode.
Now inferno will not go into the normalization process runtime, but trusts the developer decision about the shape of the object and correctness of data.
If this contract is not kept and `node` variable contains invalid value for the pre-defined shape (fe. `null`), then application would crash runtime.
There is also span-element in the same render method, which content is set dynamically through `_getText()` method. There `$HasTextChildren` child-flag
fits nicely, because the content of that given "span" is never anything else than text.
All the available child flags are documented [here](https://infernojs.org/docs/guides/optimizations).

```jsx
import { createTextVNode, render, Component } from 'inferno';

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    };
  }

  _getText() {
     return 'Hello!';
  }
  
  render() {
    const node = this.state.counter > 0 ? 0 : {this._getText()};
      
    return (
      
        <h1>Header!</h1>
        {node}
      
    );
  }
}

render(
  <MyComponent />,
  document.getElementById("app")
);
```

### Tear down

To tear down inferno application you need to render null on root element. 
Rendering `null` will trigger unmount lifecycle hooks for whole vDOM tree and remove global event listeners.
It is important to unmount unused vNode trees to free browser memory. 

```jsx
import { createTextVNode, render, Component } from 'inferno';

const rootElement = document.getElementById("app");

// Start the application
render(
  <ExampleComponent/>,
  rootElement
);

// Tear down
render(
  null,
  rootElement
);

```


### More Examples

If you have built something using Inferno you can add them here:

- [**Simple Clock** (@JSFiddle)](https://jsfiddle.net/4bha7kcg/)
- [**Simple JS Counter** (@github/scorsi)](https://github.com/scorsi/simple-counter-inferno-cerebral-fusebox): SSR Inferno (view) + Cerebral (state manager) + FuseBox (build system/bundler)
- [**Online interface to TMDb movie database** (@codesandbox.io)](https://codesandbox.io/s/9zjo5yx8po): Inferno + [Inferno hyperscript](https://github.com/infernojs/inferno) (view) + [Superagent](https://github.com/visionmedia/superagent) (network requests) + Web component ([custom elements v1](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements)) + [state-transducer](https://github.com/brucou/state-transducer) 
(state machine library) 
- [**Lemmy - a self-hostable reddit alternative** (front end in Inferno)](https://github.com/dessalines/lemmy)

## Getting Started

The easiest way to get started with Inferno is by using [Create Inferno App](https://github.com/infernojs/create-inferno-app).

Alternatively, you can try any of the following:
* the [Inferno Boilerplate](https://github.com/infernojs/inferno-boilerplate) for a very simple setup.
* for a more advanced example demonstrating how Inferno might be used, we recommend trying out [Inferno Starter Project](https://github.com/nightwolfz/inferno-starter) by [nightwolfz](https://github.com/nightwolfz/).
* for using Inferno to build a mobile app, try [Inferno Mobile Starter Project](https://github.com/Rudy-Zidan/inferno-mobile) by [Rudy-Zidan](https://github.com/Rudy-Zidan).
* for [TypeScript](https://www.typescriptlang.org/) support and bundling, check out [ts-plugin-inferno](https://github.com/infernojs/ts-plugin-inferno), or [inferno-typescript-example](https://github.com/infernojs/inferno-typescript-example).
* for an example of how to use Inferno in [codesandbox](https://codesandbox.io/): https://codesandbox.io/s/znmyj24w4p
* for using [parcel and typescript](https://github.com/jayy-lmao/inferno-parcel-ts)

Core package:

```sh
npm install --save inferno
```

Addons:

```sh
# server-side rendering
npm install --save inferno-server
# routing
npm install --save inferno-router
```

Pre-bundled files for browser consumption can be found on [our cdnjs](https://cdnjs.com/libraries/inferno):

Or on jsDelivr:

```
https://cdn.jsdelivr.net/npm/inferno@latest/dist/inferno.min.js
```

Or on unpkg.com:

```
https://unpkg.com/inferno@latest/dist/inferno.min.js
```

### Creating Virtual DOM

#### JSX:
```sh
npm install --save-dev babel-plugin-inferno
```

#### Hyperscript:
```sh
npm install --save inferno-hyperscript
```

#### createElement:
```sh
npm install --save inferno-create-element
```

### Compatibility with existing React apps
```sh
npm install --save-dev inferno-compat
```

Note: Make sure you read more about [`inferno-compat`](https://github.com/infernojs/inferno/tree/master/packages/inferno-compat) before using it.

## Third-party state libraries

Inferno now has bindings available for some of the major state management libraries out there:

- Redux via [`inferno-redux`](https://github.com/infernojs/inferno/tree/dev/packages/inferno-redux)
- MobX via [`inferno-mobx`](https://github.com/infernojs/inferno/tree/dev/packages/inferno-mobx)
- Cerebral via [`@cerebral/inferno`](https://github.com/cerebral/cerebral/tree/master/packages/node_modules/@cerebral/inferno)

## JSX

Inferno has its own [JSX Babel plugin](https://github.com/trueadm/babel-plugin-inferno).

## Differences from React

- Inferno doesn't have a fully synthetic event system like React does. Inferno has a partially synthetic event system, instead opting to only delegate certain events (such as `onClick`).
- Inferno doesn't support React Native. Inferno was only designed for the browser/server with the DOM in mind.
- Inferno doesn't support legacy string refs, use `createRef` or callback `ref` API
- Inferno provides lifecycle events on functional components. This is a major win for people who prefer lightweight components rather than ES2015 classes.

## Differences from Preact

- Inferno has a partial synthetic event system, resulting in better performance via delegation of certain events.
- Inferno is *much* faster than Preact in rendering, updating and removing elements from the DOM. Inferno diffs against virtual DOM, rather than the real DOM (except when loading from server-side rendered content), which means it can make drastic improvements. Unfortunately, diffing against the real DOM has a 30-40% overhead cost in operations.
- Inferno fully supports controlled components for `input`/`select`/`textarea` elements. This prevents lots of edgecases where the virtual DOM is not the source of truth (it should always be). Preact pushes the source of truth to the DOM itself.
- Inferno provides lifecycle events on functional components. This is a major win for people who prefer lightweight components rather than ES2015 classes.

## Event System

Like React, Inferno also uses a light-weight synthetic event system in certain places (although both event systems differ massively). Inferno's event system provides highly efficient delegation and an event helper called [`linkEvent`](https://github.com/infernojs/inferno/blob/master/README.md#linkevent-package-inferno).

One major difference between Inferno and React is that Inferno does not rename events or change how they work by default. Inferno only specifies that events should be camel cased, rather than lower case. Lower case events will bypass
Inferno's event system in favour of using the native event system supplied by the browser. For example, when detecting changes on an `` element, in React you'd use `onChange`, with Inferno you'd use `onInput` instead (the
native DOM event is `oninput`).

Available synthetic events are:
- `onClick`
- `onDblClick`
- `onFocusIn`
- `onFocusOut`
- `onKeyDown`
- `onKeyPress`
- `onKeyUp`
- `onMouseDown`
- `onMouseMove`
- `onMouseUp`
- `onTouchEnd`
- `onTouchMove`
- `onTouchStart`

### `linkEvent` (package: `inferno`)

`linkEvent()` is a helper function that allows attachment of `props`/`state`/`context` or other data to events without needing to `bind()` them or use arrow functions/closures. This is extremely useful when dealing with events in functional components. Below is an example:

```jsx
import { linkEvent } from 'inferno';

function handleClick(props, event) {
  props.validateValue(event.target.value);
}

function MyComponent(props) {
  return ;
}
```

This is an example of using it with ES2015 classes:


```jsx
import { linkEvent, Component } from 'inferno';

function handleClick(instance, event) {
  instance.setState({ data: event.target.value });
}

class MyComponent extends Component {
  render () {
    return ;
  }
}
```

`linkEvent()` offers better performance than binding an event in a class constructor and using arrow functions, so use it where possible.


## Controlled Components

In HTML, form elements such as ``, `<textarea>`, and `<select>` typically maintain their own state and update it based on user input.
In Inferno, mutable state is typically kept in the state property of components, and only updated with `setState()`.

We can combine the two by making the Inferno state be the "single source of truth". Then the Inferno component that renders a form also
controls what happens in that form on subsequent user input. An input form element whose value is controlled by
Inferno in this way is called a "controlled component".

## Inferno Top-Level API

### `render` (package: `inferno`)

```javascript
import { render } from 'inferno';

render(, document.getElementById("app"));
```

Render a virtual node into the DOM in the supplied container given the supplied virtual DOM. If the virtual node was previously rendered
into the container, this will perform an update on it and only mutate the DOM as necessary, to reflect the latest Inferno virtual node.

Warning: If the container element is not empty before rendering, the content of the container will be overwritten on the initial render.

### `createRenderer` (package: `inferno`)

`createRenderer` creates an alternative render function with a signature matching that of the first argument passed to a reduce/scan function. This allows for easier integration with reactive programming libraries, like [RxJS](https://github.com/ReactiveX/rxjs) and [Most](https://github.com/cujojs/most).

```javascript
import { createRenderer } from 'inferno';
import { scan, map } from 'most';

const renderer = createRenderer();


// NOTE: vNodes$ represents a stream of virtual DOM node updates
scan(renderer, document.getElementById("app"), vNodes$);
```

See [inferno-most-fp-demo](https://github.com/joshburgess/inferno-most-fp-demo) for an example of how to build an app architecture around this.

### `createElement` (package: `inferno-create-element`)

Creates an Inferno VNode using a similar API to that found with React's `createElement()`

```javascript
import { Component, render } from 'inferno';
import { createElement } from 'inferno-create-element';

class BasicComponent extends Component {
  render() {
    return createElement('div', {
        className: 'basic'
      },
      createElement('span', {
        className: this.props.name
      }, 'The title is ', this.props.title)
    )
  }
}

render(
  createElement(BasicComponent, { title: 'abc' }),
  document.getElementById("app")
);
```

### `Component` (package: `inferno`)

**Class component:**

```javascript
import { Component } from 'inferno';

class MyComponent extends Component {
  render() {
      return My Component
  }
}
```

This is the base class for Inferno Components when they're defined using ES6 classes.

**Functional component:**

```javascript
const MyComponent = ({ name, age }) => (
  My name is: { name } and my age is: {age}
);
```

Another way of using defaultHooks.
```javascript
export function Static() {
    return 1;
}

Static.defaultHooks = {
    onComponentShouldUpdate() {
        return false;
    }
};
```

Default props
```jsx
export function MyFunctionalComponent({value}) {
    return {value};
}

MyFunctionalComponent.defaultProps = {
    value: 10
};

```

Functional components are first-class functions where their first argument is the `props` passed through from their parent.

### `createVNode` (package: `inferno`)
```js
import { createVNode } from 'inferno';

createVNode(
  flags,
  type,
  [className],
  [...children],
  [childFlags],
  [props],
  [key],
  [ref]
)
```

createVNode is used to create html element's virtual node object. Typically `createElement()` (package: `inferno-create-element`), `h()` (package: `inferno-hyperscript`) or JSX are used to create
`VNode`s for Inferno, but under the hood they all use `createVNode()`. Below is an example of `createVNode` usage:

```javascript
import { VNodeFlags, ChildFlags } from 'inferno-vnode-flags';
import { createVNode, createTextVNode, render } from 'inferno';

const vNode = createVNode(VNodeFlags.HtmlElement, 'div', 'example', createTextVNode('Hello world!'), ChildFlags.HasVNodeChildren);

// Hello world!

render(vNode, container);
```

`createVNode` arguments explained:

`flags`: (number) is a value from [`VNodeFlags`](https://github.com/infernojs/inferno/tree/master/packages/inferno-vnode-flags), this is a numerical value that tells Inferno what the VNode describes on the page.

`type`: (string) is tagName for element for example 'div'

`className`: (string) is the class attribute ( it is separated from props because it is the most commonly used property )

`children`: (vNode[]|vNode) is one or array of vNodes to be added as children for this vNode

`childFlags`: (number) is a value from [`ChildFlags`](https://github.com/infernojs/inferno/tree/master/packages/inferno-vnode-flags), this tells inferno shape of the children so normalization process can be skipped.

`props`: (Object) is object containing all other properties. fe: `{onClick: method, 'data-attribute': 'Hello Community!}`

`key`: (string|number) unique key within this vNodes siblings to identify it during keyed algorithm.

`ref`: (function) callback which is called when DOM node is added/removed from DOM.


### `createComponentVNode` (package: 'inferno')
```js
import { createComponentVNode } from 'inferno';

createComponentVNode(
  flags,
  type,
  [props],
  [key],
  [ref]
)
```

createComponentVNode is used for creating vNode for Class/Functional Component.

Example:
```javascript
import { VNodeFlags, ChildFlags } from 'inferno-vnode-flags';
import { createVNode, createTextVNode, createComponentVNode, render } from 'inferno';

function MyComponent(props, context) {
  return createVNode(VNodeFlags.HtmlElement, 'div', 'example', createTextVNode(props.greeting), ChildFlags.HasVNodeChildren);
}

const vNode = createComponentVNode(VNodeFlags.ComponentFunction, MyComponent, {
  greeting: 'Hello Community!'
}, null, {
  onComponentDidMount() {
    console.log("example of did mount hook!")
  }
})

// Hello Community!

render(vNode, container);
```


`createComponentVNode` arguments explained:

`flags`: (number) is a value from [`VNodeFlags`](https://github.com/infernojs/inferno/tree/master/packages/inferno-vnode-flags), this is a numerical value that tells Inferno what the VNode describes on the page.

`type`: (Function/Class) is the class or function prototype for Component

`props`: (Object) properties passed to Component, can be anything

`key`: (string|number) unique key within this vNodes siblings to identify it during keyed algorithm.

`ref`: (Function|Object) this property is object for Functional Components defining all its lifecycle methods. For class Components this is function callback for ref.



### `createTextVNode` (package: 'inferno')

createTextVNode is used for creating vNode for text nodes.

`createTextVNode` arguments explained:
text: (string) is a value for text node to be created.
key: (string|number) unique key within this vNodes siblings to identify it during keyed algorithm.

```js
import { createTextVNode } from 'inferno';

createTextVNode(
  text,
  key
)
```


### `cloneVNode` (package: `inferno-clone-vnode`)

This package has same API as React.cloneElement

```javascript
import { cloneVNode } from 'inferno-clone-vnode';

cloneVNode(
  vNode,
  [props],
  [...children]
)
```

Clone and return a new Inferno `VNode` using a `VNode` as the starting point. The resulting `VNode` will have the original `VNode`'s props with the new props merged in shallowly. New children will replace existing children. key and ref from the original `VNode` will be preserved.

`cloneVNode()` is almost equivalent to:
```jsx
<VNode.type {...VNode.props} {...props}>{children}</VNode.type>
```

An example of using `cloneVNode`:

```javascript
import { createVNode, render } from 'inferno';
import { cloneVNode } from 'inferno-clone-vnode';
import { VNodeFlags } from 'inferno-vnode-flags';

const vNode = createVNode(VNodeFlags.HtmlElement, 'div', 'example', 'Hello world!');
const newVNode = cloneVNode(vNode, { id: 'new' }); // we are adding an id prop to the VNode

render(newVNode, container);
```

If you're using JSX:

```jsx
import { render } from 'inferno';
import { cloneVNode } from 'inferno-clone-vnode';

const vNode = Hello world;
const newVNode = cloneVNode(vNode, { id: 'new' }); // we are adding an id prop to the VNode

render(newVNode, container);
```

### `createPortal` (package: 'inferno')

HTML:
```html


```

Javascript:
```jsx
const { render, Component, version, createPortal } from 'inferno';

function Outsider(props) {
	return {`Hello ${props.name}!`};
}

const outsideDiv = document.getElementById('outside');
const rootDiv = document.getElementById('root');

function App() {
	return (
  	    
    	    Main view
            ...
            {createPortal(<Outsider name="Inferno" />, outsideDiv)}
        
    );
}


// render an instance of Clock into :
render(<App />, rootDiv);
```

Results into:
```html

    Main view ...


    Hello Inferno!

```
Cool, huh? Updates (props/context) will flow into "Outsider" component from the App component the same way as any other Component.
For inspiration on how to use it click [here](https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202)!

### `createRef` (package: `inferno`)

createRef API provides shorter syntax than callback ref when timing of element is not needed.

```jsx
import { Component, render, createRef } from 'inferno';

class Foobar extends Component {
  constructor(props) {
    super(props);

    // Store reference somewhere
    this.element = createRef(); // Returns object {current: null}
  }

  render() {
    return (
      
        
          Ok
        
      
    );
  }
}

render(<Foobar />, container);
```


### `createFragment` (package: `inferno`)

createFragment is the native way to createFragment vNode. `createFragment(children: any, childFlags: ChildFlags, key?: string | number | null)`

`createFragment` arguments explained:

`children`: (Array) Content of fragment vNode, typically array of VNodes

`childFlags`: (number) is a value from [`ChildFlags`](https://github.com/infernojs/inferno/tree/master/packages/inferno-vnode-flags), this tells inferno shape of the children so normalization process can be skipped.

`key`: (string|number) unique key within this vNodes siblings to identify it during keyed algorithm.


Alternative ways to create fragment vNode are:

- Using JSX `<> ... </>`, `<Fragment> .... </Fragment>` or ` ... `
- Using createElement API `createElement(Inferno.Fragment, {key: 'test'}, ...children)`
- Using hyperscript API `h(Inferno.Fragment, {key: 'test'}, children)`


In the below example both fragments are identical except they have different key
```jsx
import { Fragment, render, createFragment } from 'inferno';
import { ChildFlags } from 'inferno-vnode-flags';

function Foobar() {
    return (
      
        {createFragment(
            [Ok, 1],
            ChildFlags.HasNonKeyedChildren,
            'key1'
        )}
        <Fragment key="key2">
          Ok
          1
        </Fragment>
      
    );
}

render(<Foobar />, container);
```


### `forwardRef` (package: `inferno`)

forwardRef is a new mechanism to "forward" ref inside a functional Component.
It can be useful if you have simple functional Components and you want to create reference to a specific element inside it.

```jsx
import { forwardRef, Component, render } from 'inferno';

const FancyButton = forwardRef((props, ref) => (
  
    {props.children}
  
));

class Hello extends Component {
  render() {
    return (
      <FancyButton
        ref={btn => {
          if (btn) {
            // btn variable is the button rendered from FancyButton
          }
        }}
      >
        Click me!
      </FancyButton>
    );
  }
}

render(<Hello />, container);
```

### `hydrate` (package: `inferno-hydrate`)

```javascript
import { hydrate } from 'inferno-hydrate';

hydrate(, document.getElementById("app"));
```

Same as `render()`, but is used to hydrate a container whose HTML contents were rendered by `inferno-server`. Inferno will attempt to attach event listeners to the existing markup.

### `findDOMNode` (package: `inferno-extras`)
This feature has been moved from inferno to inferno-compat in v6. No options are needed anymore.

Note: we recommend using a `ref` callback on a component to find its instance, rather than using `findDOMNode()`. `findDOMNode()` cannot be used on functional components.

If a component has been mounted into the DOM, this returns the corresponding native browser DOM element. This method is useful for reading values out of the DOM, such as form field values and performing DOM measurements.
In most cases, you can attach a ref to the DOM node and avoid using `findDOMNode()` at all. When render returns null or false, `findDOMNode()` returns null.
If Component has rendered fragment it returns the first element.

### Inferno Flags (package: inferno-vnode-flags)

**VNodeFlags:**
- `VNodeFlags.HtmlElement`
- `VNodeFlags.ComponentUnknown`
- `VNodeFlags.ComponentClass`
- `VNodeFlags.ComponentFunction`
- `VNodeFlags.Text`
- `VNodeFlags.SvgElement`
- `VNodeFlags.InputElement`
- `VNodeFlags.TextareaElement`
- `VNodeFlags.SelectElement`
- `VNodeFlags.Portal`
- `VNodeFlags.ReCreate` (JSX **$ReCreate**) always re-creates the vNode
- `VNodeFlags.ContentEditable`
- `VNodeFlags.Fragment`
- `VNodeFlags.InUse`
- `VnodeFlags.ForwardRef`
- `VNodeFlags.Normalized`

**VNodeFlags Masks:**
- `VNodeFlags.ForwardRefComponent` Functional component wrapped in forward ref
- `VNodeFlags.FormElement` - Is form element
- `VNodeFlags.Element` - Is vNode element
- `VNodeFlags.Component` - Is vNode Component
- `VNodeFlags.DOMRef` - Bit set when vNode holds DOM reference
- `VNodeFlags.InUseOrNormalized` - VNode is used somewhere else or came from normalization process
- `VNodeFlags.ClearInUseNormalized` - Opposite mask of InUse or Normalized


**ChildFlags**
- `ChildFlags.UnknownChildren` needs Normalization
- `ChildFlags.HasInvalidChildren` is invalid (null, undefined, false, true)
- `ChildFlags.HasVNodeChildren` (JSX **$HasVNodeChildren**) is single vNode (Element/Component)
- `ChildFlags.HasNonKeyedChildren` (JSX **$HasNonKeyedChildren**) is Array of vNodes non keyed (no nesting, no holes)
- `ChildFlags.HasKeyedChildren` (JSX **$HasKeyedChildren**) is Array of vNodes keyed (no nesting, no holes)
- `ChildFlags.HasTextChildren` (JSX **$HasTextChildren**) vNode contains only text

**ChildFlags Masks**
- `ChildFlags.MultipleChildren` Is Array


### `renderToString` (package: `inferno-server`)

```javascript
import { renderToString } from 'inferno-server';

const string = renderToString();
```

Render a virtual node into an HTML string, given the supplied virtual DOM.

## Functional component lifecycle events

| Name                        | Triggered when                                                  | Arguments to callback           |
| -----------                 | --------------                                                  | -----------------------         |
| `onComponentWillMount`      | a functional component is about to mount                        |                                 |
| `onComponentDidMount`       | a functional component has mounted successfully                 | `domNode`                       |
| `onComponentShouldUpdate`   | a functional component has been triggered to update             | `lastProps, nextProps`          |
| `onComponentWillUpdate`     | a functional component is about to perform an update            | `lastProps, nextProps`          |
| `onComponentDidUpdate`      | a functional component has performed an update                  | `lastProps, nextProps`          |
| `onComponentWillUnmount`    | a functional component is about to be unmounted                 | `domNode`                       |
| `onComponentDidAppear`      | a functional component has mounted and is ready for animations  | `domNode, props`                |
| `onComponentWillDisappear`  | a functional component is unmounted before DOM node is removed  | `domNode, props, callback`      |

onComponentWillDisappear has special type of argument "callback" which needs to be called when component is ready to be removed from the DOM. fe. after animations are finished.

## Class component lifecycle events

All these Component lifecycle methods ( including `render` and `setState - callback`) are called with Component instance context. You don't need to "bind" these methods.

| Name                              | Triggered when                                                                        | Arguments to callback           |
| -----------                       | --------------                                                                        | -----------------------         |
| `componentDidMount`               | component has been mounted successfully                                                |                                 |
| `componentWillMount`              | component is about to mount                                                           |                                 |
| `componentWillReceiveProps`       | before render when component updates                                                  | `nextProps, context`            |
| `shouldComponentUpdate`           | component has been triggered to update                                                | `nextProps, nextState`          |
| `componentWillUpdate`             | component is about to perform an update                                               | `nextProps, nextState, context` |
| `componentDidUpdate`              | component has performed an update                                                     | `lastProps, lastState, snapshot`|
| `componentWillUnmount`            | component is about to be unmounted                                                    |                                 |
| `getChildContext`                 | before render method, return value object is combined to sub tree context             |                                 |
| `getSnapshotBeforeUpdate`         | before component updates, return value is sent to componentDidUpdate as 3rd parameter | `lastProps, lastState`          |
| `static getDerivedStateFromProps` | before render method                                                                  | `nextProps, state`              |
| `componentDidAppear`              | component has mounted and is ready for animations                                     | `domNode`                       |
| `componentWillDisappear`          | component is unmounted before DOM node is removed                                     | `domNode, callback`             |

componentWillDisappear has special type of argument "callback" which needs to be called when component is ready to be removed from the DOM. fe. after animations are finished.

### Using functional lifecycle events

Functional lifecycle events must be explicitly assigned via props onto a functional component like shown below:

```javascript
import { render } from 'inferno';

function mounted(domNode) {
  // [domNode] will be available for DOM nodes and components (if the component has mounted to the DOM)
}

function FunctionalComponent({ props }) {
  return Hello world;
}

render(
  <FunctionalComponent onComponentDidMount={ mounted } />,
  document.getElementById("app")
);
```

Please note: class components (ES2015 classes) from `inferno` **do not** support the same lifecycle events (they have their own lifecycle events that work as methods on the class itself).

## Development vs Production modes

By default, Inferno will run in development mode. Development mode provides extra checks and better error messages at the cost of slower performance and larger code to parse.
When using Inferno in a production environment, it is highly recommended that you turn off development mode.

### Running Inferno on Node JS

Ensure the environment variable `process.env.NODE_ENV` is set to `production`.

## Application bundling

When building your application bundle, ensure `process.env.NODE_ENV` is replaced with string`"development"` or `"production"` based on the workflow.
It is recommended to use [ts-plugin-inferno](https://github.com/infernojs/ts-plugin-inferno) for typescript TSX compilation and [babel-plugin-infeno](https://github.com/infernojs/babel-plugin-inferno) for javascript JSX compilation.

When building for development, you may want to use `inferno.dev.mjs` for v9 or newer and `inferno.dev.esm.js` for older than v9. That bundle file contains ES6 exports for better tree-shaking support, improved error messages and added validation to help fixing possible issues during development.
The file is found from `package.json` - `dev:module` entry point and the files are physically located in `node_modules/inferno/dist/` folder.
Remember that it is not recommended to use that file in production due to slower performance. For production usage use `node_modules/inferno/dist/inferno.mjs` -file for v9 or newer and `node_modules/inferno/dist/inferno.esm.js` -file for older than v9.

Example of **Webpack** configuration:

```js
const path = require('path');
const infernoTsx = require('ts-plugin-inferno').default;

... webpack config ...

    module: {
        rules: [
            {
                test: /\.js$/, // Add "jsx" if your application uses `jsx` file extensions
                exclude: /node_modules/,
                use: [{
                    loader: 'babel-loader',
                    options: {
                        plugins: [
                            // Compile javascript JSX syntax using inferno's own plugin
                            ['babel-plugin-inferno', {imports: true}]
                        ]
                    }
                }]
            },
            {
                test: /\.ts+(|x)$/, // Compile ts and tsx extensions
                exclude: /node_modules/,
                use: [{
                    loader: 'ts-loader',
                    options: {
                        getCustomTransformers: () => ({
                            // inferno custom TSX plugin
                            after: [infernoTsx()]
                        }),
                        compilerOptions: {
                            /* typescript compiler options */
                        }
                    }
                }]
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.ts', '.tsx'],
        alias: {
            // This maps import "inferno" to es6 module entry based on workflow
            inferno: path.resolve(__dirname, 'node_modules/inferno/dist', isProduction ? 'index.dev.mjs' : 'index.mjs')
        }
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env': {
                'NODE_ENV':  JSON.stringify(isProduction ? 'production' : 'development')
            }
        })
    ]
```

Example of **Rollup** configuration:

```js
const path = require('path');
const alias = require('@rollup/plugin-alias');
const {babel} = require('@rollup/plugin-babel');
const replace = require('@rollup/plugin-replace');
const typescript = require('rollup-plugin-typescript2');
const transformInferno = require('ts-plugin-inferno').default;

... Rollup config ...
{
    input: /* entry file */,
    plugins: [
            alias({
                resolve: ['.js'],
                entries: [
                    // This maps import "inferno" to es6 module entry based on workflow
                    {find: 'inferno', replacement: path.resolve(__dirname, 'node_modules/inferno/dist', isProduction ? 'index.dev.mjs' : 'index.mjs')}
                ]
            }),
            typescript({
                include: ['*.ts+(|x)', '**/*.ts+(|x)'],
                transformers: [
                    () => ({
                        after: [transformInferno()]
                    })
                ],
                tsconfig: 'tsconfig.json',
                tsconfigOverride: {
                    /* typescript compiler options */
                }
            }),
            babel({
                babelrc: false,
                sourceMaps: isDeploy,
                plugins: [
                    // Compile javascript JSX syntax using inferno's own plugin
                    ['babel-plugin-inferno', {imports: true}]
                ],
                babelHelpers: 'bundled'
            })
    ]
}
```

### Custom namespaces

Inferno always wants to deliver great performance. In order to do so, it has to make intelligent assumptions about the state of the DOM and the elements available to mutate. Custom namespaces conflict with this idea and change the schema of how different elements and attributes might work, so Inferno makes no attempt to support namespaces. Instead, SVG namespaces are automatically applied to elements and attributes based on their `tag name`.

## Development
If you want to contribute code, fork this project and submit a PR from your fork. To run browser tests you need to build the repos. A complete rebuild of the repos can take >5 mins.

```sh
$ git clone git@github.com:infernojs/inferno.git
$ cd inferno && pnpm install
$ pnpm run test:node
$ pnpm run build
$ pnpm run test:browser
```

If you only want to run the browser tests when coding, use the following to reduce turnaround by 50-80%:

```sh
$ pnpm run quick-test:browser # Compiles all packages and runs browser tests
$ pnpm run quick-test:browser-inferno # Only compiles the inferno package and runs browser tests
$ pnpm run quick-test:browser-debug # Compiles all packages and runs browser tests with "debug"
```

## Community

There is an InfernoJS Discord. You can join via [https://discord.gg/SUKuhgaBpF](https://discord.gg/SUKuhgaBpF).


### Contributors

This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
[](https://github.com/infernojs/inferno/graphs/contributors)


### Backers

Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/inferno#backer)]

[](https://opencollective.com/inferno#backers)


### Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/inferno#sponsor)]

[](https://opencollective.com/inferno/sponsor/0/website)
[](https://opencollective.com/inferno/sponsor/1/website)
[](https://opencollective.com/inferno/sponsor/2/website)
[](https://opencollective.com/inferno/sponsor/3/website)
[](https://opencollective.com/inferno/sponsor/4/website)
[](https://opencollective.com/inferno/sponsor/5/website)
[](https://opencollective.com/inferno/sponsor/6/website)
[](https://opencollective.com/inferno/sponsor/7/website)
[](https://opencollective.com/inferno/sponsor/8/website)
[](https://opencollective.com/inferno/sponsor/9/website)

---

## File: demo/inferno-router-demo/README.md

# Demo of Inferno-Router

NOTE: Requires Nodejs >=18 (uses `fetch`)

```sh
pnpm install
pnpm --filter inferno-router-demo run dev:frontend
```

Go to http://127.0.0.1:1234/

---

## File: documentation/v4-migration.md

#### V4 Breaking changes:

`inferno-component` is removed. Inferno.Component (ES6) Class has been moved to `inferno` package.

`findDOMNode` has been moved to `inferno-compat`

string components now require `inferno-compat`

Default exports have been removed from all packages except `inferno-compat`. If you are getting exception for example:
cannot read `Inferno.createComponentVNode` make sure you have babel-plugin-inferno before babel module transformers in your `.babelrc` file.

Inferno packages are now using peerDependencies to external components to avoid duplicates

`module` entry has been added to package.json for all packages.

**NOTE:** module entry point (`"module": "index.mjs"`) targets to production build of Inferno. If you are doing development using Inferno you should use `dist/index.dev.js` - file or module entry point: `"dev:module": "dist/index.dev.mjs"`

`createVNode` cannot be used to create Component vNodes anymore. use `createComponentVNode(flags, type, props, key, ref)` instead.

VNodeFlags and ChildrenFlags have changed, see inferno-vnode-flags package for new flags.

There is no more "noNormalize" parameter for `createVNode` if you have been using it and you need to normalize children you need to pass `childFlags.UnknownChildren` as childFlags parameter.

example:
```javascript
import {createVNode, render} from 'inferno';
import {VNodeFlags, ChildFlags} from 'inferno-vnode-flags';

render(
    createVNode(
        VNodeFlags.HtmlElement,
        'div',
        'example-class'
        data, // unknown children
        ChildFlags.UnknownChildren // This tells inferno to normalize (data)
    ),
    document.getElementById('root')
);
```

inferno-compat users should install all dependencies they use themselves. For example:

```bash
npm install --save inferno
npm install --save inferno-compat
npm install --save inferno-clone-vnode
npm install --save inferno-create-class
npm install --save inferno-create-element
```

- Many JSX flags have changed, see babel-plugin-inferno README for more information


### Create Inferno App

It now uses `npx create-inferno-app your-app` to create new application

---

## File: documentation/v6-migration.md

#### V6 Breaking changes:

## Hydration, re-using SSR on client side

> Shortly:
>
> `hydrate` moved to `inferno-hydrate` package
>


Not all applications need server side rendering, so hydration functionality has been moved to `inferno-hydrate` package.
Inferno render will no longer try to re-use server side rendered HTML automatically.
If you want to hydrate (render existing html) you need to install `inferno-hydrate` package
and call hydrate on first render.

```jsx
import { render } from 'inferno';
import { hydrate } from 'inferno-hydrate';

// First time client is loaded, FE:

document.addEventListener('DOMContentLoaded', function(e) {
    const element = document.getElementById('app');

    hydrate(<App data={initialData} />, element);

    // Future updates should use render
    render(<App data={newData} />, element);
});
```

## Style property names changed

> Shortly:
>
> `backgroundColor` becomes `background-color`
>
> `top: 10` becomes `top: "10px"`
>

To support the latest style API inferno needs to set styles using `dom.style.setProperty()`.
This change adds support for inline CSS variables and if browser vendors add new parameters its easier to extend.

There used to be a list of hardcoded properties which Inferno detected and automatically added `px` suffix to, when value was numeric.
Inferno will no longer get between application input and setting style property. When you set `top: 1` you get ``

Unlike React, inferno has always supported setting styles using string. This API is now unified with object literal API.
It supports the same features and uses the same syntax.

```jsx

// equals

```

`inferno-compat` still uses the same old way and transpiles property names runtime to InfernoJS equivalents.
If you don't need camelCase styles you can disable this runtime using Inferno.options API.

```jsx
import {options} from 'inferno-compat';

// Disabling reactStyles uses native CSS syntax
options.reactStyles = false;
```

## JSX plugin requires Babel 7

To support JSX Fragment syntax, [babel-plugin-inferno](https://github.com/infernojs/babel-plugin-inferno) now depends on
[babel v7](https://babeljs.io/blog/2018/08/27/7.0.0).

## Lifecycle changes

`setState` lifecycle has been changed to be compatible with ReactJS flow.
Also `componentDidUpdate` will now trigger later in lifecycle chain, after refs have been creted.
See: https://github.com/infernojs/inferno/issues/1286


## Changes in VNode properties

#### `dom` not always populated

Supporting fragments complicates vNode structure and `dom` property is no longer populated
to Components or Fragments. There is [inferno-extras](https://github.com/infernojs/inferno/tree/master/packages/inferno-extras) package which contains helper functions to get DOM node.

```jsx
import { Component } from 'inferno';
import { findDOMNode } from 'inferno-extras';

class Example extends Component {

    componentDidMount() {
        // element equals "Okay"
        const element = findDOMNode(this);
    }

    render() {
        return Okay;
    }
}

```

#### `parentVNode` removed

There used to be reference to `parentVNode` from Component vNodes due to technical difficulties of changing Component roots.
This issue has been now resolved and `parentVNode` references have been removed.


#### single textVNodes are no longer inside another VNode

In Inferno v5 vNode elements that had text children had the following structure.
V6 adds new optimization paths for text children.

```jsx
const vNode = Hello

// children property now holds the string
vNode.children === 'Hello';
```

## Component properties removed

All Component properties which start with `$` are considered private and their behavior can change in minor versions.

- `$V` has been removed. no work around available.
- `$P` has been removed. use `findDOMNode(this).parentNode`


## Inferno-server

Inferno server no longer adds comment tags to separate single text children.
Make sure client and server use the same version SSR v6 needs client v6.

## Legacy String refs removed

Inferno no longer supports legacy string refs at all. They are not supported through `inferno-compat` either.
You can use callback refs, createRef API or forward Refs.

---

## File: documentation/v6-release.md

# InfernoJS v6.0.0

## Breaking changes

- `hydrate` moved to `inferno-hydrate` package
- Style properties use hyphen syntax `backgroundColor` => `background-color`
- JSX plugin depends on babel v7
- Lifecycle changed to have better compatibility with ReactJS
- String refs completely removed


For complete list see [Migration guide](https://github.com/infernojs/inferno/blob/master/documentation/v6-migration.md)

## New features

- Fragments, a new type of VNode that can be used to render Component root level arrays
- createRef API
- forwardRef API
- new Component lifecycle: `getDerivedStateFromProps` and `getSnapshotBeforeUpdate`
- `$HasTextChildren` new JSX compilation time optimization flag added
- rerender method
- top level context



### Fragments

Fragment support means you can return array from Component render creating an invisible layer that ties its content together
but will not render any container to actual DOM. The examples below need v6 [babel-plugin-inferno](https://github.com/infernojs/babel-plugin-inferno)

Short syntax example `<> ... </>`

```jsx
import { Component } from 'inferno';

class MyApplication extends Component {

    render() {

        /*
         * This will render "HiOkay"
         * to location where MyApplication is used
         * /
        return (
            <>
                Hi
                Okay
            </>
        )
    }
}

```

Long syntax allows you to specify keys for Fragments. This is useful if there are many Fragments or if array is built dynamically.

```jsx
import { Component, Fragment } from 'inferno';

class MyApplication extends Component {

    render() {

        const list = [];


        if (/* some logic */) {
            list.push(
                <Fragment key="coffee">
                    <dt>Coffee</dt>
                    <dd>Black hot drink</dd>
                </Fragment/>
            );
        }

        ...

        if (/* other logic */) {
            list.push(
                <Fragment key="milk">
                    <dt>Milk</dt>
                    <dd>White cold drink</dd>
                </Fragment/>
            );
        }

        /*
         * This will render
         * <dl>
         *    <dt>Coffee</dt>
         *    <dd>Black hot drink</dd>
         *    <dt>Milk</dt>
         *    <dd>White cold drink</dd>
         * </dl>
         * /
        return (
            <dl>
                {list}
            </dl>
        )
    }
}

```

You can create fragment:

- Using native Inferno API `createFragment(children: any, childFlags: ChildFlags, key?: string | number | null)`
- Using JSX `<> ... </>`, `<Fragment> .... </Fragment>` or ` ... `
- Using createElement API `createElement(Inferno.Fragment, {key: 'test'}, ...children)`
- Using hyperscript API `h(Inferno.Fragment, {key: 'test'}, children)`

React documentation: https://reactjs.org/docs/fragments.html

### CreateRef API

createRef method allows nicer syntax, and reduces code when no callback to DOM creation is needed.
The below example creates ref object and stores it to Component property `element`.
This object is then assigned to the element where you want to create reference. In the example below we want to reference "span".
After render has gone, span element is available in `this.element.current` property.


```jsx
import { Component, render, createRef } from 'inferno';

class Foobar extends Component {
  constructor(props) {
    super(props);

    // Store reference somewhere
    this.element = createRef(); // Returns object {current: null}
  }

  render() {
    return (
      
        
          Ok
        
      
    );
  }
}

render(<Foobar />, container);

```

React documentation: https://reactjs.org/docs/refs-and-the-dom.html


### ForwardRef API

forwardRef is a new mechanism to "forward" ref inside a functional Component.
It can be useful if you have simple functional Components and you want to create reference to a specific element inside it.

```jsx
import { forwardRef, Component, render } from 'inferno';

const FancyButton = forwardRef((props, ref) => (
  
    {props.children}
  
));

class Hello extends Component {
  render() {
    return (
      <FancyButton
        ref={btn => {
          if (btn) {
            // btn variable is the button rendered from FancyButton
          }
        }}
      >
        Click me!
      </FancyButton>
    );
  }
}

render(<Hello />, container);
```

React documentation: https://reactjs.org/docs/forwarding-refs.html

### New lifecycle

Like in React when new lifecycle methods `getDerivedStateFromProps` or `getSnapshotBeforeUpdate` are used old lifecycle methods will not be called ( `componentWillMount`, `componentWillReceiveProps` `componentWillUpdate` ).
There will not be `UNSAFE_` methods in Inferno. Just use the normal names.


### TextChildren

New optimization paths have been added for text. JSX users can force this optimization by adding `$HasTextChildren` tag to any vNode element.
This makes given element always render text. Normalization will also default into text children when only single text element is detected as children.

This flag also simplifies an old version of:
```
import { createTextVNode } from 'inferno';

// While this still works, this is not recommended anymore
{createTextVNode('text')}
```

New version:
```
// No imports needed
text
```


### rerender

rerender is a new method that will flush all pending setState calls and render immediately.
It can be used when render timing is important, or to simplify tests.

```jsx
import { Component, rerender, render } from 'inferno';

describe('test example', () => {
    it('Should update immediately', () => {
      class Foo extends Component {
        constructor(props, context) {
          super(props, context);

          this.state = {
            value: 'initial'
          };
        }

        componentDidMount() {
          this.setState({ value: 'updated' });
        }

        render() {
          return ;
        }
      }

      const container = document.createElement('div');

      render(<Foo />, container);
      expect(container.firstChild.className).toEqual('initial');

      // Call rerender to flush pending setState, no timeouts needed
      rerender();
      expect(container.firstChild.className).toEqual('updated');
    });
});
```

### Top level context

Inferno.render now takes fourth parameter which is initial context.
This removes the need of wrapping application with Class component.

```jsx
import { render } from 'inferno';

function App (props, context) {
    // context contains property "foo" => "bar"

    return Cool App!;
}


render(<App />, document.getElementById('root'), callback, { foo: 'bar' });
```

## Common

Runtime memory usage has been improved. `dom` properties are no longer stored to component vNode.
Various properties have been removed from ES6 Component as well. `parentVNode` hack has been removed removing circular
references from vNode tree. Normalization `array['$'] = true` hack has been removed.

### Core

- Better recovery from user land errors
- Fixes performance issue where normalization copied input data two times
- Fixes performance issue where frozen input data was always copied

### Typescript

- Adds support for pointer event types
- setState typings have been improved. https://github.com/infernojs/inferno/pull/1388

### Inferno-router

- Improved nested routes handling #1360
- `Route` component can now have multiple children

### Inferno-compat

- `options.reactStyles` option added, setting it false removes runtime transformation of style properties


List of Github issues can be found using this link: https://github.com/infernojs/inferno/issues?utf8=%E2%9C%93&q=label%3A%22Fixed+in+v6.0.0%22+

---

## File: documentation/v9-migration.md

# InfernoJS v9.0.0

## Breaking changes

`inferno-create-class` has been removed, use `createComponentVNode`, `createElement` APIs instead.
If you were using `createClass` to wrap the class into observable you can do the same by extending inferno component.

```js
observer(
  class MyCom extends Component {
    componentWillReact() {
      willReactCount++;
    }

    render() {
      return (
        
          {[foo.a.get(), foo.b.get(), foo.c.get()].join(',')}
        
      );
    }
  },
);
```

Inferno v9 requires following features to be present in the executing runtime:

- `Promise`
- `String.prototype.includes()`
- `String.prototype.startsWith()`
- `Array.prototype.includes()`
- `Object.spread()`

`options.componentComparator` has been removed
`options.renderComplete` has been removed, same result can be achieved by calling own function after render

## ES module bundle extension is now `.mjs`

`inferno.esnext.js` bundle has been removed and replaced with `inferno.mjs` bundle.
The following bundles have been renamed:

`inferno.esm.js` is now `inferno.mjs`

`inferno.dev.esm.js` is now `inferno.dev.mjs`

---

## File: packages/inferno-vnode-flags/README.md

# inferno-vnode-flags

Inferno VNode Flags is a small utility library for [Inferno](https://github.com/infernojs/inferno).

Usage of `inferno-vnode-flags` should be limited to assigning `VNodeFlags` and `ChildFlags` when using creating vNodes.

## Install

```
npm install --save inferno-vnode-flags
```

## Contents

**VNodeFlags:**

- `VNodeFlags.HtmlElement`
- `VNodeFlags.ComponentUnknown`
- `VNodeFlags.ComponentClass`
- `VNodeFlags.ComponentFunction`
- `VNodeFlags.Text`
- `VNodeFlags.SvgElement`
- `VNodeFlags.InputElement`
- `VNodeFlags.TextareaElement`
- `VNodeFlags.SelectElement`
- `VNodeFlags.Portal`
- `VNodeFlags.ReCreate` (JSX **$ReCreate**) always re-creates the vNode
- `VNodeFlags.ContentEditable`
- `VNodeFlags.Fragment`
- `VNodeFlags.InUse`
- `VnodeFlags.ForwardRef`
- `VNodeFlags.Normalized`

**VNodeFlags Masks:**

- `VNodeFlags.ForwardRefComponent` Functional component wrapped in forward ref
- `VNodeFlags.FormElement` - Is form element
- `VNodeFlags.Element` - Is vNode element
- `VNodeFlags.Component` - Is vNode Component
- `VNodeFlags.DOMRef` - Bit set when vNode holds DOM reference
- `VNodeFlags.InUseOrNormalized` - VNode is used somewhere else or came from normalization process
- `VNodeFlags.ClearInUseNormalized` - Opposite mask of InUse or Normalized

**ChildFlags**

- `ChildFlags.UnknownChildren` needs Normalization
- `ChildFlags.HasInvalidChildren` is invalid (null, undefined, false, true)
- `ChildFlags.HasVNodeChildren` (JSX **$HasVNodeChildren**) is single vNode (Element/Component)
- `ChildFlags.HasNonKeyedChildren` (JSX **$HasNonKeyedChildren**) is Array of vNodes non keyed (no nesting, no holes)
- `ChildFlags.HasKeyedChildren` (JSX **$HasKeyedChildren**) is Array of vNodes keyed (no nesting, no holes)
- `ChildFlags.HasTextChildren` (JSX **$HasTextChildren**) vNode contains only text

**ChildFlags Masks**

- `ChildFlags.MultipleChildren` Is Array

You can easily combine multiple flags, by using bitwise operators. A common use case is an element that has keyed children:

---

## File: packages/inferno-test-utils/README.md

# inferno-test-utils

> Suite of utilities for testing Inferno applications

## Install

```
npm install inferno --save
npm install inferno-test-utils --save-dev
```

## Contents

- [`findAllInRenderedTree`](#findallinrenderedtreerenderedtree-predicate)
- [`findAllInVNodeTree`](#findallinvnodetreevnodetree-predicate)
- [`scryRenderedDOMElementsWithClass`](#scryrendereddomelementswithclassrenderedtree-classnames)
- [`findRenderedDOMElementWithClass`](#findrendereddomelementwithclassrenderedtree-classnames)
- [`scryRenderedDOMElementsWithTag`](#scryrendereddomelementswithtagrenderedtree-tagname)
- [`findRenderedDOMElementWithTag`](#findrendereddomelementwithtagrenderedtree-tagname)
- [`scryRenderedVNodesWithType`](#scryrenderedvnodeswithtyperenderedtree-type)
- [`findRenderedVNodeWithType`](#findrenderedvnodewithtyperenderedtree-type)
- [`scryVNodesWithType`](#scryvnodeswithtypevnodetree-type)
- [`findVNodeWithType`](#findvnodewithtypevnodetree-type)
- [`isVNode`](#isvnodeinstance)
- [`isVNodeOfType`](#isvnodeoftypeinstance-type)
- [`isDOMVNode`](#isdomvnodeinstance)
- [`isDOMVNodeOfType`](#isdomvnodeoftypeinstance-type)
- [`isFunctionalVNode`](#isfunctionalvnodeinstance)
- [`isFunctionalVNodeOfType`](#isfunctionalvnodeoftypeinstance-type)
- [`isClassVNode`](#isclassvnodeinstance)
- [`isClassVNodeOfType`](#isclassvnodeoftypeinstance-type)
- [`isDOMElement`](#isdomelementinstance)
- [`isDOMElementOfType`](#isdomelementoftypeinstance-type)
- [`isRenderedClassComponent`](#isrenderedclasscomponentinstance)
- [`isRenderedClassComponentOfType`](#isrenderedclasscomponentoftypeinstance-type)
- [`renderIntoContainer`](#renderIntoContainervnodetree)

## Usage

### `renderIntoContainer(vNodeTree)`

Renders `vNodeTree` into a detached DOM element in the document and returns a rendered `VNode` tree.

_This function requires a DOM. JEST can provide this for you_.

```js
const vNodeTree = (
  
    <SomeComponent className="inner" />
  
);
const renderedTree = renderIntoContainer(vNodeTree);
```

### `findAllInRenderedTree(renderedTree, predicate)`

Calls `predicate` with each `VNode` instance in `renderedTree`.

Returns an array of `VNodes` where `predicate` returns `true`.

```js
const vNodeTree = (
  
    <SomeComponent className="inner" />
  
);
const renderedTree = render(vNodeTree, DOM);
const predicate = (vNode) => vNode.type === SomeComponent;
const result = findAllInRenderedTree(renderedTree, predicate);
```

### `findAllInVNodeTree(vNodeTree, predicate)`

Calls `predicate` with each `VNode` instance in `vNodeTree`.

Returns an array of `VNodes` where `predicate` returns `true`.

```js
const vNodeTree = (
  
    <SomeComponent className="inner" />
  
);
const predicate = (vNode) => vNode.type === SomeComponent;
const result = findAllInVNodeTree(vNodeTree, predicate);
```

### `scryRenderedDOMElementsWithClass(renderedTree, classNames)`

Returns an array of DOM elements with `classNames`.

`classNames` can be a space-separated string or an array of strings.

```js
const vNodeTree = (
  
    <SomeComponent className="inner one" />
    <SomeComponent className="inner two" />
  
);
const renderedTree = render(vNodeTree, DOM);
const result1 = scryRenderedDOMElementsWithClass(renderedTree, 'inner');
const result2 = scryRenderedDOMElementsWithClass(renderedTree, 'inner one');
const result3 = scryRenderedDOMElementsWithClass(renderedTree, [
  'inner',
  'two',
]);
const result4 = scryRenderedDOMElementsWithClass(renderedTree, 'three'); // Empty array
```

### `findRenderedDOMElementWithClass(renderedTree, classNames)`

Returns a single DOM element with `classNames`. If more than one matches are found, throws an error.

`classNames` can be a space-separated string or an array of strings.

```js
const vNodeTree = (
  
    <SomeComponent className="inner one" />
    <SomeComponent className="inner two" />
  
);
const renderedTree = render(vNodeTree, DOM);
const result1 = scryRenderedDOMElementsWithClass(renderedTree, 'outer');
const result2 = scryRenderedDOMElementsWithClass(renderedTree, 'inner one');
// Will throw an error because more than 1 matches were found...
const result3 = scryRenderedDOMElementsWithClass(renderedTree, 'inner');
```

### `scryRenderedDOMElementsWithTag(renderedTree, tagName)`

Returns an array of DOM elements with `tagName`.

```js
const vNodeTree = (
  
    <h1>Heading</h1>
    Paragraph One
    Paragraph Two
    Paragraph Three
  
);
const renderedTree = render(vNodeTree, DOM);
const result1 = scryRenderedDOMElementsWithTag(renderedTree, 'h1');
const result3 = scryRenderedDOMElementsWithTag(renderedTree, 'p');
const result4 = scryRenderedVNodesWithType(renderedTree, 'span'); // Empty array
```

### `findRenderedDOMElementWithTag(renderedTree, tagName)`

Returns a single DOM element with `tagName`. If more than one matches are found, throws an error.

```js
const vNodeTree = (
  
    <h1>Heading</h1>
    
      Paragraph One
      Paragraph Two
      Paragraph Three
    
  
);
const renderedTree = render(vNodeTree, DOM);
const result1 = findRenderedDOMElementWithTag(renderedTree, 'h1');
// Will throw an error because more than 1 matches were found...
const result2 = findRenderedDOMElementWithTag(renderedTree, 'p');
```

### `scryRenderedVNodesWithType(renderedTree, type)`

Returns an array of rendered `VNodes` with `type`.

```js
const vNodeTree = (
  
    <h1>Heading</h1>
    <SomeComponent />
    <SomeComponent />
  
);
const renderedTree = render(vNodeTree, DOM);
const result1 = scryRenderedVNodesWithType(renderedTree, 'h1');
const result2 = scryRenderedVNodesWithType(renderedTree, SomeComponent);
const result3 = scryRenderedVNodesWithType(renderedTree, 'p'); // Empty array
```

### `findRenderedVNodeWithType(renderedTree, type)`

Returns a single rendered `VNode` with `type`. If more than one matches are found, throws an error.

```js
const vNodeTree = (
  
    <h1>Heading</h1>
    Paragraph 1
    Paragraph 2
    <SomeComponent />
    <AnotherComponent />
    <AnotherComponent />
  
);
const renderedTree = render(vNodeTree, DOM);
const result1 = findRenderedVNodeWithType(renderedTree, 'h1');
const result2 = findRenderedVNodeWithType(renderedTree, SomeComponent);
// Will throw an error because more than 1 matches were found...
const result3 = findRenderedVNodeWithType(renderedTree, 'p');
const result4 = findRenderedVNodeWithType(renderedTree, AnotherComponent);
```

### `scryVNodesWithType(vNodeTree, type)`

Returns an array of `VNode` instances with `type`.

```js
const vNodeTree = (
  
    <h1>Heading</h1>
    <SomeComponent />
    <SomeComponent />
  
);
const result1 = scryVNodesWithType(vNodeTree, 'h1');
const result2 = scryVNodesWithType(vNodeTree, SomeComponent);
const result3 = scryVNodesWithType(vNodeTree, 'p'); // Empty array
```

### `findVNodeWithType(vNodeTree, type)`

Returns a single `VNode` instance with `type`. If more than one matches are found, throws an error.

```js
const vNodeTree = (
  
    <h1>Heading</h1>
    <SomeComponent />
    <SomeComponent />
  
);
const result1 = findVNodeWithType(vNodeTree, 'h1');
// Will throw an error because more than 1 matches were found...
const result2 = findVNodeWithType(vNodeTree, SomeComponent);
```

### `isVNode(instance)`

Returns `true` when `instance` is a `VNode`.

### `isVNodeOfType(instance, type)`

Returns `true` when `instance` is a `VNode` of `type`.

### `isDOMVNode(instance)`

Returns `true` when `instance` is a DOM-type `VNode`.

### `isDOMVNodeOfType(instance, type)`

Returns `true` when `instance` is a DOM-type `VNode` of `type`.

### `isFunctionalVNode(instance)`

Returns `true` when `instance` is a functional-type `VNode`.

### `isFunctionalVNodeOfType(instance, type)`

Returns `true` when `instance` is a functional-type `VNode` of `type`.

### `isClassVNode(instance)`

Returns `true` when `instance` is a class-type `VNode`.

### `isClassVNodeOfType(instance, type)`

Returns `true` when `instance` is a class-type `VNode` of `type`.

### `isDOMElement(instance)`

Returns `true` when `instance` is a DOM element.

### `isDOMElementOfType(instance, type)`

Returns `true` when `instance` is a DOM element of `type`.

### `isRenderedClassComponent(instance)`

Returns `true` when `instance` is a rendered class `VNode`.

### `isRenderedClassComponentOfType(instance, type)`

Returns `true` when `instance` is a rendered class `VNode` of `type`.

---

## File: packages/inferno-server/README.md

# inferno-server

> Inferno package for working with the server

This package serves as the entry point of the Server-related rendering paths. It is intended to be paired with the isomorphic Inferno, which will be shipped as inferno to npm.

## Install

```
npm install inferno inferno-server
```

## Contents

- renderToString
- RenderQueueStream
- RenderStream
- renderToStaticMarkup
- renderToString
- streamAsStaticMarkup
- streamAsString
- streamQueueAsStaticMarkup
- streamQueueAsString

## Usage

```js
import { renderToString } from 'inferno-server';

renderToString(Hello world, container);
```