Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 22 Sep 15:08
· 434 commits to main since this release

Eight new components (26 in total), a command contract that makes every value component CQRS-ready, continuous deployment, and a security, performance and SEO pass.

Added

  • 8 new components (18 → 26):
    • sb-nebula: a drifting WebGL nebula in dithered pixels. The first component that came in through the submission bot.
    • sb-theme-switch: auto, dark or light (or any themes), as radio buttons, a select or a header menu. It remembers the choice in a cookie, so the server renders the theme before the first paint (no flash). The Starbase header uses it for the site's own themes, with "auto" following the system (Deep Space or Daylight).
    • sb-rating: pixel hearts or stars for a score, with half steps, hover preview and keys.
    • sb-relative-time: "3 minutes ago" that stays current, in any language, with a server fallback.
    • sb-qr-code: pixel QR codes for any text or URL, with optional brand-coloured corners (uqr, vendored and verified).
    • sb-tree: a keyboard-friendly tree whose branches load lazily from the server; expanded and loaded are props the server can morph.
    • sb-select: filter, pick several, or autocomplete from the server through a results prop.
    • sb-range: a two-thumb slider whose {start, end} is one value, committed as one command.
  • Command contract for value components (input, slider, toggle, code editor, tabs, rating, tree, select, range): a name prop and sb-change {name, value} on commit, ready to post as a command. With confirm, :state(pending) marks an edit the server hasn't confirmed, and revert() returns to the server's value after a rejected command. The Showcase demonstrates the loop (pending, a server-normalized value, a rejected command).
  • Example dataset (a seeded universe of galaxies, systems, planets and moons) with generic demo endpoints, /demo/data/children and /demo/data/search, for docs and playground demos (into= names the signal, delay= simulates latency).
  • Component sizes: gallery cards show the download size (brotli, including the components it renders), and component pages have a Size table with original, gzip and brotli sizes for each file and each rendered component, plus a total. Datastar and Rocket are not counted.
  • Continuous deployment: after CI passes on main, the Deploy workflow ships the binary over a single-purpose SSH key to starbase-deploy, which verifies it, checks /healthz and rolls back if the new version isn't healthy. The unit, env and Caddy files are in deploy/.
  • Vendored libraries: a submission from a repository brings along every file the component imports relatively (up to 2 MB each), listed with its license banner in the PR. Imports are checked strictly: 'datastar' or files in the component's folder, never URLs or bare packages.
  • Submission pull requests get a playground preview link for every revision (/playground?preview=<commit>/<slug>) and a list of similar existing components, to spot duplicates before merging. When the pull request step fails, the bot tells the author on the issue.
  • Opt out of the 8-bit look: --sb-notch and data-sb-style="smooth" turn off pixel corners, notched frames and the pixel display font. The Themes page has a switch.
  • SEO: robots.txt, a sitemap, canonical URLs, Open Graph and Twitter cards, JSON-LD (WebSite with search, SoftwareSourceCode per component) and PNG icons rendered from the pixel art.
  • Contribute guidelines for component authors: the command contract, components with several values (one structured value per decision, view state and server data as separate props, sb-<verb> operations), and no optimistic updates (server results only come from the server's render; the user's own input stays, marked pending).

Changed

  • The server can set every component's value: a value/checked attribute the server changes wins over local edits, while re-sent identical markup leaves edits alone. Removed attributes are ignored (morphs also strip reflected ones), so to clear, send value="" / checked="false". The manual pre-upgrade property adoption and the dirty flags are gone (Rocket replays those writes itself).
  • sb-alert has an open prop, so the server can hide and re-show it. sb-theme-switch draws its icons as CSS masks.
  • The logo and the hero scene follow the site theme: they are inlined as SVG, and their themeable colours are --sb-art-* tokens. As standalone files (favicon) they keep the original colours.
  • Performance: brotli, zstd or gzip for pages and text assets; one minified, hashed CSS bundle; hashed, preloaded fonts; immutable static files; pixel art drawn as one path per colour; lazy playground preview frames, and no layout shift on /playground.
  • GitHub Actions updated to their Node 24 (LTS) majors.

Fixed

  • sb-copy-button: a refused clipboard write (no secure context, no permission, unfocused document) was silently ignored; it now shows "Copy failed" (failed-label) and emits sb-copy-error {value, error}. The result is announced through a role="status" region outside the button, and the tip is readable on light themes and no longer cut off on code blocks.
  • Demo endpoints answer CORS preflights, so components in the playground sandbox (opaque origin) can load demo data with @get, e.g. the lazy tree.
  • Playground: the preview theme picker applied the previous choice.
  • The playground can run components that import their own files (e.g. sb-code-editor and its vendored Prism): relative imports resolve against the component's folder.
  • Submissions from a playground link failed validation: the link was recorded as the component's source:, which must be a GitHub repository.
  • The hero scene keeps its proportions at every width; sb-theme-switch icons line up with their labels; light-theme contrast fixes.

Security

  • Versioned, immutable component URLs (/c/<slug>@<hash>/…) and catalog snapshots (/c/@<catalog>/autoloader.js), with SHA-384 integrity for every file (/c/@<catalog>/importmap.json). Sites can pin exactly what they reviewed; browsers refuse any file that changed. Old versions keep working after later deploys.
  • Vendored libraries are verified: vendor.json names each file's npm release, and the bot checks it byte for byte against the registry-verified tarball. Minified code that can't be verified is refused.
  • The Starbase service listens on a Unix socket and is denied all of localhost (other services on a shared host), with a fully hardened systemd unit. starbase-deploy asks a new binary its version inside a network-less sandbox with a timeout.
  • Pull request previews are limited to the repository's own submission branches; script-src is limited to /static/ and /c/.
  • Rate limits for snippet saves and painting (per session and per IP), and a cap on total snippet storage.
  • CI: actions pinned to commit SHAs (Dependabot keeps them current), job timeouts, Chrome's sandbox kept on for submitted code, the bot's write-capable job re-validates what the build job produced, CODEOWNERS for vendored code, CI/CD and deploy files, and tests that keep the production environment to deploy.yml.

Known issues

  • Datastar's morph is not re-entrant with Rocket components that are reordered by id: reported upstream as starfederation/datastar#1209, with a minimal reproduction and a fix in docs/repro/rocket-morph-reentrancy/. Starbase avoids the pattern.