Skip to main content
CodeSpeedTest
Languages
Start TypingJump into a test — pick any languageAdaptive TrainingUnlock chars as you master themPractice DrillsFocused sessions targeting weak spotsDaily ChallengesNew coding challenges every dayRace ModeCompete against others in real timeAI OpponentRace against an AI at your WPM levelTournamentsLive coding speed tournamentsArcade GamesZType, Overkill Survival, Glyphica & moreGamificationXP, coins, badges & quests
LeaderboardGlobal rankings for every languageCertificatesEarn verifiable Bronze / Silver / Gold certsActivityDaily streaks & historical analyticsProfileYour stats, badges & achievements
Browse Languages500+ languages with real code examplesBlogTips, guides & deep divesFree ToolsWPM calculator, typing speed report & moreFAQCommon questions answeredGetting StartedNew to CodeSpeedTest?AboutOur story & missionSupportGet help — Pro users get priorityContactGet in touch with the team
Pricing
  1. Home
  2. /
  3. Learn
  4. /
  5. Hyperapp

Learn Hyperapp - 9 Code Examples & CST Typing Practice Test

Hyperapp is an ultra-lightweight (≈1 KB), functional JavaScript library for building user interfaces using a minimalist architecture of state, actions, and a virtual DOM. It emphasizes simplicity, purity, and predictable UI updates.

View all 9 Hyperapp code examples →
Hyperapp Simple CounterHyperapp Counter with StepHyperapp Counter with Max/MinHyperapp Counter with Auto IncrementHyperapp Counter with Double IncrementHyperapp Counter with Even/Odd IndicatorHyperapp Counter with Max/Min and StepHyperapp Counter with LocalStorageHyperapp Counter with Color Themes

Learn HYPERAPP with Real Code Examples

Updated Nov 23, 2025

Explain

Hyperapp uses a functional, Elm-inspired architecture.

It focuses on predictable state updates through pure actions.

Its virtual DOM implementation is extremely minimal yet efficient.

Core Features

State management via pure functions

Virtual DOM rendering

Actions for updating state

Subscriptions for external effects

Component composition via functions

Basic Concepts Overview

The global state object

Pure actions modifying state

View function returning virtual DOM

Subscriptions for external events

Component functions (reusable UI)

Project Structure

index.html - basic mount point

app.js - state, actions, and views

components/ - optional reusable UI pieces

store.js - centralized state (optional)

effects/ - subscriptions for events like timers

Building Workflow

Define initial state

Write actions that update it

Write a view that renders DOM

Mount app via `app({})`

Iterate with small components

Difficulty Use Cases

Beginner: counters and forms

Intermediate: components and actions

Advanced: subscriptions and effects

Expert: custom rendering patterns

Community: Hyperapp plugins or contributions

Comparisons

Lighter than React, Preact, and Vue

More functional than Svelte

Simpler than Elm with fewer constraints

More predictable than jQuery-based UIs

Better for micro-apps than Angular

Versioning Timeline

2017 - Hyperapp 1.0 released

2018 - Virtual DOM improvements

2020 - Hyperapp 2 released with simplified API

2022 - Community growth and tooling maturation

2025 - Hyperapp used widely for microfrontends

Glossary

VDOM: Lightweight representation of DOM

Action: Pure function updating state

Subscription: External side effects

Component: Reusable function returning VDOM

App(): Initializes state/action/view

Installation Setup

Install via npm: `npm install hyperapp`

Or use CDN script: `<script src='https://unpkg.com/hyperapp'></script>`

No CLI or build system required

Start coding in a single JavaScript file

Use bundlers only if desired (Vite/Webpack)

Environment Setup

Install Node.js (optional)

Start with CDN or npm install

Use VSCode or any editor

Set up dev server if bundling

Keep project structure simple

Config Files

index.html

app.js

components/*.js

vite.config.js (optional)

package.json

Cli Commands

No official CLI needed

Use `npm init vite` if bundling

Run `npx serve` for static dev

Use Parcel/Vite for zero-config builds

Run tests via Jest CLI

Internationalization

Simple JSON message dictionaries

Manual i18n logic via actions

Community plugins for i18n

Component-based formatting

RTL support via CSS

Accessibility

Semantic HTML encouraged

ARIA attributes added manually

Keyboard navigation supported via events

Simple DOM encourages A11y compliance

Small markup = better screen reader compatibility

Ui Styling

CSS or inline styles

Tailwind or PostCSS

Functional class binding

Component-based styles

Atomic or utility-first styles

State Management

Global state object

Pure actions

Local states via components

Subscriptions for events

Community-based stores (optional)

Data Management

Fetch API for requests

Actions handling async data

Global or component-level stores

Subscriptions for timers and sockets

Local browser storage integrations

Architecture

Elm-like functional design

State + Actions + View model

Pure update flow

Virtual DOM diffing

Subscription-based side effects

Rendering Model

Virtual DOM diffing

Pure view functions

Subscription-driven re-renders

Efficient keyed updates

DOM patching

Architectural Patterns

Functional state management

Component composition

Pure update flow

Effect-driven subscriptions

Unidirectional UI updates

Real World Architectures

IoT device dashboards

Admin widgets

Chrome/Firefox extensions

Small SPAs

Embedded UIs in enterprise software

Design Principles

Functional purity

Minimal bundle size

Predictable updates

No hidden magic

Composable architecture

Scalability Guide

Split into components early

Share state through top-level app

Use subscriptions for async tasks

Group actions logically

Avoid deeply nested VDOM

Migration Guide

Hyperapp 1 -> 2 uses simpler API

Replace old `h()` signatures

Update subscriptions

Remove deprecated helpers

Refactor class components (if any)

Performance Notes

Avoid large nested components

Keep view functions pure

Use small, composable components

Prefer minimal DOM updates

Leverage subscriptions instead of constant re-renders

Security Notes

Escape user-provided HTML manually

Never interpolate raw HTML into VDOM

Validate form input on client/server

Use HTTPS for API calls

Careful with 3rd-party scripts due to small ecosystem

Monitoring Analytics

Custom logging via subscriptions

Track state transitions manually

Integrate with Sentry

Minimal overhead performance monitoring

Console tracing for actions

Code Quality

Use ESLint + Prettier

Keep actions pure

Avoid state mutations

Document subscriptions

Use TypeScript if desired

Practical Examples

Counters and toggles

Todo apps

Light dashboards

Landing pages with interactivity

Embedded widgets

Troubleshooting

Ensure actions return new state objects

Check that view returns valid VDOM

Verify no state mutation occurs

Ensure subscriptions are correctly defined

Check DOM mount target exists

Testing Guide

Test actions as pure functions

Unit test VDOM output

Snapshot test components

Mock subscriptions

Use JSDOM for DOM tests

Deployment Options

Static hosting (Netlify/Vercel)

CDN embedding

Single-file deploy for micro-apps

Bundle with Vite/Webpack

Deploy inside other frameworks

Tools Ecosystem

Hyperapp core library

Community router packages

Community state utilities

Parcel/Vite integrations

Browser devtools (no official inspector)

Integrations

REST APIs via fetch

GraphQL via fetch or clients

Tailwind or vanilla CSS

Bundlers like Vite/Parcel

Testing with Jest

Productivity Tips

Use small pure components

Organize actions logically

Leverage subscriptions instead of loops

Compose UI declaratively

Avoid unnecessary libraries

Challenges

Build a counter with subscriptions

Create a Todo app

Componentize UI sections

Implement router manually

Build a small PWA

Learning Path

Learn Hyperapp state/actions

Understand VDOM and view functions

Learn subscriptions

Build reusable components

Explore community plugins

Skill Improvement Plan

Week 1: State & actions basics

Week 2: Components and VDOM patterns

Week 3: Subscriptions & effects

Week 4: Modular app architecture

Week 5: Bundling, performance, patterns

Interview Questions

Explain Hyperapp’s functional architecture.

How do actions work?

What is Hyperapp’s virtual DOM?

Explain subscriptions.

Why would you choose Hyperapp over React?

Cheat Sheet

`h()` - create VDOM nodes

`app()` - initialize app

Actions: `(state, data) => newState`

View: `(state) => h('div', {}, ...)`

Subscriptions: `[effect, data]`

Books

Hyperapp Essentials (community ebook)

Building Functional UIs with Hyperapp

Microfrontend Architecture with Hyperapp

Hyperapp Patterns & Recipes

Minimalist JavaScript UI Design

Tutorials

Hyperapp official guide

Dev.to Hyperapp tutorials

YouTube Hyperapp walkthroughs

Community blog series

GitHub example apps

Official Docs

https://hyperapp.dev

https://github.com/jorgebucaran/hyperapp

https://hyperapp.dev/guide

Community Links

Hyperapp GitHub

Hyperapp Discussions

Dev.to Hyperapp tag

StackOverflow Hyperapp

Hyperapp Discord

Community Support

GitHub issues

Hyperapp discussions

Small but active community on Discord

StackOverflow tag

Minimal but helpful blog posts

Monetization

Build lightweight SaaS widgets

Develop embeddable UI kits

IoT dashboards

Custom dev tools

Micro-app consulting

Future Roadmap

Better TypeScript integrations

Modern routing solutions

Community-driven ecosystem

More patterns and best practices

Improved devtools and debugging

When Not To Use

Large-scale enterprise applications

Teams requiring huge ecosystems

Apps needing SSR or hydration natively

Developers unfamiliar with functional patterns

Projects needing advanced routing or animations out-of-the-box

Final Summary

Hyperapp is a tiny, functional UI library for predictable web apps.

Ideal for microtools, widgets, and performance-critical interfaces.

Maintains Elm-like purity without heavy constraints.

Simple architecture of state, actions, and views.

Perfect for devs who want minimalism and clarity.

Faq

Is Hyperapp really only 1 KB?

Yes, production builds are extremely small.

Does Hyperapp use a virtual DOM?

Yes, a tiny and fast one.

Do I need a build tool?

No, but you can use one.

Is routing included?

No, use community routers.

Is Hyperapp beginner-friendly?

Yes - simple mental model and small API.

Code Sample Descriptions

1

Hyperapp Simple Counter

import { h, app } from 'https://unpkg.com/hyperapp?module';

const state = { count: 0, isDark: false };
const actions = {
    increment: () => s => ({ count: s.count + 1 }),
    decrement: () => s => ({ count: s.count - 1 }),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ isDark: !s.isDark })
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+'),
        h('button', { onclick: a.decrement }, '-'),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Switch to ' + (s.isDark ? 'Light' : 'Dark') + ' Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Basic counter with increment, decrement, reset, and theme toggle.

Let’s Try →
2

Hyperapp Counter with Step

import { h, app } from 'https://unpkg.com/hyperapp?module';
const state = { count: 0, step: 5, isDark: false };
const actions = {
    increment: () => s => ({ count: s.count + s.step }),
    decrement: () => s => ({ count: s.count - s.step }),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ isDark: !s.isDark })
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+ ' + s.step),
        h('button', { onclick: a.decrement }, '- ' + s.step),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Switch Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Counter increments/decrements by a custom step value.

Let’s Try →
3

Hyperapp Counter with Max/Min

import { h, app } from 'https://unpkg.com/hyperapp?module';
const state = { count: 0, min: 0, max: 10, isDark: false };
const actions = {
    increment: () => s => (s.count < s.max ? { count: s.count + 1 } : {}),
    decrement: () => s => (s.count > s.min ? { count: s.count - 1 } : {}),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ isDark: !s.isDark })
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+'),
        h('button', { onclick: a.decrement }, '-'),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Toggle Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Counter that respects maximum and minimum limits.

Let’s Try →
4

Hyperapp Counter with Auto Increment

import { h, app } from 'https://unpkg.com/hyperapp?module';
const state = { count: 0, isDark: false, auto: false };
const actions = {
    increment: () => s => ({ count: s.count + 1 }),
    decrement: () => s => ({ count: s.count - 1 }),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ isDark: !s.isDark }),
    toggleAuto: () => s => {
        if (!s.auto) { s.timer = setInterval(() => actions.increment(), 1000); }
        else clearInterval(s.timer);
        return { auto: !s.auto };
    }
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+'),
        h('button', { onclick: a.decrement }, '-'),
        h('button', { onclick: a.reset }, 'Reset'),
        h('button', { onclick: a.toggleAuto }, s.auto ? 'Stop Auto' : 'Start Auto')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Toggle Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Counter that automatically increments every second.

Let’s Try →
5

Hyperapp Counter with Double Increment

import { h, app } from 'https://unpkg.com/hyperapp?module';
const state = { count: 0, isDark: false };
const actions = {
    increment: () => s => ({ count: s.count + 1 }),
    doubleIncrement: () => s => ({ count: s.count + 2 }),
    decrement: () => s => ({ count: s.count - 1 }),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ isDark: !s.isDark })
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+'),
        h('button', { onclick: a.doubleIncrement }, '++'),
        h('button', { onclick: a.decrement }, '-'),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Toggle Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Counter increments by 2 with a special button.

Let’s Try →
6

Hyperapp Counter with Even/Odd Indicator

import { h, app } from 'https://unpkg.com/hyperapp?module';
const state = { count: 0, isDark: false };
const actions = {
    increment: () => s => ({ count: s.count + 1 }),
    decrement: () => s => ({ count: s.count - 1 }),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ isDark: !s.isDark })
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count + ' (' + (s.count % 2 === 0 ? 'Even' : 'Odd') + ')'),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+'),
        h('button', { onclick: a.decrement }, '-'),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Toggle Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Displays whether the count is even or odd.

Let’s Try →
7

Hyperapp Counter with Max/Min and Step

import { h, app } from 'https://unpkg.com/hyperapp?module';
const state = { count: 0, step: 5, min: 0, max: 50, isDark: false };
const actions = {
    increment: () => s => (s.count + s.step <= s.max ? { count: s.count + s.step } : {}),
    decrement: () => s => (s.count - s.step >= s.min ? { count: s.count - s.step } : {}),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ isDark: !s.isDark })
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+ ' + s.step),
        h('button', { onclick: a.decrement }, '- ' + s.step),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Toggle Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Counter with custom step and limits.

Let’s Try →
8

Hyperapp Counter with LocalStorage

import { h, app } from 'https://unpkg.com/hyperapp?module';
const state = { count: parseInt(localStorage.getItem('count')||0), isDark: false };
const actions = {
    increment: () => s => { const count = s.count + 1; localStorage.setItem('count', count); return { count }; },
    decrement: () => s => { const count = s.count - 1; localStorage.setItem('count', count); return { count }; },
    reset: () => s => { localStorage.setItem('count', 0); return { count: 0 }; },
    toggleTheme: () => s => ({ isDark: !s.isDark })
};
const view = (s, a) => (
    h('div', { class: s.isDark ? 'dark-theme' : 'light-theme' }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+'),
        h('button', { onclick: a.decrement }, '-'),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Toggle Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Counter persists value in localStorage.

Let’s Try →
9

Hyperapp Counter with Color Themes

import { h, app } from 'https://unpkg.com/hyperapp?module';
const themes = ['light-theme','dark-theme','blue-theme'];
const state = { count: 0, current: 0, theme: themes[0] };
const actions = {
    increment: () => s => ({ count: s.count + 1 }),
    decrement: () => s => ({ count: s.count - 1 }),
    reset: () => s => ({ count: 0 }),
    toggleTheme: () => s => ({ current: (s.current+1)%themes.length, theme: themes[(s.current+1)%themes.length] })
};
const view = (s, a) => (
    h('div', { class: s.theme }, [
        h('h2', {}, 'Counter: ' + s.count),
        h('div', {}, [
        h('button', { onclick: a.increment }, '+'),
        h('button', { onclick: a.decrement }, '-'),
        h('button', { onclick: a.reset }, 'Reset')
        ]),
        h('button', { onclick: a.toggleTheme }, 'Switch Theme')
    ])
);
app({ init: state, view, node: document.body, actions });

Counter cycles through multiple color themes.

Let’s Try →

Frequently Asked Questions about Hyperapp

What is Hyperapp?

Hyperapp is an ultra-lightweight (≈1 KB), functional JavaScript library for building user interfaces using a minimalist architecture of state, actions, and a virtual DOM. It emphasizes simplicity, purity, and predictable UI updates.

What are the primary use cases for Hyperapp?

Tiny SPAs or micro-frontends. Browser extensions. IoT dashboards. Static sites with light interactivity. Widgets or embeddable UI components

What are the strengths of Hyperapp?

Extremely lightweight. Highly predictable architecture. Easy learning curve. Works without build tools. Ideal for embedded or performance-critical apps

What are the limitations of Hyperapp?

Smaller ecosystem than React/Vue. Minimal built-in tooling. No official router or complex ecosystem. Not ideal for huge enterprise applications. Requires comfort with functional programming

How can I practice Hyperapp typing speed?

CodeSpeedTest offers 9+ real Hyperapp code examples for typing practice. You can measure your WPM, track accuracy, and improve your coding speed with guided exercises.

Learn Other Programming Languages

CReactPythonC++RustTypeScriptKotlinPHPJavaC#RubyMqlCqlN1qlCypherGremlinPartiqlHaskellElixirFsharpView all languages →
CodeSpeedTest

Improve your coding speed, code accuracy, and programming syntax WPM with practice sessions across 500+ programming languages.

Quick Links

HomeAboutFeaturesGetting StartedLanguages

Legal & Support

Pro ⚡ PricingContactPrivacy PolicyTerms of Service

Connect

CodeSpeedTest on GitHubCodeSpeedTest on TwitterEmail CodeSpeedTest

© 2026 CodeSpeedTest. All rights reserved.