:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

Overview

Inferno

Build Status Coverage Status MIT NPM npm downloads Discord gzip size Backers on Open Collective Sponsors on Open Collective lerna

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 plugin creates monomorphic createVNode calls, instead of createElement
  • 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 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 without any polyfills
  • defaultHooks for Functional components, this way re-defining lifecycle events per usage can be avoided
  • Inferno supports setting styles using string <div style="background-color: red"></div> or using object literal syntax <div style={{"background-color": "red"}}></div>. For camelCase syntax support see inferno-compat.
  • Fragments (v6)
  • createRef and forwardRef APIs (v6)
  • componentDidAppear and componentWillDisappear (v7.5.0) - class component callbacks to ease animation work, see inferno-animation package

Browser support

Since version 4 we have started running our test suite without any polyfills. Inferno is now part of Saucelabs open source program and we use their service for executing the tests.

InfernoJS natively supports the browsers listed below.

Build Status

Migration guides

Benchmarks

Live examples at https://infernojs.github.io/inferno

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 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 or createElement (like React does). Keep in mind that compile time optimizations are available only for JSX.

import { render } from 'inferno';

const message = "Hello world";

render(
  <MyComponent message={ message } />,
  document.getElementById("app")
);

Furthermore, Inferno also uses ES6 components like React:

import { render, Component } from 'inferno';

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

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 to predefine children shape compile time. Then we create text vNode using createTextVNode. All child flags are documented here.

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

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

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.

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:

Getting Started

The easiest way to get started with Inferno is by using Create Inferno App.

Alternatively, you can try any of the following:

Core package:

npm install --save inferno

Addons:

# 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:

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:

npm install --save-dev babel-plugin-inferno

Hyperscript:

npm install --save inferno-hyperscript

createElement:

npm install --save inferno-create-element

Compatibility with existing React apps

npm install --save-dev inferno-compat

Note: Make sure you read more about inferno-compat before using it.

Third-party state libraries

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

JSX

Inferno has its own JSX Babel plugin.

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.
  • Inferno is able to use the React Dev Tools extensions for Chrome/Firefox/etc to provide the same level of debugging experience to the Inferno user via inferno-devtools.

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.

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 <input> 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:

import { linkEvent } from 'inferno';

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

function MyComponent(props) {
  return <div><input type="text" onClick={ linkEvent(props, handleClick) } /><div>;
}

This is an example of using it with ES2015 classes:

import { linkEvent, Component } from 'inferno';

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

class MyComponent extends Component {
  render () {
    return <div><input type="text" onClick={ linkEvent(this, handleClick) } /><div>;
  }
}

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 <input>, <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)

import { render } from 'inferno';

render(<div />, 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 and Most.

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 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()

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:

import { Component } from 'inferno';

class MyComponent extends Component {
  render() {
    ...
  }
}

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

Functional component:

const MyComponent = ({ name, age }) => (
  <span>My name is: { name } and my age is: {age}</span>
);

Another way of using defaultHooks.

export function Static() {
    return <div>1</div>;
}

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

Default props


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

createVNode (package: inferno)

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 VNodes for Inferno, but under the hood they all use createVNode(). Below is an example of createVNode usage:

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);

// <div class="example">Hello world!</div>

render(vNode, container);

createVNode arguments explained:

flags: (number) is a value from VNodeFlags, 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, 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')

import { createComponentVNode } from 'inferno';

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

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

Example:

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!")
  }
})

// <div class="example">Hello Community!</div>

render(vNode, container);

createComponentVNode arguments explained:

flags: (number) is a value from VNodeFlags, 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.

import { createTextVNode } from 'inferno';

createTextVNode(
  text,
  key
)

cloneVNode (package: inferno-clone-vnode)

This package has same API as React.cloneElement

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:

<VNode.type {...VNode.props} {...props}>{children}</VNode.type>

An example of using cloneVNode:

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:

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

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

render(newVNode, container);

createPortal (package: 'inferno')

HTML:

<div id="root"></div>
<div id="outside"></div>

Javascript:

const { render, Component, version, createPortal } from 'inferno';

function Outsider(props) {
	return <div>{`Hello ${props.name}!`}</div>;
}

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

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


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

Results into:

<div id="root">
    <div>Main view ...</div>
</div>
<div id="outside">
    <div>Hello Inferno!</div>
</div>

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!

createRef (package: inferno)

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

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 (
      <div>
        <span id="span" ref={this.element}>
          Ok
        </span>
      </div>
    );
  }
}

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, 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 <Inferno.Fragment> ... </Inferno.Fragment>
  • 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

import { Fragment, render, createFragment } from 'inferno';
import { ChildFlags } from 'inferno-vnode-flags';

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

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.

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

const FancyButton = forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

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)

import { hydrate } from 'inferno-hydrate';

hydrate(<div />, 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.

options.componentComparator ( package inferno) DEV only

This option can be used during development to create custom component comparator method. This option will be called on every Component update. It gets two parameters: lastVNode and nextVNode. When it returns true lastVNode will be replaced with nextVNode. If anything else than true is returned it falls to normal behavior.

import {options} from 'inferno';

options.componentComparator = function (lastVNode, nextVNode) {
    /* custom logic */
    return true; // Replaces lastVNode with nextVNode
}

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.Void
  • 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)

import { renderToString } from 'inferno-server';

const string = renderToString(<div />);

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

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

Using functional lifecycle events

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

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 <div>Hello world</div>;
}

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.

Building Inferno for use in a browser

When running Inferno on the browser using Webpack or Rollup, a replacement will need to occur during your build.

Webpack

Use the following configuration in your Webpack build for production build:

  ...
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    })
  ]

When you are building for development, you may want to use inferno.dev.esm.js ("dev:module": "dist/index.dev.esm.js",) file. That build version has extra level of validation for development purposes. You can use it by adding following code to your webpack config.

    ...
	resolve: {
    /* When doing development workflow we want to make sure webpack picks up development build of inferno */
		alias: {
			inferno: __dirname + "/node_modules/inferno/dist/index.dev.esm.js"
		}
	}

Rollup

Use the following configuration in your Rollup build:

const replace = require('rollup-plugin-replace');
  ...
  plugins: [
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
    })
  ]

When you are building for development, you may want to use inferno.dev.esm.js ("dev:module": "dist/index.dev.esm.js",) file. That build version has extra level of validation for development purposes. You can use it by adding following code to your rollup config.

const alias = require('@rollup/plugin-alias');

    ...
  plugins: [
    alias({
        resolve: ['.js'],
        entries: [
          {find: 'inferno', replacement: __dirname + '/node_modules/inferno/dist/index.dev.esm.js'}
        ]
    }),
  ]

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.

$ git clone [email protected]:infernojs/inferno.git
$ cd inferno && npm i
$ npm run test:node
$ npm run build
$ npm run test:browser

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

$ npm run quick-test:browser # Compiles all packages and runs browser tests
$ npm run quick-test:browser-inferno # Only compiles the inferno package and runs browser tests
$ npm 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/AW92rGbJ.

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! πŸ™ [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

Comments
  • Inferno 3.5.0 and controlled checkboxes and radio

    Inferno 3.5.0 and controlled checkboxes and radio

    Controlled inputs like type='checkbox' or type='radio' generate the onClick events but do not fire onChange events. This is my fault also, I checked the onClick only in https://github.com/AlgoTrader/inferno-controls.

    bug to verify 
    opened by AlgoTrader 54
  • styled-components not work even with inferno-compat?

    styled-components not work even with inferno-compat?

    I'm using inferno-compat, last version, with styled-component and it just not render anything (with any error on console)... Did you know about this? if yes, there is any plan to make it compatible?

    I started to port my app to inferno today, so I just has no ideia if this is a bug or something already expected...

    thanks!

    opened by maxguzenski 52
  • Rendering fragments

    Rendering fragments

    Or in other words, support for components to render multiple children:

    const Component = () => [<Child1 />, <Child2 />];
    

    It was said on slack it's a wanted feature with intention to be implement in future, so I'm creating this issue to have a place to track the progress.

    Someone mentioned that it was already once in Inferno, but at the cost of performance, so it was dropped until a faster implementation is discovered. Was the performance hit really that bad? Because I'd gladly take it if it means the ability to render fragments. Inferno is one of the fastest frameworks out there, so it definitely doesn't lack the perf budget.

    I consider this to be an essential feature to not have DOM polluted with useless wrapper elements which just get in the way of developing, maintaining, and styling components. And React already supports this in their Fiber rewrite, which is mostly done.

    enhancement feature request Fixed in v6.0.0 
    opened by darsain 47
  • New Inferno site design suggestions/mockups

    New Inferno site design suggestions/mockups

    Let's use this thread to aggregate a collection of ideas/notes and mockups for the new InfernoJS website. If you have a design you're working on submit it here for consideration.

    opened by davedbase 47
  • Make compatible with Material-UI

    Make compatible with Material-UI

    Slick material design without bloat vdom library == Material-UI + InfernoJS.

    But:

    ERROR in ./~/react-addons-create-fragment/index.js
    Module not found: Error: Cannot resolve module 'inferno-compat/lib/ReactFragment' in node_modules\react-addons-create-fragment
     @ ./~/react-addons-create-fragment/index.js 1:17-51
    
    ERROR in ./~/react-addons-transition-group/index.js
    Module not found: Error: Cannot resolve module 'inferno-compat/lib/ReactTransitionGroup' in node_modules\react-addons-transition-group
     @ ./~/react-addons-transition-group/index.js 1:17-58
    

    Give me a fix or a workaround.

    enhancement 
    opened by cia48621793 39
  • Convert 1.0 codebase to TypeScript

    Convert 1.0 codebase to TypeScript

    Currently the 1.0 codebase lives on the dev branch. It'll gradually be completely converted over to TS – with a keen eye on not reducing any regressions to performance. I'll need community help here (in form of PRs) to help get it all converted.

    Currently the build works fine – it handles the mix of js and ts files and also accounts for the fact that our tests need to use babel for the babel-plugin-inferno to compile JSX code. I'm struggling currently to get all this working properly – npm run test and npm run browser both fail.

    Furthermore, Inferno is using the latest typescript@rc for those wondering.

    @Schnueggel any help here would be awesome :)

    enhancement 
    opened by trueadm 36
  • patchComponent: Cannot read property '_unmounted' of null

    patchComponent: Cannot read property '_unmounted' of null

    Observed Behaviour

    Inferno is throwing and uncaught exception Cannot read property '_unmounted' of null. It is happening inside patchComponent when lastVNode.children is null. It is throwing because instance._unmounted is null to be more specific.

    https://github.com/infernojs/inferno/blob/8a605aba148136678f1e7689064b1deb535ac1a5/packages/inferno/src/DOM/patching.ts#L289

    Expected Current Behaviour

    Inferno should not throw an uncaught exception, but should handle null as children appropriately.

    Inferno Metadata

    Using inferno/inferno-compat v1.3.0-rc.8

    macOS / Chrome

    bug help wanted 
    opened by kanzelm3 35
  • Improve the VNode normalization process

    Improve the VNode normalization process

    Background

    Unlike React, Inferno's VNodes are not immutable. They are handled like pseudo-immutable objects in that if multiple instances are detected within Inferno, it attempts to clone the VNode. Inferno does this to reduce object creation and to improve performance (the dom property on VNodes constantly get updated as the mount/patch/unmount process happens during run-time).

    What we currently do

    https://github.com/trueadm/inferno/blob/master/src/core/shapes.ts#L163

    Inferno currently implements a normalization process when you call createVNode. createVNode is the main entry point into creating virtual DOM for Inferno, as such, slowing down this function can have an impact on overall app performance.

    Below explains what the normalization process currently does and what it deals with:

    1. normalizeElement if the type property is a string, but the flags pass through says "Component", Inferno tries to correctly change this a type of "Element". This is done because JSX passes over "Component" when the JSX Element starts with an uppercase name (it assumes all uppercase names are components).

    2. normalizeProps - if the props contains ref, events, children or key, usually because the VNode was created using JSX spread props, we need to put these values back onto the root of the VNode.

    3. normalizeChildren - if the VNode has children, we need to do a bunch of things here (this is generally where the performance impact comes from)

      • we need to assign a property to the children if the children is an array, in this case we assign a property $ directly to the array and set it to true. We use this to know if we've seen this array before. As Inferno's VNodes are not immutable and we use them in the mount/diffing/unmounting, we need to make sure if someone has hoisted the children array, we clone it via children.splice() so we don't mutate the same object.
      • we loop through all children, detecting if we need to flatten children (where there is an array in the children), we check if there is a string or number and convert that to a VNode and if we find a child that has dom already set, we assume it's hoisted and clone it. We do this recursively for all children within children – unless the original children does not need any changes, then we simply return the original children.
      • we do not strip invalid entries from the children or assign pseudo keys to non keyed children (like React does) based on the position of the child in the array. This means that our keyed update process is extremely fragile (see #562).

    Step 3 is causing some issues on performance. It feels like there must be a way to avoid doing this expensive cost if possible. Currently we can avoid normalization in benchmarks by specifying noNormalize via JSX or as a parameter of createVNode which takes away this cost.

    What can we do?

    We need to somehow remove normalisation. If we need to keep it, can we get away with doing it "just in time" during mounting/patching/unmounting to remove this performance loss? It's having an impact on SSR rendering where there is no DOM. It's also having an impact on animations with lots of children that have frequent updates occurring. Yes we can bypass normalization using the flag, but ideally we want to remove this altogether and have a streamlined approach. People using JSX aren't going to know how to use it properly anyway (without breaking their app).

    Any ideas on how we might improve this whilst being able to still handle mixed key children and hoisting of VNodes?

    @localvoid @thysultan @Havunen

    enhancement 
    opened by trueadm 32
  • What is the roadmap ?

    What is the roadmap ?

    Hi, @trueadm

    Seems great this project, but comparing to the readme. A couple of missing pieces?

    • createElement(). Is this something coming soon? I think that will give you even more stars. I was looking into the code, and shouldn't be too hard to copy from your very great t7 script? Or maybe I'm wrong.
    • different things seems unfinished inside the code, any plans for finishing this?
    • any plans for hooks ala Snabbdom? Not lifecycle, but example when you create a fragment, you can trigger a callback, same when you remove or update a fragment.
    • Server side rendring, is this going to happen soon? It's more or lest a must have if I should convert to Inferno. I'm from React world!

    Btw. Is there any benchmark for latest version, and what is the roadmap?

    I will absolutly start to use this script soon as a createElement() are done. And I like your component part too :+1:

    opened by ghost 31
  • Port React-Redux v5

    Port React-Redux v5

    This is an initial commit for react-redux. All the code is ported except for the tests. tslint crashes on my computer in the inferno repository, so I am having problems running tests in any good way.

    opened by Alxandr 30
  • Touch events not supported?

    Touch events not supported?

    I am migrating a code like this from a React codebase:

    <div
    className="discover-slider"
    onTouchStart={this.onTouchStart}
    onTouchMove={this.onTouchMove}
    onTouchEnd={this.onTouchEnd}
    >
    ...
    </div>
    

    Those events are working on React but they are not being fired in Inferno. Am I doing something wrong? I think it is just not supported right now. Ideas?

    Thanks a lot for all your support guys!

    bug feature request 
    opened by hguillermo 28
  • Feature support for async prefetch in inferno-router

    Feature support for async prefetch in inferno-router

    All tests are passing for me.

    This PR adds a property loader to <Route> which will be resolved prior to performing a navigation. This allows data to be fetched from an API and the result sent to the rendered component. The behaviour mimics the loader behaviour of React Router v6.

     <Route path="/" loader={async () => {} }
    

    For SSR you can run await resolveLoaders(...) on your initial application and get the results of all the invoked loaders for a given location. This can then be passed to a <StaticRouter loaderData={...} > for server side rendering and then used during rehydration in the browser by passing the same data to <BrowserRouter loaderData={...} >.

    This will greatly simplify SSR with Inferno which currently requires both patience and guts.

    I have added some helper methods to abstract access to data in a way that looks familiar to those who are accustomed to the hooks of react-router v6. This has the benefit of allowing us to change implementation details without breaking applications.

    Reference: https://reactrouter.com/en/main/route/loader

    opened by jhsware 11
  • Add implementation type aliases to make types safe application development easier

    Add implementation type aliases to make types safe application development easier

    We have a very, very rich set of types in Inferno and many types have similar names. This can make it hard to pick an appropriate type in application code.

    It would be great if we could create a limited set of type aliases with intuitive names that can be used by application developers.

    Use case:

    • You want to create a look up dictionary with different components that are resolved at runtime to render a list of various items

    What is the correct type for the the component? Is it:

    • IComponent<any, any> | Function
    • Component | Function
    • Component<any> | Inferno.StatelessComponent<any>
    • ComponentType

    So a type alias could be:

    // Require a Function or Class Component where P is a required set of properties
    export type InfernoComponent<P = any> = Component<P> | Inferno.StatelessComponent<P>;
    

    This would save time, encourage type safety and make application code more readable.

    opened by jhsware 1
  • Investigate changes to react-router v5-branch

    Investigate changes to react-router v5-branch

    The v5 branch of react-router has been updated after the initial inferno-router port. These should be ported to inferno-router to keep it compatible with the docs. Also, these are probably useful features.

    Go through the list of commits and check which ones add functionality that are relevant to inferno-router:

    https://github.com/remix-run/react-router/commits/v5

    NOTE: A lot of the commits are just maintenance of the project or docs so I don't think it will be too much work.

    opened by jhsware 0
  • inferno-server docs

    inferno-server docs

    packages/inferno-server/readme.md contains a list of contents, renderToString is repeated. renderToString is the only one function that is documented. Please indicate which functions are available on each different platform.

    documentation 
    opened by Coachonko 0
  • inferno-mobx observer is incompatible with certain life cycle hooks

    inferno-mobx observer is incompatible with certain life cycle hooks

    Preface

    The issue comes from the fact that if class Components implement at least one of the getSnapshotBeforeUpdate or the getDerivedStateFromProps life cycle hook then the componentWillMount, componentWillReceiveProps, and componentWillUpdate hooks will be ignored.

    Which by the way this behavior is not mentioned in the documentation on class Components.

    For inferno-mobx's observer function, it uses the componentWillMount hook to set up the reactive re-rendering of the Component.

    The componentWillMount hook is normally called in createClassComponentInstance function from packages/inferno/src/DOM/utils/componentUtil.ts. But if getSnapshotBeforeUpdate or getDerivedStateFromProps are present then componentWillMount is not called.

    Observed Behaviour

    If a class Component that implements getSnapshotBeforeUpdate or getDerivedStateFromProps and is passed to inferno-mobx's observer function will not update in response to changes in the mobx observables it depends on.

    If getSnapshotBeforeUpdate and getDerivedStateFromProps are removed then things work as expected.

    Expected Current Behaviour

    A class Component passed to inferno-mobx's observer function should update in response to changes in the mobx observables it depends on regardless of which life cycle hooks it does or does not implement.

    How to Fix

    The best way (in the context of how inferno currently works) to make inferno-mobx's observer function work for class Components implementing getSnapshotBeforeUpdate or getDerivedStateFromProps is to initialize the mobx reaction on the first call of the render function. The componentDidMount could also be used, but would require forcing an update as it is called after the first use of the Component's render method. Initializing the first time render is called avoids this.

    There is one part of the componentDidMount created by inferno-mobx that may not transfer well is turning the props and state properties of the Component into mobx atoms. This is technically an unneeded step for making a Component react to changes in mobx observables. It is only needed if the value of those properties will be directly changed by user code. If props is only set by inferno and state is changed with setState (or updated when getDerivedStateFromProps is called) then the component would already be re-rendered when appropriate.

    If that aspect of inferno-mobx cannot be moved into an override of render, then to maintain backwards compatibility the observer function will need to check for getSnapshotBeforeUpdate and getDerivedStateFromProps and then override either componentDidMount or render as appropriate.

    opened by Gwenio 3
Releases(v8.0.5)
  • v8.0.5(Nov 27, 2022)

    Typescript

    • Typescript typing improvements https://github.com/infernojs/inferno/pull/1612

    Inferno router

    • Fixes an issue where state was no longer passed to history https://github.com/infernojs/inferno/issues/1608 https://github.com/infernojs/inferno/commit/e3c3debff225c3ec0cb25f5ebb650d31298a24a8
    • Implements className function to be compatible with React router https://github.com/infernojs/inferno/pull/1613
    Source code(tar.gz)
    Source code(zip)
  • v8.0.4(Oct 16, 2022)

    Typescript

    • Adds type information for Animation hooks https://github.com/infernojs/inferno/commit/77acc73ff5da0bb46bc594b3117b21af693e505f
    • AnimatedMoveComponent, PureComponent and Component are now abstract classes to indicate they must be extended
    • All attributes now accept null value https://github.com/infernojs/inferno/commit/eb881221b4f2093e5ae53dcad4240cc0183b8675
    • Refs now accept null value https://github.com/infernojs/inferno/commit/12be729eade0a9a4ed43a548a0f9d3b9064fdfa6

    Internal

    • Dependencies updated to latest versions
    • Rollup plugin bubble replaced with babel
    Source code(tar.gz)
    Source code(zip)
  • v8.0.3(Aug 18, 2022)

    Inferno-core

    • Added funding note to package.json https://github.com/infernojs/inferno/commit/7f76923b83e39016d4faa2ad0ce740c8b9635f1b
    • Improved documentation about bundling inferno application https://github.com/infernojs/inferno#application-bundling https://github.com/infernojs/inferno/commit/de56ad694c26c20e08375b2116aa9a0ee77fd7f7

    Typescript

    • Added back types for CssProperties, correctly typed with hyphen case, fixes https://github.com/infernojs/inferno/issues/1604

    Dependencies

    • inferno-shared moved to devDependencies in all packages https://github.com/infernojs/inferno/commit/231d7176d0e9699e1a5b7613dd9d6e712e7bf152
    Source code(tar.gz)
    Source code(zip)
  • v8.0.2(Aug 2, 2022)

    Typescript

    • Reverted Component state from read-only to mutable object
    • inferno-router typings improved
    • type IComponentConstructor removed it was not needed for anything
    Source code(tar.gz)
    Source code(zip)
  • v8.0.1(Jun 19, 2022)

    Typescript

    • Fixes an issue where mixing React and Inferno in same application failed to resolve JSX Component type https://github.com/infernojs/inferno/issues/1599 https://github.com/infernojs/inferno/commit/5192eef02bc8e7775da573cac5f11f0e348ae7bc
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0(Jun 17, 2022)

    Inferno

    • Added new Component lifecycle methods componentWillMove, componentDidAppear and componentWillDisappear
    • Added a warning when rendering links with javascript: URLs https://github.com/infernojs/inferno/commit/7bc376300cea89de28e1368c3dcdf25e4ba4e2c0
    • Inferno now uses String.prototype.substring instead of deprecated String.prototype.substr https://github.com/infernojs/inferno/commit/06195ad0c8bf965ba16b4a42f67f836abc8896ab https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr
    • Removed development bundle warning when Inferno is used in Jest test environment https://github.com/infernojs/inferno/commit/5c017e189c67875516145f3efb56b0a8e6d124f3

    Typescript

    • Added basic support for JSX Component default props https://github.com/infernojs/inferno/commit/696006c3d817fc4f0af45d422eb78ad6deeb1caa
    • Added missing optimization flag https://github.com/infernojs/inferno/pull/1595

    Inferno-animation

    • inferno-animation is a new package that eases animation work using inferno v8 componentDidAppear and componentWillDisappear hooks to coordinate animations and reduce number of repaints browsers have to do https://github.com/infernojs/inferno/tree/master/packages/inferno-animation https://github.com/infernojs/inferno/pull/1583

    Special thanks for improving inferno animations to @jhsware

    Inferno-router

    • history package has been updated to version 5

    Inferno-mobx

    • Document details about server side rendering for inferno-mobx https://github.com/infernojs/inferno/commit/d0ed1ca70ef4f81491c037f5a001d86833657a74
    • Forward exceptions thrown by render so MobX does not eat them https://github.com/infernojs/inferno/commit/0165ff0b2067a8c94b71e9bc04fce1b571324ee8
    • inferno-mobx observer now correctly throws an exception for incompatible components https://github.com/infernojs/inferno/commit/2da4cb66ba2c07a5e3361d360a297feeda3ba201
    • Clean up new inferno-mobx examples https://github.com/infernojs/inferno/commit/779f04fd14de3054cd0dcb8610d16b87876b2240
    • Added observerPatch to inferno-mobx https://github.com/infernojs/inferno/commit/8b6750fa4143ea9d7283e157daa5ecf719361246

    Special thanks for improving inferno-mobx to @Gwenio

    Build system and internal changes

    • Inferno build system has been improved and is now 13 times faster thanks to @jhsware https://github.com/infernojs/inferno/pull/1558
    • Development dependencies have been updated
    • Inferno build scripts have been converted to ESM syntax https://github.com/infernojs/inferno/commit/614a1d2b48ccf7633800245beeaebca5d228b1f5
    • Removed color.js and colored output from build, because its maintainer created infinite loop on purpose https://github.com/infernojs/inferno/commit/320be7db7541aca2adaddf7c0e603c6ad04b8375 https://github.com/advisories/GHSA-gh88-3pxp-6fm8
    • Removed rollup-plugin-typescript2 https://github.com/infernojs/inferno/commit/4e36aa7fbbbe991e2a61bb4034ae98fa09960e26
    • Sinon.Js has been removed https://github.com/infernojs/inferno/commit/0abcc9fc96c5737422f08ae091dd97e67eb618f1
    • Benchmarks and Examples have been merged https://github.com/infernojs/inferno/pull/1554 https://infernojs.github.io/inferno/

    Breaking changes

    • VNodeFlags.Void has been removed https://github.com/infernojs/inferno/commit/c658a41266e97e1a33d65f536c705cc70f5bd997, use null or undefined vNode instead
    • Internet Explorer is not actively tested anymore due to Internet Explorer retiring on June 15, 2022 and jasmine v4 has dropped IE support https://github.com/jasmine/jasmine/blob/main/release_notes/4.0.0.md
    • inferno-component package has been removed. Component is available in "inferno" main package
    • inferno-devtools is discontinued https://github.com/infernojs/inferno/commit/537cb2d343744aa9c81f57a27300c0fa7788ee88
    • method findDOMfromVNode is now called findDOMFromVNode
    • method isDOMinsideComponent is now called isDOMInsideComponent
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.6(May 24, 2022)

    inferno

    • Fixes performance regression in patch method https://github.com/infernojs/inferno/commit/9dcc1984ec7cbf5c929d006ce250821f99e66512
    • Fixes performance regression in unmounting logic https://github.com/infernojs/inferno/commit/1170cea51dddfee16bfe68b06ee759ada491cd27
    • Small performance optimization to moveVNodeDOM method https://github.com/infernojs/inferno/commit/7b66a2d4e7b8b9a45daa886126fd39327bae74cb

    Breaking change

    • inferno-devtools is discontinued https://github.com/infernojs/inferno/commit/537cb2d343744aa9c81f57a27300c0fa7788ee88
    • method findDOMfromVNode is now called findDOMFromVNode
    • method isDOMinsideComponent is now called isDOMInsideComponent
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.3(Nov 24, 2021)

    Inferno

    • Removes development bundle warning when infernojs is used in Jest test environment https://github.com/infernojs/inferno/commit/5c017e189c67875516145f3efb56b0a8e6d124f3
    • Fixes an issue where context becomes null when fragment is used to render single vNode https://github.com/infernojs/inferno/commit/ef07f26bbca0359e61c302f8c566bfb98da07724

    Inferno-animations

    • New feature global animations https://github.com/infernojs/inferno/commit/776b607573445a8891d8c9a11dee2e2ca791a0c2
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.2(Nov 3, 2021)

  • v7.4.11(Nov 3, 2021)

    • Fixes an issue where top level context becomes null if Fragment was rendered having single child node https://github.com/infernojs/inferno/issues/1579
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.1(Oct 25, 2021)

    • inferno-component package has been removed. Component is available in "inferno" main package
    • inferno-animation clean up and performance bug fixes: https://github.com/infernojs/inferno/pull/1575 https://github.com/infernojs/inferno/pull/1576
    • internal dependencies updated
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.0(Sep 22, 2021)

    New package inferno-animation has been added

    Inferno-router

    "history" package has been updated to the latest major version 5

    Multiple internal changes to build system and dependencies

    Note

    This is preview release available for testing and there might be breaking changes in future releases

    Source code(tar.gz)
    Source code(zip)
  • v7.4.10(Sep 11, 2021)

    All packages

    This release fixes a possible supply chain attack by adding repository link to all packages https://github.com/infernojs/inferno/pull/1574

    Source code(tar.gz)
    Source code(zip)
  • v7.4.9(Aug 21, 2021)

    Inferno-core

    • Adds typing support for lazy loading images https://github.com/infernojs/inferno/commit/e34e287d60855e750b002140660e7ef72d6c4204
    • Fixes an issue where normalizeProps overrides explicitly defined class name property https://github.com/infernojs/inferno/commit/592e065d3ed19d86e642004d9cea47089b908738

    Inferno-router

    • Adds typing support for title and other html element attributes to Link component https://github.com/infernojs/inferno/commit/6480b05709c32f5b249e9807b3a7da24e53e7fe2
    Source code(tar.gz)
    Source code(zip)
  • v7.4.8(Feb 14, 2021)

    Inferno core

    Fixes an issue where shouldComponentUpdate gets called after forceUpdate if there were pending state changes on the given component https://github.com/infernojs/inferno/issues/1534 https://github.com/infernojs/inferno/pull/1535 Inernal dependencies updated

    Source code(tar.gz)
    Source code(zip)
  • v7.4.7(Jan 13, 2021)

    Inferno-core

    This release fixes wrong "latest" tag in npm registry after v5 hotfix Internal dependencies updated https://github.com/infernojs/inferno/commit/90e2daadf059f00e2ea8ea35a38efe00d037491e License year updated https://github.com/infernojs/inferno/commit/1f06cdd90bf6bdc63eb7e72c1ea7e4086d12f2d7

    Source code(tar.gz)
    Source code(zip)
  • v5.6.2(Jan 13, 2021)

    Inferno Core

    This is patch inferno v5x versions to change opencollective dependency to opencollective postinstall. Closes https://github.com/infernojs/inferno/issues/1532 original change backported: https://github.com/infernojs/inferno/commit/0ea17d05dcded3aa187065ea852ce68f6f6c14ac

    Source code(tar.gz)
    Source code(zip)
  • v7.4.6(Oct 22, 2020)

  • v7.4.5(Sep 19, 2020)

    Inferno-core

    Improved createRef() type

    Inferno-server

    Fixes a bug where rendering forwardRef component server side failed to exception. https://github.com/infernojs/inferno/issues/1523

    Source code(tar.gz)
    Source code(zip)
  • v7.4.4(Sep 19, 2020)

    Inferno-router

    Navlink component typescript typings have been improved and it does not require all properties to be set anymore. This fixes Github issue https://github.com/infernojs/inferno/issues/1518

    Internal dependencies were updated

    Source code(tar.gz)
    Source code(zip)
  • v7.4.3(Aug 21, 2020)

    Inferno core

    Optimized rendering functional component https://github.com/infernojs/inferno/commit/1af165f3875d8ccca20def1ee7835012508d3616 Optimized cloneFragment method https://github.com/infernojs/inferno/commit/85eba1228411bcb572f0382d84a7f39cc23689c2

    Internal development dependencies have been upgraded

    Source code(tar.gz)
    Source code(zip)
  • v7.4.2(Mar 2, 2020)

    Inferno core

    Fixes an issue introduced in v7.4.1 where setState callback was called even if component got unmounted https://github.com/infernojs/inferno/commit/0e6b2438bac4539a97c4debe97cbda8c07703b28

    Source code(tar.gz)
    Source code(zip)
  • v7.4.1(Feb 25, 2020)

    Inferno core

    Fixes an issue where all setState callbacks were not called after chaining multiple setStates during asynchronous flow

    Inferno router

    Fixes typings of IRouteProps component https://github.com/infernojs/inferno/commit/078b323b0c63f5fc40d9a3bc0aaedc7a24031880

    Source code(tar.gz)
    Source code(zip)
  • v7.4.0(Jan 28, 2020)

    Inferno-server

    • Adds support for rendering array from Component root. https://github.com/infernojs/inferno/commit/9396adea5b86849a8afd28bb150ae46a78327cff

    Inferno-compat

    • Removed always truthy conditions from Children methods https://github.com/infernojs/inferno/commit/fb9d5febddb0c8a0cef97c58c681d2dcdf50baa2
    Source code(tar.gz)
    Source code(zip)
  • v7.3.3(Nov 19, 2019)

  • v7.3.2(Oct 8, 2019)

  • v7.3.1(Aug 22, 2019)

    Inferno-hydration

    • Fixes an issue where hydrating forwardRef Component crashed https://github.com/infernojs/inferno/issues/1486 https://github.com/infernojs/inferno/commit/646753c70c87c3a425bea100126a35aef25751da
    Source code(tar.gz)
    Source code(zip)
  • v7.3.0(Aug 13, 2019)

    Inferno-core

    • Adds root level array support to createPortal
    • Synthetic events are now propagated from shadow-dom https://github.com/infernojs/inferno/issues/1430 This requires browser to support shadow-dom https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM
    • Code clean up
    Source code(tar.gz)
    Source code(zip)
  • v7.2.1(Jul 25, 2019)

    Inferno-core

    • Fixes an issue caused by Release 7.2.0 where events were not updated correctly https://github.com/infernojs/inferno/commit/be677f9a3d096a44b8116581211ccb2e8de8518c
    • Simplified and optimized Synthetic event patch routines
    Source code(tar.gz)
    Source code(zip)
  • v7.2.0(Jul 24, 2019)

    Inferno-core

    • Adds support for defaultHooks when using forwardRef functional components
    • Fixes performance regression between 7.0.2 and 7.1.13

    General

    • All dependencies updated
    • UglifyJS has been replaced with TerserJS
    Source code(tar.gz)
    Source code(zip)
A declarative, efficient, and flexible JavaScript library for building user interfaces.

Solid is a declarative JavaScript library for creating user interfaces. It does not use a Virtual DOM. Instead it opts to compile its templates down t

Ryan Carniato 24.5k Jan 4, 2023
πŸŒ™ The minimal & fast library for functional user interfaces

Moon The minimal & fast library for functional user interfaces Summary ?? Small file size (2kb minified + gzip) ⚑ Blazing fast view rendering ?? Purel

Kabir Shah 6k Jan 2, 2023
Tiny (2 KB) turboboosted JavaScript library for creating user interfaces.

Develop web applications with 100% JavaScript and web standards. ?? RE:DOM is a tiny (2 KB) UI library by Juha Lindstedt and contributors, which adds

RE:DOM 3.2k Jan 3, 2023
βš›οΈ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

Fast 3kB alternative to React with the same modern API. All the power of Virtual DOM components, without the overhead: Familiar React API & patterns:

Preact 33.6k Jan 8, 2023
A Web Component compiler for building fast, reusable UI components and static site generated Progressive Web Apps

Stencil: A Compiler for Web Components and PWAs npm init stencil Stencil is a simple compiler for generating Web Components and static site generated

Ionic 11.3k Jan 4, 2023
A blazing fast React alternative, compatible with IE8 and React 16.

Nerv is a virtual-dom based JavaScript (TypeScript) library with identical React 16 API, which offers much higher performance, tinier package size and

null 5.4k Jan 4, 2023
Relay is a JavaScript framework for building data-driven React applications.

Relay Β· Relay is a JavaScript framework for building data-driven React applications. Declarative: Never again communicate with your data store using a

Facebook 17.5k Jan 1, 2023
jCore - JavaScript library for building UI components

JavaScript library for building UI components

iOnStage 11 Jan 21, 2022
🐰 Rax is a progressive React framework for building universal application. https://rax.js.org

Rax is a progressive React framework for building universal applications. ?? Write Once, Run Anywhere: write one codebase, run with Web, Weex, Node.js

Alibaba 7.8k Dec 31, 2022
A JavaScript UI Library with JQuery like syntax

A JavaScript UI Library with JQuery like syntax. (Beta)

Sijey 5 Jan 16, 2022
πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

Supporting Vue.js Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome ba

vuejs 201.6k Jan 7, 2023
πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

vue-next This is the repository for Vue 3.0. Quickstart Via CDN: <script src="https://unpkg.com/vue@next"></script> In-browser playground on Codepen S

vuejs 34.6k Jan 4, 2023
A JavaScript Framework for Building Brilliant Applications

mithril.js What is Mithril? Installation Documentation Getting Help Contributing What is Mithril? A modern client-side JavaScript framework for buildi

null 13.5k Dec 28, 2022
The tiny framework for building hypertext applications.

Hyperapp The tiny framework for building hypertext applications. Do more with lessβ€”We have minimized the concepts you need to learn to get stuff done.

Jorge Bucaran 18.9k Jan 1, 2023
A declarative, HTML-based language that makes building web apps fun

A declarative, HTML-based language that makes building web apps fun ?? Docs βˆ™ Try Online βˆ™ Contribute βˆ™ Get Support Intro Marko is HTML re-imagined as

Marko 12k Jan 3, 2023
Dojo Framework. A Progressive Framework for Modern Web Apps

@dojo/framework Dojo is a progressive framework for modern web applications built with TypeScript. Visit us at dojo.io for documentation, tutorials, c

Dojo 549 Dec 25, 2022
Create blazing fast multithreaded Web Apps

Welcome to neo.mjs! neo.mjs enables you to create scalable & high performant Apps using more than just one CPU, without the need to take care of a wor

neo.mjs 2.4k Dec 31, 2022
πŸ™Œ Check if a Discord user is sponsoring you/someone on GitHub and give them roles!

Discord: Is User Sponsor? A bot that gives roles if a user is supporting you on GitHub! Uses Discord OAuth and Discord GitHub integration to get user'

EGGSY 18 Jun 27, 2022
KioskBoard - A pure JavaScript library for using virtual keyboards.

KioskBoard - Virtual Keyboard A pure JavaScript library for using virtual keyboards. Current Version 2.0.0 * Documentation and Demo https://furcan.git

Furkan MT 177 Dec 29, 2022