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

@youneed/dom-provider-feature-flags

v0.1.0

Published

Use @youneed/feature-flags inside @youneed/dom components — evaluate flags in html templates with reactive re-render on flag change, plus SSR hydration.

Readme

@youneed/dom-provider-feature-flags

Use @youneed/feature-flags inside @youneed/dom components — evaluate a flag straight in an html template, and have the component re-render when the flag changes (an override, or the source reloading).

import { Component, html, when } from "@youneed/dom";
import { createFlags } from "@youneed/feature-flags";
import { provideFlags, flags, flagged } from "@youneed/dom-provider-feature-flags";

provideFlags(createFlags([{ key: "new-dashboard", defaultValue: false }]));

class Dashboard extends Component() {
  constructor() {
    super();
    flagged(this); // ← re-render on every flag change
  }
  render() {
    return when(flags().isEnabled("new-dashboard"), () => html`<new-ui></new-ui>`);
  }
}

flags() returns the app-wide engine installed by provideFlags(...); its synchronous isEnabled / variant / value / all drop into any template hole. Reactivity is opt-in per component via flagged(this): it subscribes the host and calls requestUpdate() on every onChange (override / source reload), auto-unsubscribing on disconnect.

Scoped this.flags — the providers slot (recommended)

Component(tag, { providers: [...] }) is the DOM analogue of a server Controller's { guards, interceptors }: an array of orthogonal extensions that augment this. featureFlagsProvider(engine, { context }) adds a scoped this.flags — every call evaluates against the provider's context(), so you never thread the EvaluationContext through each check — AND automatic re-render on flag change (no flagged boilerplate). It composes with other providers (i18n, a11y, …) in the same array:

import { Component, html, when } from "@youneed/dom";
import { featureFlagsProvider } from "@youneed/dom-provider-feature-flags";

class Card extends Component("x-card", {
  providers: [featureFlagsProvider(engine, { context: () => ({ targetingKey: user.id }) })],
}) {
  render() {
    return when(this.flags.isEnabled("new-ui"), () => html`<new-ui></new-ui>`);
    //                ^ evaluated against the provider's context, re-renders on change
  }
}

this.flags exposes isEnabled(key), variant(key), value(key, fallback?), evaluate(key), and all() — each bound to the scoped context.

withFlags — the same, as a base-class mixin

Equivalent to a single featureFlagsProvider, in extends withFlags(Base, engine) form — handy when you're already chaining mixins:

import { withFlags } from "@youneed/dom-provider-feature-flags";
class Card extends withFlags(Component("x-card"), engine) {
  render() { return when(this.flags.isEnabled("new-ui"), () => html`<new-ui></new-ui>`); }
}

SSR → client hydration

The SSR plugin evaluates engine.all(ctx) on the server and serialises the record (e.g. window.__FLAGS__). On the client, hydrateFlags() rebuilds a read-only engine from it — no flag definitions shipped, values match exactly what the server rendered — and installs it as the app-wide engine:

import { hydrateFlags, flags } from "@youneed/dom-provider-feature-flags";

hydrateFlags();                 // reads window.__FLAGS__ (default)
// hydrateFlags("__MY_FLAGS__"); // pick a different global
// hydrateFlags(recordObject);   // or pass the snapshot record directly

flags().isEnabled("new-dashboard"); // ← same value the server rendered

API

| API | meaning | | --- | --- | | provideFlags(engine) | install the app-wide flags engine; returns it | | flags() / getFlags() | the active engine (throws if none provided) — for template holes | | flagged(host, engine?) | re-render host on flag change; auto-unsubscribes on disconnect | | featureFlagsProvider(engine, { context? }) | a ComponentProvider adding a scoped this.flags + auto reactivity | | withFlags(Base, engine, { context? }) | the mixin form of the same contribution | | hydrateFlags(snapshot?) | rebuild a read-only engine from an SSR snapshot (record or global name) and install it |

this.flags (from the provider / mixin): isEnabled(key), variant(key), value(key, fallback?), evaluate(key), all() — each evaluated against the provider's context() (default {}).