Agent Skill
2/7/2026

session-retrospective

セッション終盤に知見を振り返り、ドキュメントや skill への落とし込みを行う。作業の区切りで使用。

C
cwd
0GitHub Stars
1Views
npx skills add cwd-k2/ydant

SKILL.md

Namesession-retrospective
Descriptionセッション終盤に知見を振り返り、ドキュメントや skill への落とし込みを行う。作業の区切りで使用。

Ydant

You Don't Actually Need This - A generator-based DOM rendering DSL for JavaScript.

日本語版 README

What is this?

Ydant is an experimental UI library that uses JavaScript generators as a domain-specific language for building DOM structures. It's deliberately minimal and unconventional—a playground for exploring what's possible when generators meet the DOM.

import { scope } from "@ydant/core";
import {
  createDOMBackend,
  createBasePlugin,
  div,
  button,
  text,
  refresh,
  type Slot,
} from "@ydant/base";

function Counter(initial: number) {
  let count = initial;
  let countSlot: Slot;

  return div({ class: "counter" }, function* () {
    countSlot = yield* div(() => [text(`Count: ${count}`)]);

    yield* button(
      {
        onClick: () => {
          count++;
          refresh(countSlot, () => [text(`Count: ${count}`)]);
        },
      },
      "+1",
    );
  });
}

scope(createDOMBackend(document.getElementById("app")!), [createBasePlugin()]).mount(() =>
  Counter(0),
);

Features

  • Generator-based DSL - Use yield* to compose DOM elements naturally
  • Two syntaxes - Generator syntax for Slot access, array syntax for static structures
  • Simple function components - Plain functions that take props and return generators
  • Slot pattern - Fine-grained updates without virtual DOM diffing
  • Plugin architecture - Extensible renderer with signals, context, and more
  • Tiny footprint - No dependencies, minimal abstraction
  • TypeScript-first - Full type safety with tagged union types

Packages

PackageDescriptionREADME
@ydant/coreRendering engine, plugin systemDetails
@ydant/baseElement factories, primitives, SlotDetails
@ydant/reactiveSignal-based reactivityDetails
@ydant/contextContext APIDetails
@ydant/routerSPA routingDetails
@ydant/asyncSuspense, ErrorBoundaryDetails
@ydant/transitionCSS transitionsDetails
@ydant/canvasCanvas2D renderingDetails
@ydant/portalRender into alternate targetsDetails
@ydant/ssrServer-side rendering + HydrationDetails
@ydant/devtoolsEngine lifecycle observationDetails

Quick Start

import { mount, div, p, type Component } from "@ydant/base";

const App: Component = () =>
  div({ class: "app" }, function* () {
    yield* p("Hello, Ydant!");
  });

mount("#root", App);

With Plugins

import { mount, div, button, type Component } from "@ydant/base";
import { createReactivePlugin, signal, reactive } from "@ydant/reactive";
import { createContextPlugin } from "@ydant/context";

const count = signal(0);

const App: Component = () =>
  div(function* () {
    yield* reactive(() => [div(`Count: ${count()}`)]);
    yield* button({ onClick: () => count.update((n) => n + 1) }, "+1");
  });

mount("#root", App, {
  plugins: [createReactivePlugin(), createContextPlugin()],
});

For advanced use cases (Canvas, SSR, embed), use scope() from @ydant/core directly.

Examples

ExampleDescription
showcase1Counter, Dialog - basic Slot usage
showcase2ToDo App - CRUD, localStorage
showcase3Pomodoro Timer - SVG, lifecycle
showcase4SPA - Router, Context, plugins
showcase5Sortable list - keyed() for efficient updates
showcase6Async - Suspense, ErrorBoundary
showcase7Transitions - enter/leave animations
showcase9Admin dashboard - router, auth, context
showcase10Form validation - dynamic rules
showcase11Canvas embed - DOM + Canvas2D hybrid
showcase12Portal for modal dialogs
showcase13SSR + Hydration
showcase14Reactive Canvas - signal-driven repaint
showcase15Multi-target dashboard (DOM/Canvas/SSR)
showcase16Priority-based rendering with Engine control
showcase17Inter-engine messaging via Hub
showcase18Multi-engine collaborative editing

Each example has a README with implementation tips. Run all examples:

pnpm run dev  # http://localhost:5173

Installation

npm install @ydant/core @ydant/base

Optional packages:

npm install @ydant/reactive   # Signal-based reactivity
npm install @ydant/context    # Context API
npm install @ydant/router     # SPA routing
npm install @ydant/async      # Suspense, ErrorBoundary
npm install @ydant/transition # CSS transitions
npm install @ydant/canvas    # Canvas2D rendering
npm install @ydant/portal    # Render into alternate targets
npm install @ydant/ssr       # Server-side rendering + Hydration

Development

git clone https://github.com/cwd-k2/ydant.git
cd ydant
pnpm install        # Install dependencies
pnpm -r run build   # Build all packages
pnpm run dev        # Run unified dev server
pnpm test           # Run tests (watch mode)
pnpm test:run       # Run tests (single run)
pnpm test:coverage  # Run tests with coverage

Why "You Don't Actually Need This"?

Because you probably don't. This is an experiment in alternative approaches to UI development. If you're building production software, you should probably use React, Vue, Svelte, or SolidJS.

But if you're curious about:

  • How generators can be used as a DSL
  • Fine-grained reactivity without virtual DOM
  • Minimal abstractions over the DOM

...then maybe you'll find something interesting here.

License

MIT

Skills Info
Original Name:session-retrospectiveAuthor:cwd