StencilJS-powered web components for feature-flag previews, bundled with tsdown and shipped as ESM-only via Bun.
bun install
# scripts
bun run dev # watch build
bun run build # stencil build + tsdown bundle
bun run lint # biome
bun run test # vitestimport { registerFeatureFlagComponents } from '@example/feature-flags-wc';
await registerFeatureFlagComponents();<feature-flag-preview-modal
id="feature-preview-modal"
open
api-endpoint="https://flags.basestack.co/api/v1/flags/preview"
project-key="YOUR_PROJECT_KEY"
storage-key="bs-flags-preview-state"
heading="Feature preview dialog"
subtitle="Select and enable previews tailored to your workflow."
selection-prompt="Select a preview to inspect"
selection-placeholder="Choose a feature on the left to preview its details."
enable-label="Enable"
enabled-label="Enabled"
loading-label="Loading feature previews…"
empty-label="No feature flags are available right now."
></feature-flag-preview-modal>
<script>
const modal = document.getElementById("feature-preview-modal");
if (modal) {
modal.metadata = {
user: { id: "usr_123" },
payment: { plan: "pro" },
};
}
</script>- When
api-endpointis omitted, the component useshttps://flags.basestack.co/api/v1/flags/preview. - Provide either
project-key(headerx-project-key) orenvironment-key(headerx-environment-key) for the Basestack API. If neither is provided, built-in mock flags are shown. - The component sends a
POSTrequest to the preview endpoint and supports optionalmetadatain the request JSON body. - User choices are persisted to
localStorageunderstorage-key. - All user-facing labels (heading, subtitle, prompts, button text, badges, empty/loading states) are optional attributes so you can localize or reword them per embed.
- The SDK helpers exported from
src/sdkgive you headless access to fetching and storage logic.
<feature-flag-feedback-modal
open
flag-key="command-palette"
feature-name="Command palette"
project-key="YOUR_PROJECT_KEY"
environment-key="YOUR_ENVIRONMENT_KEY"
heading="Feedback"
mood-prompt="How did this feature make you feel?"
rating-prompt="How would you rate the quality of this feature?"
feedback-label="Your feedback"
feedback-placeholder="Anything you'd like to add? Your input is valuable to us"
submit-label="Send Feedback"
></feature-flag-feedback-modal>- Feedback is sent to
https://flags-api.basestack.co/v1/flags/feedback/:flagKeywith the appropriatex-project-keyorx-environment-keyheader.
This package has a dual-build architecture using two separate tools:
Stencil compiles the web components (<feature-flag-preview-modal>, <feature-flag-feedback-modal>) into framework-agnostic custom elements.
- Output:
dist/components/ - Usage: Components are self-contained and can be used directly without the SDK
// Direct component usage (no SDK)
import { defineCustomElement } from '@basestack/flags-wc/components/feature-flag-preview-modal';
defineCustomElement();tsdown bundles the SDK layer — a lightweight wrapper that provides:
-
Re-exported utilities and TypeScript types
-
Output:
dist/sdk/ -
Entry:
src/sdk/index.ts
// SDK usage (recommended)
import { registerFeatureFlagComponents, FeatureFlagClient } from '@basestack/flags-wc';
await registerFeatureFlagComponents();| Tool | Purpose | Output |
|---|---|---|
| Stencil | Compiles .tsx components into native Web Components with Shadow DOM, scoped styles, and lazy-loading |
dist/components/ |
| tsdown | Bundles the SDK entry point with tree-shaking, minification, and TypeScript declarations | dist/sdk/ |
The components don't depend on the SDK — the SDK depends on the components. This means you can use the raw Stencil components directly if you prefer, or use the SDK for a more ergonomic developer experience.