Reactive components using a virtual DOM