Skip to content

jbeshir/beshir-widgets

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

123 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

beshir-widgets

Small, experimental web widgets — quickly generated by AI to visualise or demonstrate an idea. Each is an independent, iframe-embeddable Vite SPA, deployed automatically to its own subdomain on Cloudflare Workers via GitHub Actions, and designed to be embedded in any page without coordination with the host origin. Treat them as quick demos, not production-grade components.

Widget index

Widget Live URL Description
function-plotter https://function-plotter.widgets.beshir.org Plot any function of x as an SVG curve.
image-comparison-table https://image-comparison-table.widgets.beshir.org Side-by-side comparison grids of labelled images, with click-to-zoom lightbox and per-row prompt info.
japanese-verb-tower https://japanese-verb-tower.widgets.beshir.org Assemble a Japanese verb morpheme-by-morpheme through its conjugation layers; search 26,784 verbs by romaji, kana, or kanji.
pennsic-planner https://pennsic-planner.widgets.beshir.org Browse the Pennsic 53 (2026) class schedule and build a shareable personal calendar with conflict detection and .ics export.

Embedding

<iframe src="https://function-plotter.widgets.beshir.org" loading="lazy" style="width:100%;height:480px;border:0"></iframe>

Default stack

  • Runtime: Preact core (not React). Tiny, framework-agnostic libraries pair well with it; React-only packages should generally be avoided unless they justify the preact/compat cost.
  • Charts: Observable Plot (@observablehq/plot) as the default for chart-like widgets — grammar-of-graphics, SVG output, no CDN required.
  • Don't optimize for bundle size. Pick whatever makes the best widget; ~400 KB gzip is a comfortable ceiling, and larger is fine when it's the best fit (show a loading state if it's big or waits on data). Reserve caution for true heavyweights like Plotly or MathJax.
  • See LIBRARIES.md for the curated library menu, and DATA.md for the per-widget data contract (static / prebake / live).
  • Widgets must render offline in dev and the render check — bundle the code, and data widgets ship a sample (see DATA.md). In production a widget may fetch at runtime (live data, map tiles); prefer bundling for reliability and give remote data a loading state.

Per-widget convention

Each widget lives under widgets/<slug>/ and contains:

  • package.json — npm manifest with build scripts
  • package-lock.json — lockfile committed to the repo
  • widget.json — metadata: slug, title, description, build config, Cloudflare routing
  • wrangler.jsonc — Cloudflare Workers deployment config

The slug determines the worker name (widget-<slug>) and the hostname (<slug>.widgets.beshir.org).

CI deploys

Pushes to main trigger .github/workflows/deploy-widgets.yml, which discovers all widget directories, builds each one with npm ci && npm run build, and deploys via wrangler deploy. Pull requests trigger .github/workflows/check-widgets.yml, which validates all widget.json/wrangler.jsonc configs and builds each widget without deploying.

Cloudflare setup (one-time, manual)

  • Create a Cloudflare API token with account scope Workers Scripts: Edit plus zone scope (beshir.org) Workers Routes: Edit. Do NOT grant DNS: Write; custom_domain: true in wrangler.jsonc provisions DNS automatically.
  • Add GitHub repo secrets CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.
  • Ensure no conflicting CNAME exists on the widget hostnames before first deploy.

New widgets

New widgets are normally scaffolded via the build-widget Claude skill, which copies the function-plotter template and customises it.

About

Independent, iframe-embeddable web widgets, each auto-deployed to its own subdomain on Cloudflare Workers.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors