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

@rettangoli/fe

v1.4.1

Published

Frontend framework for building reactive web components

Readme

Rettangoli Frontend

A modern frontend framework that uses YAML for view definitions, web components for composition, and Immer for state management. Build reactive applications with minimal complexity using 4 types of files.

Features

  • 🗂️ Four-File Architecture - .view.yaml, .store.js, .handlers.js, .schema.yaml scale from single page to complex applications
  • 📝 YAML Views - Declarative UI definitions that compile to virtual DOM
  • 🧩 Web Components - Standards-based component architecture
  • 🔄 Reactive State - Immer-powered immutable state management
  • ⚡ Fast Development - Auto reload with Vite integration
  • 🎯 Template System - Jempl templating for dynamic content
  • 🧪 Testing Ready - Pure functions and dependency injection for easy testing

Quick Start

rtgl fe build     # Build components
rtgl fe watch     # Start dev server

Documentation

Architecture

Technology Stack

Runtime:

Build & Development:

  • Vite 8 - Rolldown-powered production bundling and dev server

Browser Native:

  • Web Components - Component encapsulation

Development

Prerequisites

  • Node.js 20.19+, Node.js 22.12+, or Bun
  • A rettangoli.config.yaml file in your project root

Setup

  1. Install dependencies:
bun install
  1. Create project structure:
# Scaffold a new component
node ../rettangoli-cli/cli.js fe scaffold --category components --component-name MyButton
  1. Start development:
# Build once
node ../rettangoli-cli/cli.js fe build

# Watch for changes (recommended)
node ../rettangoli-cli/cli.js fe watch

Project Structure

src/
├── cli/
│   ├── build.js       # Build component bundles
│   ├── watch.js       # Development server with auto reload
│   ├── scaffold.js    # Component scaffolding
│   ├── examples.js    # Generate examples for testing
│   └── blank/         # Component templates
├── createComponent.js # Component factory
├── createWebPatch.js  # Internal virtual DOM patching
├── parser.js          # YAML to JSON converter
├── common.js          # Shared utilities
└── index.js           # Main exports

Vite Integration

@rettangoli/fe uses Vite directly through the Node API, behind the existing FE CLI commands.

  • rtgl fe build uses Vite 8's Rolldown-powered vite.build() with a virtual entry module generated from configured component files.
  • rtgl fe watch uses vite.createServer(), warms the virtual entry during startup, and serves the configured outfile path via middleware.
  • Watch projects can configure fe.publicDir to serve static assets from the project root without Vite transformations.
  • fe.watchEntry can provide a project bootstrap module at the configured outfile URL. The module can register framework primitives and import virtual:rettangoli-fe-entry for Rettangoli component HMR.
  • FE runtime source is generated in memory (virtual module), so no temporary generated JS files are required.
  • Contract validation, YAML parsing, and template parsing still run before code generation.
  • Component directories, setup files, and locale files are registered explicitly so watch mode also sees sources outside the served static root.

Current Vite features used by FE:

  • Build API (build) for production bundles.
  • Dev Server API (createServer) for watch mode serving.
  • Custom plugin hooks:
    • resolveId + load for the FE virtual entry (virtual:rettangoli-fe-entry).
    • handleHotUpdate for FE file change detection.
    • configureServer for reload fallbacks and serving the configured output entry URL.
  • Rolldown output control through Vite (entryFileNames, chunkFileNames, assetFileNames) to preserve CLI outfile behavior.

Notes:

  • Watch mode preserves component instances and store state while applying compatible .view.yaml, .constants.yaml, .handlers.js, .methods.js, .store.js, and .schema.yaml edits through HMR. Locale YAML edits replace the development catalogs while retaining the selected locale and existing subscriptions.
  • Changes to setup and component file additions or removals perform a full reload because they can change registration or project topology. An update rejected by the runtime as incompatible, including a component-name or observed-prop change, also falls back to a full reload.
  • No dedicated CSS plugin pipeline is enabled in FE at this time.

Configuration

Create a rettangoli.config.yaml file in your project root:

fe:
  dirs:
    - "./src/components"
    - "./src/pages"
  setup: "setup.js"
  outfile: "./dist/bundle.js"
  publicDir: "./static"
  watchEntry: "./src/watch.js"
  i18n:
    dir: "./src/i18n"
    defaultLocale: "en"
    fallbackLocale: "en"
    locales:
      - "en"
      - "vi"
  examples:
    outputDir: "./vt/specs/examples"

publicDir is optional and only affects rtgl fe watch. Its files are served at / without Vite transformations. This is useful for extensionless or other binary assets that must retain their source filenames.

watchEntry is also watch-only. When present, that module is transformed and served at the outfile URL instead of serving the FE virtual entry directly. Import virtual:rettangoli-fe-entry from it to retain component HMR while adding project bootstrap code such as primitive custom-element registration.

Setup Contract

setup.js should export deps only. createWebPatch/h wiring is internalized by the framework.

const deps = {
  components: {},
  pages: {},
};

export { deps };

Action Listeners

In .view.yaml, listeners can dispatch store actions directly with action. This path auto-runs render after the action executes.

refs:
  inputEmail:
    eventListeners:
      input:
        action: setEmail
        payload:
          value: ${_event.target.value}

Store action:

export const setEmail = ({ state }, { value }) => {
  state.email = value;
};

Runtime-injected action payload fields:

  • _event
  • _action (internal dispatch metadata)

Testing

Unit and Contract Tests

  • Puty contract tests (spec/) — YAML-driven pure-function specs for view, store, schema, and handler contracts.
  • Vitest integration tests (test/) — runtime behavior tests for component lifecycle, props, events, and DOM.
bun run test           # all tests
bun run test:puty      # contract tests only
bun run test:vitest    # integration tests only

End-to-End Testing

FE has two E2E suites in this package:

  • packages/rettangoli-fe/e2e/dashboard
  • packages/rettangoli-fe/e2e/interactions

Use this workflow:

  1. Build FE with the local repo CLI (cli.js) so it uses your current FE source.
  2. Run VT in Docker for stable Playwright runtime.

Docker image:

IMAGE="han4wluc/rtgl:playwright-v1.57.0-rtgl-v1.1.0"

Dashboard suite:

(cd packages/rettangoli-fe/e2e/dashboard && node ../../../rettangoli-cli/cli.js fe build)
docker run --rm -v "$(pwd):/workspace" -w /workspace/packages/rettangoli-fe/e2e/dashboard "$IMAGE" rtgl vt screenshot
docker run --rm -v "$(pwd):/workspace" -w /workspace/packages/rettangoli-fe/e2e/dashboard "$IMAGE" rtgl vt report

Interactions suite:

(cd packages/rettangoli-fe/e2e/interactions && node ../../../rettangoli-cli/cli.js fe build)
docker run --rm -v "$(pwd):/workspace" -w /workspace/packages/rettangoli-fe/e2e/interactions "$IMAGE" rtgl vt screenshot
docker run --rm -v "$(pwd):/workspace" -w /workspace/packages/rettangoli-fe/e2e/interactions "$IMAGE" rtgl vt report

Accept intentional visual changes:

docker run --rm -v "$(pwd):/workspace" -w /workspace/packages/rettangoli-fe/e2e/dashboard "$IMAGE" rtgl vt accept
docker run --rm -v "$(pwd):/workspace" -w /workspace/packages/rettangoli-fe/e2e/interactions "$IMAGE" rtgl vt accept

VT specs live under each suite's vt/specs/ directory.

Examples

For a complete working example, see the todos app in examples/example1/.