Conversations DEVELOPER NOTES

Runtime Bump Log: v0.2.13 to v0.2.92

More from Braden Hartsell Open conversation
  • runtime
  • changelog
Comments
0
Upvotes
1
Score
1

Thread body

March 29 to June 10, 2026 It's been a while since the last bump log, v0.2.13, back in late March. Since then the runtime has shipped sixty-plus versions. That's not version inflation. Every one of those numbers is a real, immutable asset bundle that went out to production, because that's how our runtime works: when a vibe loads, it pulls a frozen, checksummed set of runtime files pinned to an exact version. Nothing mutates underneath you. When we fix or improve anything in that layer, the version moves. So here's everything that happened between 0.2.13 and 0.2.92, grouped by what we were actually trying to accomplish, because the version numbers tell you when, but not why. Custom domains grew up, v0.2.14 to v0.2.31 The first big arc of this stretch was making vibes on their own domains, the vanity host lane, as trustworthy and boring-to-boot as vibes inside the feed. Early April was a hardening campaign. We moved the vanity host bootstrap from inlined page logic into a real shipped runtime asset, built and verified through the same pipeline as everything else, v0.2.15 to 0.2.16. Then we rebuilt how the frame starts: the page you get is now a small dynamic envelope that carries the security policy decisions, while a versioned frame-loader.js owns the actual boot sequence: import maps, runtime scripts, and bundle activation. Config no longer rides in spoofable query params. It travels through signed, header-only transport, and the loader reads its CSP nonce from its own script element instead of leaving it sitting in the DOM. Why so much effort on a boot path? Because a runtime that sometimes starts is worse than one that fails honestly. This era also rewrote our health model, v0.2.18. A frame that's merely alive no longer counts as healthy. We require strong functional probes registered ahead of user code, and we fail closed on weak launches instead of letting a half-booted vibe sit there looking fine. Recovery loops got caps and backoff, v0.2.24, so a struggling frame retries gracefully instead of thrashing. Faster opens, stricter bundles, v0.2.32 to v0.2.40 Mid-April was about the first open. We unified who owns "where do this vibe's files come from" across the manifest, vanity, and runtime loaders, started edge-caching immutable public bundles, and made public mirror readiness converge before first open instead of during it, v0.2.32. The practical result: public vibes start faster, and the runtime never has to guess which storage lane an asset belongs to. The strictness mattered just as much as the speed. A series of fixes, v0.2.36 to 0.2.39, locked root-relative assets, the /sprites/player.png kind of path your code naturally writes, firmly inside the vibe's own bundle plane, so an authored URL can never wander out of its sandbox and into our control plane. CSS readiness became a real invariant for both the React and HTML runtimes: a vibe doesn't declare itself interactive while its styles are still in flight, which is the difference between "loaded" and "flashed unstyled garbage, then loaded." The presentation engine: teaching the player how your app wants to be seen, v0.2.41 to v0.2.79 This was the longest and most user-visible campaign of the whole stretch, roughly twenty-five versions across April and early May aimed at one deceptively hard question: when the player shows your vibe, should it letterbox it like a game or flow it like a document? We started by writing the answer down as a shared contract: stage versus document presentation, agreed on by the player, the focused overlay, Studio preview, and custom-domain hosts, v0.2.41. Then reality showed up, one app shape at a time. Fixed-size canvas scenes wrapped in author chrome, v0.2.47 to 0.2.48. Imported Vue and Vite apps that lock page overflow, so their full height is invisible to naive measurement, v0.2.61 to 0.2.66. Yes, six versions in one day. This shape fought back. p5 sketches in global mode, which need their setup and draw functions discovered after script replay, v0.2.58. Responsive canvas wrappers in compact overlays that flapped between modes, v0.2.67 to 0.2.69. Apps that report their settled size only after async framework layout, v0.2.76 to 0.2.77. Each fix followed the same philosophy: measure what the author actually built, reject pathological geometry instead of rendering a centered sliver, v0.2.42, and fail open to document mode when unsure. A scrollable page is always usable; a wrongly letterboxed one isn't. The campaign closed with presentation certification, v0.2.79, turning all those hard-won classifications into a verifiable contract so they can't silently regress. The payoff is invisible when it works, which is the point: your fixed-size game stays a crisp letterboxed stage on a phone and a monitor alike, and your full-page app fills the frame without clipping its bottom controls. Quality-of-life in the same window, v0.2.50 to v0.2.57 A few things shipped between presentation rounds that deserve their own mention. The runtime now consults the bundle manifest to rewrite image requests whose extension doesn't match what was actually uploaded, the classic "code says .png, build shipped .webp" mismatch, before the browser burns a guaranteed 404, v0.2.50. Private vibes got continuity: bundle access grants refresh before they expire and flow into already-mounted frames, so a long session on a private vibe no longer loses runtime state at the grant boundary, v0.2.57. Pulses got their own execution plane, v0.2.70 to v0.2.73 In early May we restructured how Pulses, the backend companions to vibes, meet the public internet. Pulse execution moved onto the vxbe.space plane with dedicated routing and hardened control boundaries between the runtime, dispatch, and the API. We also wrote the invocation limits down publicly, 256 KiB requests and 1 MiB responses, instead of letting people discover them by surprise. The principle: vibes and their backends should live on the user-content origin, cleanly separated from the platform that hosts them. It is the same isolation story the iframe sandbox tells, extended server-side. Making imported HTML behave like it was born here, v0.2.80 to v0.2.90 May's quieter arc was correctness for imported apps. The HTML runtime replays your document's scripts inside the sandboxed frame, and replay has subtle differences from a normal page load. We closed them one by one: module metadata is preserved through replay, v0.2.81; minified bundles get their module imports rewritten correctly, v0.2.82; and scripts that register DOMContentLoaded listeners during replay, which would have fired naturally in normal page order, now get captured and flushed before the runtime declares interactivity, v0.2.83. That last one is the kind of bug users experience as "it just doesn't start," with nothing in the console to explain why. The v0.2.84 to 0.2.90 wave bundled runtime artifact persistence, import-build improvements, and the late-May Pulse invocation and worker platform release. Four bumps landed in a single release window as that platform work converged. 3D, natively, and a quieter console, v0.2.91 to v0.2.92 The newest bumps land two things. First, the runtime now ships its own version-matched copies of the three.js glTF decoders: Draco, KTX2/Basis, and meshopt, v0.2.91. Compressed 3D models decode from first-party, checksummed runtime assets instead of someone else's CDN, which means they keep working under our strict sandbox policies and they're pinned to the exact three.js version they were built for. If you're making 3D vibes, this is the floor that makes serious model compression "just work." Second, the runtime is now silent in production, v0.2.92. The boot-time console logs that helped us develop the runtime are gated behind a dev-only debug flag, so your vibe's console belongs to your code. Small change, real respect: the console is part of your creative surface, not ours. Where this leaves us Eighty versions ago the runtime could load a vibe. Today it can load a vibe on the feed, in the player, in Studio, in an embed, or on your own domain; figure out whether your creation wants to be a stage or a page and present it that way on any screen; replay imported HTML apps with their module semantics, late listeners, and asset paths intact; decode compressed 3D models from first-party assets; keep private state alive across access boundaries; and fail closed, honestly, when something is actually wrong, all while keeping user code in a cross-origin sandbox that never touches the platform it runs on. None of these sixty-plus bumps was a feature checkbox. Each one came from watching a real vibe do something the runtime didn't yet handle gracefully, and refusing to leave it that way. That's the standing commitment: the runtime is the floor every creation on Vibecodr stands on, and we will keep pouring concrete into that floor, version by version, weird edge case by weird edge case, because the best thing we can build for the people making things here is a runtime they never have to think about.