npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yamato-daiwa/universal-reactive

v0.1.0

Published

OOP-based library for frontend development.

Readme

Yamato Daiwa Universal Reactive

What is Being Developed

The object-oriented programming-based library for the frontend Web+ development alternative to React, Vue, Svelte and the like.

No plans to position it as a framework because it is intended to be the just the tool taking care of typical frontend development tasks without stealing too much attention and forcing of specific architecture, naming and directories structure.

Features

The following feature may be pros of cons depending on your preferences.

  • Class-based components. No functional API planned.
  • Pug is the only language for templates. No plain HTML support planned.
  • No new file names extensions like .vue or .jsx.
  • No new syntaxes like Vue single file components or JSX. Just plain Pug and TypeScript.
  • Project building tool like Webpack is required.

Planned

The sequence may be changed during the development.

  • [ ] Conditional rendering
  • [ ] Iterative rendering
  • [ ] Nested components
  • [ ] Routing
  • [ ] Shared state
  • [ ] SSR

Quick Tutorials for React/Vue/Svelte Experiencers

Basic ~~"Hello, world"~~ Counter Application

Code

"Counter.ydfr.pug" — The Component Template
samp= $reactiveState.currentValue

.Counter-ActionBar

  button(
    type="button"
    @onLeftClick=onClickIncrementingButton
  ) Increment

  button(
    type="button"
    @onLeftClick=onClickDecrementingButton
  ) Decrement

The YDUR components templates are been defined by Pug, the template language. No plans to support HTML.

Counter.ts — The Component Logic
import * as YDFR from "@yamato-daiwa/universal-reactive";
import componentTemplate from "./Counter.ydur.pug";


@YDFR.View(componentTemplate)
export default class Counter extends YDFR.Component {

  @YDFR.ReactiveState
  protected currentValue: number = 0;

  @YDFR.EventHandler()
  protected onClickIncrementingButton(): void {
    this.currentValue++;
  }

  @YDFR.EventHandler()
  protected onClickDecrementingButton(): void {
    this.currentValue--;
  }

}
  • The component logic is the plain TypeScript class with decorators. Besides its main role, you can use it as the plain TypeScript classes, for example, define the public static members and call them from outside (when it makes sense).
  • To import componentTemplate from Pug file correctly, you need the appropriate plugin for you project building system. Currently, the Webpack loader is available. The value of componentTemplate is not the string with HTML code — the YDUR templates compiler builds the JavaScript object called "View" based on Pug code. Such an approach is Svelte-like, one advantage of it is better performance than DOM diffing as in React.
  • The currentValue field has been declared with @YDFR.ReactiveState decorator. It means the changing of this field will update the DOM depends on it. currentValue is accessible from template as $reativeState.currentValue. Contrary to $reativeState state, there is the $constantState one.
  • The methods are accessible from the template by names as event handlers, but must be decorated by @YDFR.EventHandler() decoratory. Unlike @YDFR.ReactiveState, it requires () becaue optionally the event hanling options may be passed.
  • You can make all instance members private in this example, but the TypeScript and/all linting tool may complain about these fields have not been explicitly used.
index.ts — The Entry Point
import * as YDFR from "@yamato-daiwa/universal-reactive";
import Counter from "./GUI_Components/Counter";


YDFR.initializeFrontendApplication({
  mountingPointSelector: "#APPLICATION_ROOT",
  rootComponent: Counter
});

You need at least one component to create the application instance. Once it defined, the application may be created by one function. Of course, the HTML element with ID APPLICATION_ROOT must exist to initialize the application succesfully.

Reactive and Constant State

Some state fields are not intended to be updated during the component lifecycle. It means no need to make them to a reactive state for performance purposes. As default, the class fields are not accessible from template, but to declare the constant state field you can use the @YDFR.ConstantState field:

import * as YDFR from "@yamato-daiwa/universal-reactive";
import componentTemplate from "./Counter.ydur.pug";


@YDFR.View(componentTemplate)
export default class Counter extends YDFR.Component {

  // Basically, should be set to `readonly` but we will try to change it for experiment.
  @YDFR.ConstantState
  protected heading: string = "Counter";
  
  @YDFR.ReactiveState
  public currentValue: number = 0;

  @YDFR.EventHandler()
  public onClickIncrementingButton(): void {
    
    this.currentValue++;
    
    // You will get TypeError if try to chage it. Of course, DOM dependes in this firld will not be updated.
    this.heading = "NEW HEADING"
    
  }

  @YDFR.EventHandler()
  public onClickDecrementingButton(): void {
    this.currentValue--;
  }

}

You can access to heading in template via $constantState object:

h1= $constantState.heading

samp= $reativeState.currentValue

.Counter-ActionBar

  button(
    type="button"
    @onLeftClick=onClickIncrementingButton
  ) Increment

  button(
    type="button"
    @onLeftClick=onClickDecrementingButton
  ) Decrement

Events Handling

You can access to instance methods by name from template if they has been decorated by @YDFR.EventHandler():

@YDFR.View(componentTemplate)
export default class Counter extends YDFR.Component {

  // ...

  @YDFR.EventHandler()
  public onClickIncrementingButton(): void {
    // ...
  }

  @YDFR.EventHandler()
  public onClickDecrementingButton(): void {
    // ...
  }

}

Unlike @YDFR.ReactiveState or @YDFR.ConstantState, @YDFR.EventHandler decorator must be invoked because the optons may be passed:

type Options = Readonly<{
  
  /* @default EventPropagationTypes.bubbling */
  eventPropagation?: EventPropagationTypes | false;
  
  /* @default false */
  mustBeCalledOnce?: boolean;
  
  /* @default false */
  mustKeepDefaultBehaviour?: boolean;
  
}>;

enum EventPropagationTypes {
  bubbling = "BUBBLING",
  capturing = "CAPTURING"
}

The names of the options has been designed such as does not need any explanations.

If you don't know about bubbling and capturing, it is a common terminology, not terminology of YDR. Check this tutorial for details.

Once decorated, the method can be referred from the template by the following attributes.

.Counter-ActionBar

  button(
    type="button"
    @onLeftClick=onClickIncrementingButton
  ) Increment

  button(
    type="button"
    @onLeftClick=onClickDecrementingButton
  ) Decrement

Currently available events name listed below.

Mouse Events

| YDUR Event Name | Native event name | |--------------------|-------------------| | @onLeftClick | click | | @onDoubleLeftClick | dblclick | | @onRightClick | auxclick | | @onMouseDown | mousedown | | @onMouseUp | mouseup | | @onMouseMoved | mousemove | | @onMouseOver | mouseover | | @onMouseOut | mouseout | | @onMouseEntered | mouseenter | | @onMouseLeft | mouseleave |

Keyboard Events

| YDUR Event Name | Native event name | |-----------------|-------------------| | @onKeyPressed | keyup | | @onKeyUp | keyup | | @onKeyDown | keydown | | @onInput | input |

Common Events

| YDUR Event Name | Native event name | |-----------------|-------------------| | @onChange | change |