A blazing fast React alternative, compatible with IE8 and React 16.

Overview

Build Status License Coverage Status Downloads Build Status Sauce Test Status

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

中文

Features

Identical React API, no 'nerv-compat' is needed

Battle tested, serve in JD.com home page and TOPLIFE.com

⚡️ High performance

🤣 IE8 compatibility

🎯 Tiny size, 9Kb gzipped

🌗 Isomorphic rendering on both client and server

💫 Support React 16 features, Error Boundaries, Portals, custom DOM attributes, etc.

Packages

This repository is a monorepo that we manage using Lerna. That means that we actually publish several packages to npm from the same codebase, including:

Package Description
nervjs The core of Nerv
nerv-redux Nerv binding for Redux
nerv-devtools Provides support for React's Dev Tools for Nerv
nerv-server Support for server side rendering
nerv-test-utils Suite of utilities for testing Nerv applications
nerv-utils Internal Helpers functions for Nerv
nerv-shared Internal shared functions for Nerv
nerv-create-class The legacy createClass API for Nerv

Getting Started

The easiest way to get started with Nerv is using CodeSandbox Playground, If you use React, you already know how to use Nerv.

Install

Of course we recommend that you use Nerv with Webpack and Babel.First you can install Nerv like this

With npm

$ npm install --save nervjs

With yarn

$ yarn add nervjs

Usage

Import what you need. Nerv provides both named and default exports, you can use Nerv as a namespace or simply import what you need as locals.

Default exports:

import Nerv from 'nervjs'
class HelloMessage extends Nerv.Component {
  render() {
    return <div>Hello {this.props.name}</div>
  }
}

Nerv.render(
  <HelloMessage name="Nerv" />,
  document.getElementById('app')
)

Named:

import { Component, render } from 'nervjs'
class HelloMessage extends Component {
  render() {
    return <div>Hello {this.props.name}</div>
  }
}

render(
  <HelloMessage name="Nerv" />,
  document.getElementById('app')
)

☝️ For more information please move to the official development document

Examples

Switching to Nerv from React

Switching to Nerv from React is easy as adding alias nervjs for react and react-dom. No changes in code needed.

Usage with Webpack

Add an alias in your webpack.config.js:

{
  // ...
  resolve: {
    alias: {
      'react': 'nervjs',
      'react-dom': 'nervjs',
      // Not necessary unless you consume a module using `createClass`
      'create-react-class': "nerv-create-class"
    }
  }
  // ...
}

Usage with Babel

Install the babel plugin for aliasing

$ npm install --save-dev babel-plugin-module-resolver

In .babelrc:

{
  "plugins": [
    ["module-resolver", {
      "root": ["."],
      "alias": {
        "react": "nervjs",
        "react-dom": "nervjs",
        // Not necessary unless you consume a module using `createClass`
        "create-react-class": "nerv-create-class"
      }
    }]
  ]
}

Usage with Browserify

Install the aliasify transform:

$ npm i --save-dev aliasify

Then in your package.json:

{
  "aliasify": {
    "aliases": {
      "react": "nervjs",
      "react-dom": "nervjs"
    }
  }
}

Compatible with React

Nerv currently support React API and features:

react

  • React.createClass (legacy)
  • React.createElement
  • React.cloneElement
  • React.Component
  • React.PureComponent
  • React.PropTypes
  • React.Children
  • React.isValidElement
  • React.createFactory
  • Error Boundaries (React 16)

react-dom

  • React.unstable_renderSubtreeIntoContainer (legacy)
  • ReactDOM.render
  • ReactDOM.unmountComponentAtNode
  • ReactDOM.findDOMNode
  • ReactDOM.hydrate (React 16)
  • ReactDOM.createPortal (React 16)

Internet Explorer 8 (or below) compatibility

First, install es5-polyfill:

npm install --save es5-polyfill

Then insert the code into the beginning of your entry file:

require('es5-polyfill');

At last, setting .babelrc if you are using babel:

{
  "presets": [
    ["env", {
      "spec": true,
      "useBuiltIns": false
    }],
    ["es3"]
  ],
  ...
}

Developer Tools

Nerv has a development tools module which allows you to inspect the component hierarchies via the React Chrome Developer Tools plugin.

To enable the Nerv development tools you must install the nerv-devtools module and then require('nerv-devtools') before the initial Nerv.render().

if (process.env.NODE_ENV !== 'production')  {
  require('nerv-devtools')
}
// before Nerv.render()
Nerv.render(<App />, document.getElementById('#root'))

nerv-devtools

Change Log

Acknowledgement

AOTU.IO(JD Multi-terminal Development Department)

License

FOSSA Status

Comments
  • 兼容 React 生态系统?

    兼容 React 生态系统?

    opened by guxingke201 19
  • diff 算法原理概述

    diff 算法原理概述

    1. 找到相同的前置元素和后置元素
         *
         *  A: -> [a b c d] <-
         *  B: -> [a b d] <-
         *
    

    这里我们可以发现前置元素 a, b 和 后置元素 d 都是相同的。所以我们可以将这样的 diff 情况转变为:

    
         *
         *  A: -> [c] <-
         *  B: -> [] <-
         *
    
    

    这里我们可以发现 A 和 B 的不同就是多了一个 c 元素,所以只要进行把 c 元素移除这一步可以完成 diff。相反地,如果这步操作 A 为空,B 有多余元素,那么我们就将多余元素插入即可。 这一步 diff 优化最早由 Neil Fraser 提出,实现非常简单(在 Neil 的文章里他提供了 JavaScript,Java,Python 三种实现),优化的力度也非常大,但真正首次应用到前端框架却是十年后的 Bobril,后来号称性能最强的 Inferno 也使用了这一优化。

    再来看下一种情况:

    
         *
         *  A: -> [a b c d e f g] <-
         *  B: -> [a c b h f e g] <-
         *
    
    

    在这个情况的 diff 中,我们可以应用之前的优化策略把他简化为:

         *
         *  A: -> [b c d e f] <-
         *  B: -> [c b h f e] <-
         *
    
    1. 这时候我们就需要进行第二步:找到需要被删除、插入或移动的元素:

    首先我们创造一个数组 P,它代表新数组应该被插入的位置。

         *
         *  A: [b c d e f]
         *  B: [c b h f e]
         *  P: [. . . . .] // . == -1
         *
    

    接下来我们再创建一个索引 I,作为新数组位置的映射(如果新旧数组都很小的话,那我们直接遍历数组即可,反之我们需要一个索引):

         *
         *  A: [b c d e f]
         *  B: [c b h f e]
         *  P: [. . . . .] // . == -1
         *  I: {
         *    c: 0,
         *    b: 1,
         *    h: 2,
         *    f: 3,
         *    e: 4,
         *  }
         *  last = 0
         *
    

    有了数组 P 和 索引 I 之后,现在我们可以开始遍历旧数组

     *
     *  A: [b c d e f]
     * 	^
     *  B: [c b h f e]
     *  P: [. 0 . . .] // . == -1
     *  I: {
     *    c: 0,
     *    b: 1, <-
     *    h: 2,
     *    f: 3,
     *    e: 4,
     *  }
     *  last = 1
     *
    

    第一步遍历我们可以发现旧数组的 b 元素也在新数组上,所以我们把他在旧数组的位置 0 放到他在数组 P 相对应的位置上。

    这里我们同时还要维护一个变量 last,它代表访问过的节点在新集合中最右的位置(即最大的位置)。如果新集合中当前访问的节点比 last 大,说明当前访问节点在旧集合中就比上一个节点位置靠后,则该节点不会影响其他节点的位置,因此不必执行移动操作。只有当访问的节点比 last 小时,才需要进行移动操作。

     *
     *  A: [b c d e f]
     * 	  ^
     *  B: [c b h f e]
     *  P: [1 0 . . .] // . == -1
     *  I: {
     *    c: 0, <-
     *    b: 1,
     *    h: 2,
     *    f: 3,
     *    e: 4,
     *  }
     *  last = 1 // last > 0; moved = true
     *
    

    这里我们访问元素 c 的位置为 0,而 last 为 1,所以我们需要进行移动操作。

    这一步实际上也是 React Stack Reconciler(React 16 以下)的核心算法:每次遍历的时候把当前节点在旧集合的位置和 last 进行对比,如果 mountIndex 大于 last,那么就把他添加到差异队列,然后更新 last,全部遍历完毕之后再遍历差异队列,一步一步进行 patch。

    (这里如果理解有障碍的话建议把常规的排序算法都撸一遍,可以重点看选择排序和插入排序)

     *
     *  A: [b c d e f]
     *          ^
     *  B: [c b h f e]
     *  P: [1 0 . . .] // . == -1
     *  I: {
     *    c: 0,
     *    b: 1,
     *    h: 2,
     *    f: 3,
     *    e: 4,
     *  }
     *  moved = true
     *
    

    这里元素 d 在新数组当中并不存在,所以它应该被移除掉。

     *
     *  A: [b c d e f]
     *            ^
     *  B: [c b h f e]
     *  P: [1 0 . . 3] // . == -1
     *  I: {
     *    c: 0,
     *    b: 1,
     *    h: 2,
     *    f: 3,
     *    e: 4, <-
     *  }
     *  moved = true
    

    这里把元素 e 在旧数组的位置(3)放到数组 P 上。

     *
     *  A: [b c d e f]
     * 	        ^
     *  B: [c b h f e]
     *  P: [1 0 . 4 3] // . == -1
     *  I: {
     *    c: 0,
     *    b: 1,
     *    h: 2,
     *    f: 3, <-
     *    e: 4,
     *  }
     *  moved = true
     *
    

    这里把元素 f 在旧数组的位置(4)放到数组 P 上。

    到了这一步,如果是 React 的算法已经走完了。但不妨思考以下的 diff 情况:

     *
     * A: [a b c d]
     * B: [d a b c]
     *
    

    这里肉眼一看就知道,把旧集合的 d 元素移动到 0 这一步操作就可以完成 diff。但根据前文所述的逻辑走一次,实际上 React 会先把 a, b, c 移动到他们的相应的位置 + 1,一共三步操作。

    移动操作也并不是没有副作用,仍然可能会重启动画,focus 丢失,重置滚动条位置等。所以我们还可以进行下一步优化:

    1. 找到最小的移动次数。

    这里我们需要找到 P 数组的[最长递增子序列(longest increasing subsequence)] 来做动态规划,新集合中不属于这个序列的将会被移动。

    还是用我们之前的例子:

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *  P: [1 0 . 4 3] // . == -1
     *  LIS:     [1 4]
     *  moved = true
     *
    

    这里我们同时尾部遍历新数组和 LIS 序列,查看元素的位置是否能与 LIS 序列的任何一个值匹配。

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *              ^  // new_pos == 4
     *  P: [1 0 . 4 3] // . == -1
     *  LIS:     [1 4]
     *              ^  // new_pos == 4
     *  moved = true
     *
    

    这一步能匹配,e 可以呆在它原来的位置上。

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *            ^    // new_pos == 3
     *  P: [1 0 . 4 3] // . == -1
     *  LIS:     [1 4]
     *            ^    // new_pos != 1
     *  moved = true
     *
    

    f 的位置不能匹配,把他移动到 e 之前。

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *          ^      // new_pos == 2
     *  P: [1 0 . 4 3] // . == -1
     *          ^      // old_pos == -1
     *  LIS:     [1 4]
     *            ^
     *  moved = true
     *
    

    h 的位置为 -1,把他插入。

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *        ^        // new_pos == 1
     *  P: [1 0 . 4 3] // . == -1
     *  LIS:     [1 4]
     *            ^    // new_pos == 1
     *  moved = true
     *
    

    b 能匹配 LIS,可以老老实实呆着。

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *      ^          // new_pos == 0
     *  P: [1 0 . 4 3] // . == -1
     *  LIS:     [1 4]
     *          ^      // new_pos != undefined
     *  moved = true
     *
    

    c 不能匹配,把它移动到 b 之前。

    走完这一步我们的 diff 算法就完毕了。

    这时回头再来看看之前把尾部元素插入到头部的情况,React 需要经过 3 次操作,而经过我们动态规划之后:

     *
     - A: [a b c d]
     - B: [d a b c]
     - P: [3 0 1 2]
     - LIS: [0 1 2]
     *
    

    可以发现 a, b, c 能匹配 LIS,可以呆到天荒地老,我们只要把 d 移动到头部的位置就可以完成 diff。Perfect!

    详细代码: https://github.com/NervJS/nerv/blob/patch/packages/nerv/src/vdom/patch.ts

    opened by yuche 13
  • Adds node instead of replacing

    Adds node instead of replacing

    I found a weird bug and I'm not sure what the cause is.

    I have the following code:

    <div id="app">
    	<Header location={this.state.location} />
    	<main className="d-flex justify-content-center">
    		<HashRouter onLocationChanged={this.handleLocationChanged}>
    			<Route key="liked" hash="#/">
    				<Liked />
    			</Route>
    			<Route key="saved" hash="#/saved">
    				<Saved />
    			</Route>
    			<Route key="about" hash="#/about">
    				<About />
    			</Route>
    		</HashRouter>
    	</main>
    </div>
    

    HashRouter render function:

    return this.state.render
    

    In the state, only one child is saved (double checked with console.log and dev tools). However, when I render a different component (so to say, a route change is happening), this happens: screenshot_6

    So it seems Nerv is adding the component/a Node to the DOM instead of replacing it. Both <Liked /> and <About /> render a <div>, the latter one with className="...".

    Code is here: https://github.com/kurtextrem/Improved-for-Instagram/blob/master/src/components/HashRouter.js#L152 / https://github.com/kurtextrem/Improved-for-Instagram/blob/master/src/components/app.js#L44

    opened by kurtextrem 12
  • nerv-devtools error!!!

    nerv-devtools error!!!

    nerv-devtools always works well ,but when add the react-router-dom , it is error !

    TypeError: Cannot read property 'type' of null createReactDOMComponent E:/demos/ReactApp/nerv-app/node_modules/nerv-devtools/dist/index.esm.js:74

    71 | _currentElement: isText 72 | ? vnode.text 73 | : { 74 | type: vnode.type, 75 | props: normalizeProps(vnode.props) 76 | }, 77 | _renderedChildren: normalizeChildren(vnode.children),

    opened by pedrogao 11
  • NervJS 1.4 beta3 test-utils 报错

    NervJS 1.4 beta3 test-utils 报错

    Works well in 1.3.x版本。But broke in 1.4.

    TypeError: Cannot read property 'forEach' of undefined

      34 | 
      35 |   it(`somehow throw error`, () => {
    > 36 |     const component = renderIntoDocument(<Campaign campaignProps={mockCampaign.events} />)
         |                       ^
      37 |     const componentDom = findDOMNode(component, 'swiperContent')
      38 |     const items = componentDom.querySelectorAll('.swiperImage')
    
      at forEach (node_modules/nervjs/src/hooks.ts:123:11)
      at renderComponent (node_modules/nervjs/dist/index.js:1702:5)
      at renderComponent (node_modules/nervjs/src/lifecycle.ts:98:20)
      at ComponentWrapper.mountComponent [as init] (node_modules/nervjs/src/full-component.ts:47:17)
      at init (node_modules/nervjs/src/vdom/create-element.ts:27:47)
      at createElement (node_modules/nervjs/src/lifecycle.ts:69:10)
      at mountVNode (node_modules/nervjs/src/lifecycle.ts:107:28)
      at ComponentWrapper.mountComponent [as init] (node_modules/nervjs/src/full-component.ts:47:17)
      at createElement (node_modules/nerv-test-utils/node_modules/nervjs/dist/index.js:1333:29)
      at mountVNode (node_modules/nerv-test-utils/node_modules/nervjs/dist/index.js:1454:12)
      at Object.render (node_modules/nerv-test-utils/node_modules/nervjs/dist/index.js:1729:15)
      at renderIntoDocument (node_modules/nerv-test-utils/src/index.ts:16:16)
    
    opened by ZhangJian-3ti 7
  • IE8下报 “缺少标识符” 错误

    IE8下报 “缺少标识符” 错误

    感谢nerv团队努力!

    我使用create-react-app和react-router V4建了一个项目,修改react-scripts中关于webpack的alias配置,打包出来后,ie9, ie10都可以正常使用(在修改alias配置前试过打包项目运行,原生react在ie9和ie10下均无法使用),ie8下报了“缺少标识符”错误。

    tim 20180426091824

    检查了一下,是service worker的问题,去掉后,ie8下报"对象不支持此操作"错误

    tim 20180426094441

    opened by yaoyonstudio 6
  • 关于使用nerv前的些许小疑问

    关于使用nerv前的些许小疑问

    各位nerv开发大佬你们好。

    SSR

    我看到有提供nerv-server包,提供了字符串模板输出(包括Prefetching这些?)。 但如果用next.js也没问题吧。

    路由

    路由是沿用社区react-router,还是说后期你们会出一个官方nerv-router?

    性能

    目前nerv应用在了jd.com,我看源码是服务端渲染+客户端交互渲染? 需要写两份代码吗,server/clinet各一份? 还是说nerv ssr方案自带组件反解?

    希望大佬能百忙之中抽空解答,不胜感激。

    opened by lolipop99 6
  • Server-side rendering is crashing with react-inform

    Server-side rendering is crashing with react-inform

    I am using 1.2.4-beta.1

    When I am using react-inform and nerv-server - it crashes the render.

    state.values seems to be undefined, so values[name] is crashing in this file: https://github.com/theadam/react-inform/blob/master/src/form.js

    However when I render this in browser - everything is working as expected.

    I'm not using anything fancy with react-inform so you should be able to reproduce this with basic example, but if not - I may try to isolate the issue out of my project and make a repo out of it.

    opened by dzek69 6
  • 实际render结果和state不一致(有codesandbox的demo)

    实际render结果和state不一致(有codesandbox的demo)

    Reproduction link https://codesandbox.io/s/qlpj0071qw Steps to reproduce 1.在手机或者Chrome手机模拟器打开测试页面 2.下拉页面,并松手

    期望结果: 页面弹回 实际结果: 页面没有弹回

    补充信息: 控制台打印出了对后一次render时候的style,对比实际dom上的style,不一致。

    用react创建了一个一样的demo是正常的: https://codesandbox.io/s/kx1ox76y5o

    opened by wen911119 5
  • 做了个简单demo,nerv+nextjs跑不起来

    做了个简单demo,nerv+nextjs跑不起来

    //.babelrc配置
    "plugins": [
        [
          "transform-react-jsx",
          {
            "pragma": "Nerv.createElement"
          }
        ],
        [
          "module-resolver", 
          {
          "root": ["."],
          "alias": {
              "react": "nervjs",
              "react-dom": "nervjs",
              "create-react-class": "nerv-create-class"
          }
        }]
      ]
    
    // page/index.js
    import React from 'react'
    
    export default () => <div>Welcome to next.js!</div>
    

    1516986826288

    opened by lolipop99 5
  • Bug: as per React: unmount callbacks should be called before removing DOM

    Bug: as per React: unmount callbacks should be called before removing DOM

    unmount callbacks should be called before removing DOM. See https://jsfiddle.net/Luotcj1f/ for React behavior. at least this line in wrong: https://github.com/NervJS/nerv/blob/master/packages/nerv/src/vdom/patch.ts#L95-L96

    Didn't check any other places.

    opened by Havunen 5
  • Set correct location of typescript definition file

    Set correct location of typescript definition file

    Fixing:

    Could not find a declaration file for module 'nervjs'. 
    './default/node_modules/nervjs/index.js' implicitly has an 'any' type. 
    Try `npm install @types/nervjs` if it exists 
    or add a new declaration (.d.ts) file containing `declare module 'nervjs';
    
    opened by bogdan 1
  • nerv-test-utils的api:findRenderedDOMComponentWithClass问题

    nerv-test-utils的api:findRenderedDOMComponentWithClass问题

    版本:

    "nerv-devtools": "^1.5.7", "nerv-test-utils": "^1.5.7", "jest": "^25.1.0",

    问题描述:

    ReactTestUtils.findRenderedDOMComponentWithClass(wrapper,'.sp-alert_close_icon'); 这个方法在查找元素时候,查不到,jest测试报错

    image

    查看源码

    image

    上图里面查找的result为空数组

    opened by tibic 0
  • nervjs 1.5.7 typings 路径错误

    nervjs 1.5.7 typings 路径错误

    Version: nervjs 1.5.7 现象:使用 TS 时,nervjs 类型无法正常提示 原因:

    package.json 中指定的 typings 路径为 index.d.ts

    {
      "name": "nervjs",
      "version": "1.5.7",
      "description": "A react-like framework based on virtual-dom",
      "main": "index.js",
      "module": "dist/index.esm.js",
      "jsnext:main": "dist/index.esm.js",
      "typings": "index.d.ts",
      "unpkg": "dist/nerv.js",
    }
    

    npm包中实际的typing路径为 dist/index.d.ts

    ├── CHANGELOG.md
    ├── README.md
    ├── dist
    │   ├── index.d.ts # d.ts
    │   ├── index.esm.js
    │   ├── index.esm.js.map
    │   ├── index.js
    │   ├── index.js.map
    │   ├── index.prod.js
    │   ├── nerv.js
    │   ├── nerv.js.map
    │   ├── nerv.min.js
    │   └── packages
    ├── index.js
    └── package.json
    
    opened by FredZeng 1
⚛️ 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 compiler that converts React-compatible codes to VanillaJS with no Virtual DOM

Vidact Vidact compiles your React source codes to VanillaJS code with No Virtual DOM ™️ . It is similar to Svelte, but unlike Svelte, Vidact does not

Mohamad Mohebifar 753 Dec 22, 2022
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

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

Inferno 15.6k Dec 31, 2022
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
🌙 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
🌱 React and redux based, lightweight and elm-style framework. (Inspired by elm and choo)

English | 简体中文 dva Lightweight front-end framework based on redux, redux-saga and react-router. (Inspired by elm and choo) Features Easy to learn, eas

null 16.1k Jan 4, 2023
Write components once, run everywhere. Compiles to Vue, React, Solid, Angular, Svelte, and more.

Write components once, run everywhere. Compiles to: At a glance Mitosis is inspired by many modern frameworks. You'll see components look like React c

Builder.io 7.7k Jan 1, 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
🐰 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
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.9k Jan 9, 2023
A declarative, efficient, and flexible JavaScript library for building user interfaces.

React · React is a JavaScript library for building user interfaces. Declarative: React makes it painless to create interactive UIs. Design simple view

Facebook 200k Jan 4, 2023
Give your JS App some Backbone with Models, Views, Collections, and Events

____ __ __ /\ _`\ /\ \ /\ \ __ \ \ \ \ \ __ ___\ \ \/'\\ \ \_

Jeremy Ashkenas 28k Jan 9, 2023
Write JSX-driven components with functions, promises and generators.

Crank.js Write JSX-driven components with functions, promises and generators. Documentation is available at crank.js.org. Crank.js is in a beta phase,

null 2.5k Jan 1, 2023
The simplest way to create web components from plain objects and pure functions! 💯

?? One of the four nominated projects to the "Breakthrough of the year" category of Open Source Award in 2019 hybrids is a UI library for creating web

hybrids 2.7k Dec 27, 2022
Simple and elegant component-based UI library

Simple and elegant component-based UI library Custom components • Concise syntax • Simple API • Tiny Size Riot brings custom components to all modern

Riot.js 14.7k Jan 4, 2023
A functional and reactive JavaScript framework for predictable code

Cycle.js A functional and reactive JavaScript framework for predictable code Website | Packages | Contribute | Chat | Support Welcome Question Answer

Cycle.js 10.2k Jan 4, 2023
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
Re-developed the Sky Ice Cream website using ReactJS. Redesigned the UI to a much more appealing and intuitive styling.

This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: npm start Runs the app in the developmen

Aakash Jana 1 Dec 27, 2021