What's New

July 12, 2025, V3.35.0

Support auto use router for pretty links

AppRun now supports pretty links.

<a href="/about">About</a>

You can subscribe components to events like '/about'.

// Routing (component event)
class Home extends Component {
  view = () => <div>Home</div>;
  update = {'/, /home': state => state };
}

class Contact extends Component {
  view = () => <div>Contact</div>;
  update = {'/contact': state => state };
}

class About extends Component {
  view = () => <div>About</div>;
  update = {'/about': state => state };
}

const App = () => <>
  <div id="menus">
    <a href="/home">Home</a>{' | '}
    <a href="/contact">Contact</a>{' | '}
    <a href="/about">About</a></div>
  <div id="pages"></div>
</>

app.render(document.body, <App />);
[About, Contact, Home].map(C => new C().start('pages'));

AppRun will catch the '/about' route as event and render the component that is subscribed to it.

If you have components subscribe to '#', or '#/', Apprun will fallback to the hash-based routing.

July 6, 2025, V3.33.10

Support async generator for event handlers

You can now use async generator functions for event handlers. The async generator function can return multiple values. AppRun will render each value in the order they are generated.

  const state = {};
  const view = state => html`
  <div><button @click=${run(getComic)}>fetch ...</button></div>
  ${state.loading && html`<div>loading ... </div>`}
  ${state.comic && html`<img src=${state.comic.img} />`}
`;
  async function* getComic() {  // async generator function returns loading flag and then the comic object
    yield { loading: true };
    const response = await fetch('https://my-xkcd-api.glitch.me');
    const comic = await response.json();
    yield { comic };
  }

  app.start(document.body, state, view);

use lit-html V3 for apprun-html.js

The apprun-html.js now uses lit-html V3 for rendering the view. The apprun-html.js is a standalone version of AppRun that uses lit-html for rendering the view without JSX.

<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Counter</title>
</head>
<body>
  <script src="https://unpkg.com/dist/apprun-html"></script>
  <script>
  const add = (state, delta) => state + delta;
  const view = state => {
    return html`<div>
    <h1>${state}</h1>
      <button @click=${run(add, -1)}>-1</button>
      <button @click=${run(add, +1)}>+1</button>
    </div>`;
  };
  app.start(document.body, 0, view);
  </script>
</body>

</html>

Aug 12, 2024, V3.33.4

Add app.use_render and app.use_react function

The app.use_render function allows you to use a custom render function for rendering the view. The app.use_react function allows you to use React for rendering the view.

import ReactDOM from 'react-dom/client'
import { flushSync } from 'react-dom';
import app from 'apprun';
use_react(React, ReactDOM);

See https://github.com/yysun/apprun-antd-demo-js for an example.

Support the mounted function when starting a component manually

Dec, 8, 2023

When using a component in JSX, AppRun always invokes the the mounted lifecycle function each time the component is loaded.

class ComponentClass extends Component {
  mounted = () => console.log('mounted is called');
}
app.render(document.body, <ComponentClass />);

However, the mounted function is not called when you start the component manully in the previous versions.

class ComponentClass extends Component {
  mounted = () => console.log('mounted is called'); // not called in previous versions
}
new ComponentClass().start(document.body);

Now, the mounted function is called when the component is started.

class ComponentClass extends Component {
  mounted = () => console.log('mounted is called'); // called in this version
}
new ComponentClass().start(document.body);

This change make the mounted funciton compatible in JSX and in manual start.

Support View Transition API

September, 27, 2023

AppRun now supports the View Transition API at the event level, component level and app level.

Event level example:

const update = {
  '+1': [state => state + 1, {transition: true}],
  '-1': [state => state - 1, {transition: true}]
};

Component level example:

class C extends Component {

}
new C().mount(document.body, {transition: true});

App level example:

app.start(document.body, {transition: true});

Vite Support

December 11, 2022

The command npm create apprun-app supports Vite in addition to esbuild and webpack.

Use React for Rendering View

You can use React for rendering view. See apprun-use-react for details.

React 18 has breaking changes. Please use React 17 for now.

Create-AppRun-App CLI

April 5 , 2022

You can create an AppRun app by running command npm create apprun-app.

npm create apprun-app [my-app]

Note: AppRun CLI npx apprun init is deprecated. Please use npm create apprun-app instead.

Recent Posts and Publications

All the Ways to Make a Web Component - May 2021 Update

This post compares the coding style, bundle size, and performance of 55 different ways to make a Web Component. It put AppRun on the top 1/3 of the list of bundle size and performance.

A Dev Server Supports ESM

This post introduces apprun-dev-server, a dev server that provides fast and productive experiences to AppRun application development, so-called unbundled development.

Observerble HQ Notebooks

Rust WebAssembly and AppRun

Serverless App Using Firebase and AppRun

Avoid Spaghetti Code using AppRun

Create a Phoenix LiveView Like App in JS with AppRun

Reactivity in AppRun

AppRun Event Directives

Ceremony vs. Essence Revisited

Database-Driven Applications Using WebSockets

This post introduces a new application architecture that allows event handling between the frontend apps and the backend business logic modules without REST API.

Published on Mar 9, 2020 6 min read

Use State Machine in AppRun Applications

This post describes how to create a state machine in AppRun applications to help event handling using a calculator as an example.

Published on Mar 3, 2020 ・ 6 min read

Advanced View Features in AppRun

This post describes the advanced usage of the AppRun ref, element embedding, and directive in the JSX view.

Published on Feb 28, 2020 ・ 4 min read

Strong Typing in AppRun

This post is a complete guide for those want to opted-in TypeScript and strong typing for AppRun application development.

Published on May 17, 2019 · 8 min read

Announcing AppRun Directives

This post introduces the two built-in directives and then describes how to create custom directives.

Published on May 12, 2019 · 3 min read

AppRun Book from Apress

Order from Amazon

Published on Jan 9, 2019

Make CLI Run in the Console

We have been using the command-line interface (CLI) in the terminal window and the command prompt. Have you thought of a CLI in the console of the browser's developer tool?

Published on Aug 10, 2018 · 1 min read

Making ASP.NET Core MVC Apps into Single Page Apps using AppRun

A single-page application (SPA) is a web application or web site that interacts with the user by dynamically rewriting the current page…

Published on Aug 7, 2018 · 3 min read

I Also Created the Exact Same App Using AppRun

I felt it was quite fun to compare AppRun with Redux and React Context API last time. Today, I found another great post titled “I created…

Published on Aug 5, 2018 · 7 min read

Redux vs. The React Context API vs. AppRun

Recently, I have read a great post titled ‘Redux vs. The React Context API’ (https://daveceddia.com/context-api-vs-redux). It is the type…

Published on Jul 31, 2018 · 3 min read

Deep Dive into AppRun Events

Published on Sep 10, 2017 · 8 min read

Deep Dive into AppRun State

Published on Sep 9, 2017 · 6 min read

Building Applications with AppRun

AppRun is a Javascript library for building reliable, high-performance web applications using the Elm inspired Architecture, events and components.

Published on Jul 2, 2017 · 5 min read

Video Tutorials