Introduction to Hyperapp Working Architecture, Advantages and Tools

November 10, 2018 

Introduction to Hyperapp Working Architecture, Advantages and Tools

What is Hyperapp?

Hyperapp is a lightweight Javascript framework for developing feature-rich web applications. It is written in ES5 i.e., ECMAScript 5. Hyperapp requires Node.js, NPM, JSX and Webpack modules installed on the system before jumping on building a web application. The idea behind working on Hyper App framework is to get more from less, i.e., minimizing the dependencies and usage of simpler software code.

While comparing to other frameworks like React, Preact, Vue, Ember, Mithril, etc., in the market, HyperApp framework is very compact API which holds minimal bundle size and built-in state management. It has a strong foundation and significant community support. One can participate in their online community support for developing Hyperapp a robust frontend javascript framework.

HyperApp web applications are interactive and responsive web applications. It follows powerpack three principles, one-way data flow, JSX, and virtual DOM to make the app more flexible and robust. HyperApp framework is based on Elm architecture. Other Elm based frameworks include React and Redux etc.


How Hyperapp Works?

Hyperapp framework basically wraps up the three interconnected approaches i.e., state, actions, and view.

The state is responsible for updating the changes every time the user performs the action on the user interface(view).

View holds the responsibility for rendering the changes over the user interface which user can see.

An action is a unary function that holds the single argument expecting a payload. The payload could be anything user want to pass into the action. On each action call, the state changed and then the state redraws the changes onto the view.

Here is a simple "Hello World" example -


 import { h, app } from "hyperapp"

​const state = { title: "Hi." }

const actions = {}

const view = state => {state.title}

​app(state, actions, view, document.body)
 

Code bounding simple HTML input -


import { h, app } from "hyperapp"

const state = {

  text: "Hello!"

}
const actions = {

  setText: text => ({ text })

}
const view = (state, { setText }) => (

<main>
{state.text.trim() === : state.text}
<input
autofocus
value={state.text}
oninput={e => setText(e.target.value)}
/>
</main>
)
app(state, actions, view, document.body)

The user triggers action on the web application and after the action is triggered the action function is called and takes responsibility to replace the previous state with the new state and updates the state. The state updated asynchronously when the action triggered and make changes on the user interface(view) and the whole process follows.

HyperApp includes stateless components which are pure javascript functions and render themselves and actions allowed to trigger. These functions are framework agnostic, easy to test and debug.


Benefits of Hyperapp

  • Lightweight Javascript library - HyperApp framework has build size of 1KB (1.3 KB) delivering the purpose of building web applications with simple and easy.
  • State Management - HyperApp framework based on Elm architecture just like React and Redux, but it has built-in state management unlike React which depends on Redux for state management. Therefore, delivers functional web application efficiently with fewer lines of code.
  • Minimal (Simple to understand) - HyperApp team aggressively minimizes the concepts user needs to follow to be productive. Therefore with its fewer dependencies and just a hundred lines of code, it becomes easier to adopt such an approach for newcomers.
  • Standalone - HyperApp approach is to do more with less. HyperApp supports inbuilt state management with virtual DOM which supports key updates & lifecycle events — all with no dependencies.
  • Pragmatic - HyperApp, when managing the state holds a firm on functional programming but follows a practical approach to allow for side effects, DOM manipulations. And asynchronous actions.
  • Not a one-man-effort - HyperApp has a broad foundation and supports community which helps framework to get better and flexible every time.

Why Hyperapp Matters?

HyperApp is lightweight, easy to use, less number of lines of code, if anyone doesn't want to write the code or wants to create the app quickly, use HyperApp.

It can be a better option for the smaller application; one can not recommend for the complex application.

Event handling and changing states of the component is easy in Hyperapp as compared to Redux.

HyperApp is easy to learn if the user is familiar with the Redux framework.

Its lifecycle is similar that the React, i.e., oncreate, onupdate, onmove, ondestroy. API calls are easy to handle in Hyperapp.


How to Adopt Hyperapp?

Here is a simple counter application to make the user familiar with working of HyperApp framework -

Make dir named "hyperapp" on the local system and make dir working -



mkdir hyperapp



cd hyperapp

For running any javascript application require the package.json file.

For the yarn package manager

     
yarn init

For npm package manager


npm init

Once the package manager initialized than package.json file will be made in the directory. Install dependency parcel-bundler in application -


yarn add --dev parcel-bundler babel-preset-env babel-preset-react

Parcel-bundler is a web-application bundler to keep all our application files - Js, CSS, HTML in one place and makes a proper bundle. We can also use webpack instead, but this approach is most comfortable to set up.

Install the HyperApp dependency in the application.


yarn add hyperapp
 

Or

 

npm install hyperapp

Make a file in the project with extension ".babelrc" and keep it in that project root path.


{
  "presets": ["env", "react"],

  "plugins": [["transform-react-jsx", { "pragma": "h" }]]
}

Please note, no React used here, just including "React " as an environment for "presets" and utilizing the same settings for Babel.

Make two files named -

>index.html


<!DOCTYPE html>
<html>
<head>
<title>Hyperparcel Starter</title>
</head>
<body>
<div id="app"></div>
<script src="index.js"></script>
</body>
</html>

This file loaded and initialized the very first time the application runs and makes the entry point in the application which is "index.js" file.

> index.js


import { h, app } from "hyperapp"

const state = {

  count: 0

}
const actions = {

  down: () => state => ({ count: state.count - 1 }),

  up: () => state => ({ count: state.count + 1 })

}
const view = (state, actions) => (
<main>
<h1>{state.count}</h1>
<button onclick={actions.down}>-</button>
<button onclick={actions.up}>+</button>
</main>
)
const main = app(state, actions, view, document.body)
  

Make sure to keep both the index.html and index.js files to the root path of the project.

Launch the application, run the development server. Run the Parcel command, but the Parcel not included in the bin path, include start and build scripts under the scripts section in the package.json file.


{

  "name": "hyperapp",

  "version": "1.0.0",

  "description": "A starter for building apps with Hyperapp and Parcel.",

  "main": "index.js",

  "scripts": {

    "start": "parcel index.html",

   "build": "parcel build index.html --public-url ./"

  },

  "repository": "https://github.com/cutemachine/hyperparcel.git",

  "author": "jo@cutemachine.com",

  "license": "MIT",

  "devDependencies": {

    "babel-preset-env": "^1.6.1",

    "babel-preset-react": "^6.24.1",

    "parcel-bundler": "^1.5.1"

  },

  "dependencies": {

    "hyperapp": "^1.0.2"

  }

}

Now the package.json file will look similar to this -

This file includes -

  • the name consists of the name of the project "hyperapp."
  • version includes the version of the project.
  • description includes the small description of the project (not compulsory).
  • main includes the main entry of the project which is "index.js" file.
  • scripts include the start, build and other scripts required at the time of building and starting the application.
  • the repository includes the git repository where our project is present, and anyone can clone this repo in there a local system in the case to run this project.
  • the author is the name of the developer who has to build the project.
  • the license includes the standard "MIT" license provided.
  • devDependencies includes all the development based dependencies which are required at the time of development.
  • dependencies include all the dependencies required at the runtime.

In this way, set up the first counter application using the HyperApp framework.


Best Practices Of Hyperapp

This example is a counter that can be incremented or decremented -


import { h, app } from "hyperapp"
​
const state = {

  count: 0

}

const actions = {

  down: value => state => ({ count: state.count - value }),


  up: value => state => ({ count: state.count + value })

}

const view = (state, actions) => (
<div>
<h1>{state.count}</h1>
<button onclick={() => actions.down(1)}>-</button>
<button onclick={() => actions.up(1)}>+</button>
</div>
)
app(state, actions, view, document.body)

Hyperapp consists of a two-function APIs, i.e. hyperapp.h and hyperapp.app.

hyperapp.h returns a new virtual DOM (Document Object Model) node tree and hyperapp.app mounts a new app in the specified DOM element. It's possible to use Hyperapp "headless," without an element, which can be useful when implementing the unit test in the application.

This example assumes JavaScript compiler like Babel or TypeScript and a module bundler like Parcel, Webpack, etc. used. If JSX is used, the JSX transform plugin installed and the pragma option added to the .babelrc file.


{
  "plugins": [["@babel/plugin-transform-react-jsx", { "pragma": "h" }]]

}

JSX is a language used to write HTML tags interspersed with JavaScript. Since browsers don't understand JSX, use a compiler to transform it into hyperapp.h function calls under the hood.


const view = (state, actions) =>

  h("div", {}, [

    h("h1", {}, state.count),

    h("button", { onclick: () => actions.down(1) }, "-"),

    h("button", { onclick: () => actions.up(1) }, "+")

  ])

Note that JSX preprocessor not required for building applications with HyperApp. One can use hyperapp.h directly and without a compilation step as shown above. Other alternatives to JSX include @hyperapp/HTML, hyperx, t7 and ijk.


Hyperapp Tools

The tools required to get started with HyperApp framework -