liveBook · Manning

Application instance

As explained in Build a Frontend Web Framework (From Scratch)

An application instance is an object representing a running frontend application and connecting its state manager with its renderer.

An application instance is the object that brings a state manager and renderer together to represent a running frontend application. It manages lifecycle work: holding state, rendering views, and responding to user input. section 5.2 section 5.2.1

A basic application instance coordinates:

  • Initial state, reducers, and the top-level component supplied by the developer. section 5.2.1
  • A renderer and state manager instantiated and connected by the framework. section 5.2.1
  • A mount() method that receives a DOM element and starts the application lifecycle. section 5.2.1
  • Rendering that replaces the current DOM tree and mounts a new view when rendering occurs. section 5.2.2

Minimal renderer

createApp({ state, view }) keeps parentEl and the previous virtual DOM in a closure. mount() saves the parent element, computes view(state), and mounts the result. Later, the state manager can trigger another render. section 5.2.2

Listing 5.5 The application instance with its renderer (app.js)
import { destroyDOM } from './destroy-dom'
import { mountDOM } from './mount-dom'

export function createApp({ state, view }) {     #1
  let parentEl = null
  let vdom = null

  function renderApp() {
    if (vdom) {
      destroyDOM(vdom)    #2
    }

    vdom = view(state) 
    mountDOM(vdom, parentEl)     #3
  }

  return {
    mount(_parentEl) {       #4
      parentEl = _parentEl
      renderApp()
    },
  }
}

Inspect the incremental JavaScript implementation of createApp(), including virtual-DOM tracking, rendering, and mounting. section 5.2.2

Listing 12.7 The application instance (app.js)
import { mountDOM } from './mount-dom'
import { destroyDOM } from './destroy-dom'
import { h } from './h'

export function createApp(RootComponent, props = {}) {  #1
  let parentEl = null
  let isMounted = false
  let vdom = null

  function reset() {           #2
    parentEl = null
    isMounted = false
    vdom = null
  }
  return {
    mount(_parentEl) {
      if (isMounted) {  #3
        throw new Error('The application is already mounted')
      }

      parentEl = _parentEl  #4
      vdom = h(RootComponent, props)  #5
      mountDOM(vdom, parentEl)  #6

      isMounted = true
    },

    unmount() {
      if (!isMounted) {                              #7
        throw new Error('The application is not mounted')
      }

      destroyDOM(vdom)  #8
      reset()  #9
    },
  }
}

Compare the later component-based design, where createApp() accepts a root component and props, exposes mount() and unmount(), and rejects invalid lifecycle calls. section 12.4

How Build a Frontend Web Framework (From Scratch) covers it

How deep it goes
Builds a minimal renderer with closures, virtual-DOM tracking, mounting, and later unmounting; defers complete production behavior.
Examples
Uses createApp(), mount(), renderApp(), virtual-DOM storage, and a root-component implementation with mount() and unmount().
What it assumes
Assumes JavaScript functions and DOM concepts while introducing framework-level connections among state, views, and rendering.
What you can do after
Build it from scratch by implementing createApp(), mounting a view, and extending it with state updates or component lifecycle controls.
How it connects
Connects the state manager, renderer, reducers, virtual DOM, components, and application lifecycle.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build a Frontend Web Framework (From Scratch). The section links point to the parts of the book it draws on.