Changelog

From first prompt to live app

Aug 11, 2026·23 min read

This week Contrast made it easier to move from editing an app to putting it in someone’s hands. A guided first run takes a new project from a description to a live deploy, native previews run two platforms at once, and iOS builds go to a registered phone without TestFlight. Deployments, project files, and compile artifacts now use content-addressed, versioned storage.

Platform

Put a real build on your own iPhone

Register an iPhone from the deploy surface, start an ad hoc development build, and install it over the air. The web flow gives you two QR codes, one to enroll the device and one to install the finished build. The phone opens the enrollment profile directly. There is no TestFlight round trip.

When a project needs Apple credentials, the Dev build, TestFlight, and App Store choices open the same setup flow in the sheet. It covers Apple ID and two-factor verification, team selection, app identity, and either a new App Store Connect key or an existing one you already hold. Five visible stages show what is done, what is blocked, and what comes next. Enrollment errors stay on screen beside Retry. Mobile asks for notification permission only after you send your first chat message, when a build is starting.

Start a project with a guided path to a live app

A new project opens on a three-step setup card covering platforms, a starting point, and what the product needs. Your answers go into the first conversation. The assistant replies with ranked starting points, explains why each one fits, and creates the project through the normal handoff when you make a choice. Projects with a template default name get a short name from the first message. A name you chose yourself always wins.

A six-step timeline then tracks creation, preview readiness, a saved edit, an invite, a live deploy, and the final report. It provides a direct action for each unfinished step. The workspace shows when setup is running. If file provisioning fails, it explains the failure once and offers to open another project instead of leaving you on an empty screen.

Keep iOS and Android previews open at the same time

Native preview panes now save their platform as part of the editor layout. A second pane keeps its own platform, device, workers, menu actions, and reload state. You can compare iOS and Android builds side by side, switch between a device-framed view and a tight app-only view without restarting, and keep the preview tools visible.

The previews now match the real device more closely, including Material spring sheets, measured Android geometry and typography, system fonts, native transitions, pinch and scroll behavior, notification banners, tab tint, SVG strokes, nested text line height, phone bezels and separators, and exact initial pages in paged views. Custom fonts finish registering before large text paints, so headlines use the intended face. Readiness reports compile, delivery, host, first paint, and content separately. It also shows a build failure in under 250 ms instead of waiting through a long window.

Edit and deploy a complete small-business site

The web-business template now ships as a finished editorial site with seeded content, authentication, docs, a blog, a shop, real photography, a location and opening-hours section, scroll-enter reveals, and a login screen written in the site’s own voice. A role-gated admin area gives owners mobile-safe layouts for pages, posts, products, and site settings, so routine content changes require no code.

Connected stores and content systems feed the same pages. A Shopify connection imports real prices, variants, images, and availability. It removes products that become inactive during full and incremental syncs. Published Contentful entries reconcile into the site’s own database. Public home, blog, shop, and docs pages render the content currently being edited or synced, with real loading and empty states.

More examples worth starting from

The example catalog is now separate from the neutral starter. Hearth is a cross-platform home designer that shares one React Three Fiber scene on web and native. You can fit a lot, place sofas, trees, and lamps by touch or click, describe an arrangement in a sentence, and keep the saved layout after a reload. The sticker-wall example demonstrates onboarding, paging, uploads, themes, and dialogs across native and web. The RPG showcase is playable across ten connected areas with turn-based combat and synced saves. The travel example shows native tabs and liquid-glass navigation.

The finance example now uses one layered squircle card material in warm espresso neutrals, with a copper accent and serif figures. The Todo starter boots with the user and role fields required by its sign-in flow. Its whole screen scrolls as one surface with a sliding filter indicator.

Tech

Deployments publish as versioned bundles behind one loader host

Dynamic deployments now store versioned app and sync bundles in R2, flip a per-app pointer, and serve them through a single Cloudflare Worker Loader host. Each app’s SQL and sync code runs in its own Durable Object facets under a supervisor that owns alarms and preserves WebSocket upgrades. Configuration is version-addressed and encrypted with HMAC-derived AES-256-GCM key identities. A rotation carries the current and next ciphertexts.

Verification follows the browser request path through DNS, the deploy router, route marker, loader, facets, uploads, and sync, using a classic deployment as the negative control. Warm requests measured 31 to 38 ms and cold requests 5 to 6 s. The validated path produced 12 of 12 successes, and a wake socket stayed connected for 99 s with a supervisor tick at 69 s. Collapsing 239 byte-identical route stubs reduced the worker-equivalent gzip build to 10,272,724 bytes. The publisher keeps the pointer that served, so rollback takes one pointer move instead of a rebuild.

PublishVersioned app and syncbundles in R2Per-app pointer flipWorker Loader hostDurable Object SQL andsync facetsPrevious pointer retainedfor rollback

One content-addressed path from project files to compile artifacts

Project paths now store SHA-256 pointers while bytes live once in a shared blob keyspace. Seeds, forks, mirrors, exports, commits, and branches resolve each path to a SHA and then a blob. Copy-on-write repoints only changed paths, and garbage collection marks tree and commit-manifest references before sweeping. The first Todo project wrote 51 blobs and an identical second project wrote none. Bulk R2 concurrency rose from 10 to 64. Writes publish bytes before index rows reference them. A read with a missing blob raises an explicit storage error instead of reporting a missing path.

Compile artifacts use one CompileObjectStore contract across local disk and R2, with the same content-addressed keys, atomic renames, metadata sidecars, and zero writes on a warm stamp. The compile CDN publishes immutable catalogs and manifest packs keyed by pipeline revision and transform configuration, now at revision 8. Cold previews find a closure from lightweight manifests before fetching byte-bounded packs. Packs are capped at 80 MiB and 400 entries, and every returned byte count is verified.

Native builds compile in disposable guests and sign on the trusted host

iOS link builds and dispatched user builds run dependency installation, CocoaPods, Xcode compilation, and linking inside fresh Tart macOS guests. The trusted host receives an unsigned archive, verifies its bundle identity and build metadata, waits until the guest is gone to sign it, and then cleans up the guest and build inputs.

Android uses the same structure. The shell assembles and validates an unsigned release APK and emits a typed report with the payload, build flavor, dependency hash, package identity, architecture, and APK SHA-256. Signing runs only when the report and source hash match the signing request. Artifact checks cover identity, size, entry count, package metadata, architectures, and signature state, with a 512 MiB ceiling, build-tools 37.0.0, and minSdk 26.

Source and dependenciesDisposable guest buildUnsigned artifact plus typedreportHost verifies identity andhashesSigning on the trusted host

Delegated Zero pushes run beside their Durable Objects

The sync host now delegates mutation pushes to the data worker that owns the relevant Durable Object namespace. That worker runs the common push pipeline against its own Application SQLite client, keeps the durable-work index mark inside mutation ordering, forwards only rare app-side actions, and derives the namespace from the push path. A typed mutator registry replaced the separate host pipelines. Namespace schema readiness is cached per isolate and clears at 1,024 namespaces. The sync engine is bundled as CompiledWasm instead of an external wasm import. The previous busy-namespace path averaged about 10 s for roughly 100 ms of CPU.

The Factory HTTP mutation tunnel has also been removed. Agent events stay batched and enter a normal custom Zero mutation that checks the runtime claim inside the transaction. The combined facade owns one serial queue and acknowledges each mutation from the client instance that issued it. The Rust sync client reduced delegated pushes to two 25-second attempts. That leaves room under the browser transport’s 60-second deadline, allowing a slow push to retry without tearing down the session.

Preview memory follows measured per-realm cost

Bundler workers retire after 30 seconds idle, preview runtimes have explicit owners, and switching away disposes an unowned runtime. Replay storage is now asynchronous and compressed. Web replays fell from 15,353,662 to 2,044,432 bytes and native replays from 17,176,235 to 2,115,645 bytes, with 28 to 52 ms decompression. Parked compositor surfaces purge graphics caches after five seconds. Target JavaScript heap dropped from 1,115.6 to 339.8 MiB, settled app cache from 180.3 to 116.5 MiB, and the GPU blank-to-mounted delta from 500.9 to 382.5 MiB.

Live bundler isolates are capped at four plus one transient. The previous uncapped fan-out reached ten isolates, each retaining about 170 MB. Cold preview warmup covers at most 12 route modules, with two running and eight queued per tab. A 138-package closure fell from about 31 s to about 16 s at concurrency 8. Editor warmup reads the preview document and one level of its declared dynamic imports, reducing a cold load from 107 requests and 18.89 MB decoded to 73 requests and 14.96 MB.

Editor and workspace

  • The editor’s first paint improved from 755 ms to 402 ms on a cold production test at 20 Mbit/s, with first contentful paint down from 2696 ms to 1926 ms.
  • Workspace panes share one navigation language: sub-headers, frosted bottom tabs, a compact top-left action pill, and cross-section arrows that reveal and align the destination pane.
  • The factory workspace divider is draggable, clamped between 15% and 85%, workspace-synced, and survives a reload.
  • Minimizing and expanding editor columns animates from committed layout width, and lazy panes and heavy dialogs retry transient module-load failures.
  • Settings rows, switches, dialogs, and primary actions moved onto shared theme tokens, canonical insets, and one semantic check scale.
  • Type bundles are built from the dependency copy each project actually installs, and generation fails rather than mixing declarations when projects disagree on a version.
  • Editor type bundles follow nested package subpaths and include the package.json metadata those entrypoints need.
  • Project icons are materialized once as 128px WebP from their content hash and served from an immutable cache across web, mobile, and preview lists.
  • The left rail keeps stable initials and colors for account and project tiles until real artwork loads.
  • The branch pill shows the real branch name, project switching follows the project you opened, and creating a project keeps ownership with its creator.

AI Factory

  • Agents can generate illustrations, logos, and splash art at 1024x1024 and save them beside a project’s existing assets, falling back to free sources at the rolling budget.
  • Verified free accounts can complete factory requests whose preset names a paid-tier model, using the free fallback inside existing caps.
  • Assignments carry recent repair comments and authoritative ownership into fresh and resumed briefs, and a resume order is treated as the first action.
  • The main assistant can cancel active factory work, and a proven-complete worker pauses after two idle rounds instead of burning more time.
  • Factory direction state distinguishes pending, delivered, and handled, so a Manager turn that received a request but did no work can be retried. The final proof ran 12 of 12.
  • A host storm of about 11,000 nested updates over 6 s with 2,046 errors fell to zero, and turn-end recovery went from 44 refusals in 60 s to none.
  • Tool phases come from one shared state machine and replay reconstructs them from persisted request receipts rather than a full allowlist.
  • Shared projects show one driveable Manager per project, and an in-progress lane can say when no factory runtime is behind it.
  • Wave analysis imports driver telemetry into authoritative facts, resumes incrementally, and publishes bounded durable artifacts within a 10 MB per-wave budget.
  • Route work stays inside the template group that owns its navigation, and unsafe sibling-screen placement is refused with an alternative.

SootSim

  • Three-mode is free, and the 3D studio opens on true-black Ink with ordered controls, a low-poly stage, contact shadow, faster zoom, and separate case tint and interior glow.
  • Recording has its own rail section: video or combined takes unlock the timeline, and an empty timeline stays out of the way.
  • Settled screens render their source canvas at 2x density and drop to 1x during fast drags, and improved depth-of-field mips and gather rings removed blur banding.
  • Permission state and app settings persist like iOS, the built-in Settings app streams the current app catalog, and Dynamic Type uses measured UIKit metrics.
  • Apps using Expo Widgets, Expo Age Range, App Integrity, Apple Targets storage, PostHog, Sound Player, Expo DOM WebView, Reanimated, and draggable list cells now run as-is.
  • Map-based apps can read center, zoom, bounds, markers, and projections, keep camera and idle events through gestures, and capture the visible map as PNG or JPEG.
  • A repository can pin its own SootSim engine version while the machine keeps its default, with each version on its own local origin.
  • The CLI previews a reclaim plan before cleanup, protects active runtimes and user data, and reports reclaimed bytes from a detached worker.
  • The OpenType parser now loads only when a guest app requests a custom font, removing about 250 KB from the default boot load.
  • Cold starts compile first-content GPU programs behind the boot placeholder. Spring-window flushes fell from 100 to 200 ms down to under 12 ms.
  • Glyph atlases realize from a bounded queue and app snapshots stay on the live-frame texture path, cutting combined per-slide compositor cost from 249.6 to 237.3 ms.
  • Pressed tabs lift and refract the bar as real glass, with dark-press mean absolute error improving from 25.46 to 22.46.
  • The published runner benchmark now uses one shared dataset of four median runs on the same authenticated flow: SootSim 9.9 s against Maestro 24.0 s.
  • Compatibility scores separate pure-JavaScript adapters from packages shipping native code and no longer claim 100% beside a declared gap.

Site and marketing

  • The Contrast hero gained a WebGL glass loupe that magnifies live hero content and fades in over 450 ms, working on the authenticated marketing page too.
  • Marketing pages stop running simulator, video, and terminal demos once they leave the viewport. Off-screen SootSim playback fell from 8.0 s per 8 s to zero.
  • Cold docs dropped from 4.16 MB across 213 requests to 1.02 MB across 146, and compatibility comparisons rest after three sweeps.
  • The launch film runs as one continuous cut through questions, browser and simulator views, the ink warp, the multiplying app grid, integrations, deployment, and the store outro.
  • Film Studio uses one three-panel workspace with a shared layer tree, timeline, and inspector, and linked devices move as a group.
  • Shared links use deterministic branded cards at 1200x630 with the app title, icon, and a phone screenshot captured from the live preview.
  • The office art and hero composition stay anchored from phone widths through wide screens, reaching full hero size at 1250px.
  • Public navigation, docs, and pricing expose usable names, landmarks, and keyboard targets, and the mobile landing hero is discovered before stylesheet parsing.

Collaboration and accounts

  • Referrals have a full loop: copy a personal link, attribute a signup for 30 days, notify the inviter when a friend joins, and credit both sides once the friend starts building.
  • Passkey sign-in appears on web and mobile only when the typed account has a saved credential, behind a 350 ms debounce and a 20-per-minute IP limit.
  • Login remembers which provider last completed sign-in and marks it as the last used one.
  • Several project editors can run their own factory runtime concurrently while each work item still has one winner.
  • Beta invites open on the requested step, paint through safe areas, and grant Pro for three months.
  • GitHub accounts without a usable public email sign in through their stable noreply address, and new users reach the app without waiting on workspace provisioning.
  • Chat keeps drafts per account and project, clears the composer only after a message is saved, and folds long rows to a readable preview.
  • Long chat histories load in bounded 50-message pages while the newest live window stays active.
  • Mobile factory is a full workspace tab rather than a picture-in-picture card, and the plan stays the compact surface.
  • Lux appears in project presence, dim while watching and lit after you hand over control through a steering-wheel toggle that starts off on every load.
  • Agent identity is deterministic from an agent’s id across the factory floor, presence, chat, and marketing surfaces.

Deploy and infrastructure

  • Deleting a project checks for an initialized Apple app identity, a TestFlight or App Store deployment, and a live web deployment before changing state, all in one transaction.
  • Deploy actions read the synced hosting entitlement and wait for the authoritative server commit before changing editor state. Comped and admin accounts can host without a Stripe hosting item.
  • TestFlight and OTA workflows pin the main revision, require green CI, and let only the oldest active run publish, so an older source cannot overwrite a newer one.
  • Version-only republishing keeps the same OTA fingerprint when byte equivalence is proven. An unproven native change forces a new runtime and build.
  • Local deploys proxy to the running web and sync runtimes, forward sync traffic to the discovered namespace, and restore on first request.
  • Cold container requests wait for platform placement within a 40-second budget before proxying.
  • Production builds fail before deploy when emitted chunks contain import cycles, found by a strongly connected component walk. The client build fell from 730,326 to 533,373 Brotli bytes.
  • Deploy validation now checks worker readiness, same-origin assets, seed artifacts, the emitted API route manifest, and derived Drizzle migrations.
  • Backup coverage shares one disposable-identity predicate with its audit, cutting the inventory from 408 to 162 namespaces and dropping a journal that was 86,060 of 124,643 control-plane rows.
  • The Cloudflare write watchdog now reports whether a burst comes from one runaway object or work multiplied across the fleet, after missing a 1,244,066-row five-minute bucket.
  • Transactional email can give Contrast and SootSim their own sender domains, with an opt-in verifier checking inbox placement and SPF, DKIM, and DMARC alignment.

Security

  • Production auth uses host-only session cookies, routes sync authorization through the apex worker, and rejects state-changing API requests from untrusted origins before handlers run.
  • User deployment and preview origins no longer receive credentialed API responses, and parent-domain credentials are no longer accepted.
  • Runner requests carry an HMAC capability scoped to GitHub’s canonical repository id, run id, and attempt, verified before entitlement, spend, or provider forwarding.
  • Native build-context, install, and callback tokens sign the project id together with the deployment id, so a token cannot be replayed across projects.
  • Preview share capture filters SecureStore plaintext and keychain records out of the snapshot while keeping app state, indexed data, and routes.
  • Mobile removes the old mirrored user before storing a new session token, so a cold launch cannot mount the previous account’s local store.

Data and sync

  • Generated aggregates can be declared per namespace, combined into one set, and rejected on duplicate names or target-column ownership before triggers install.
  • Changes to grouped query, model, and instance registries force live previews to remount their generated client.
  • Project deletion performs its authorization read inside the transaction that carries the push.
  • Hot storage reads use the read client and latency-sensitive priority instead of opening serialized write transactions, with a 5-second factory access cache.
  • Preview persistence keeps platform authentication in a store keyed by auth DDL while product data rotates with the schema, and surviving accounts are mirrored back at boot.
  • Guest app storage gets a stable project, route, and tab scope, and a missing scope fails loudly instead of silently choosing an unscoped store.
  • Object reads bound transport and body separately, retry transport faults and throttling up to three attempts, and never turn a temporary storage fault into a missing object.
  • Migration history moved to generated baselines and a compact boot representation, removing repeated historical snapshots.

CLI and tooling

  • The reload command accepts the user-facing native target, alongside web, all, host, and explicit iOS forms.
  • Deploy status and build-log commands show recent or selected deployment state, with invalid flags failing before any request.
  • Doctor output can be consumed as a stable JSON envelope, and child-process failures preserve their exit status.
  • Report-issue previews the compatibility report and requires approval before sending, omitting source, environment variables, logs, screenshots, and app data.
  • Daemon start and stop fail when no service is registered, and status checks the bridge health the runtime actually needs.
  • Setup installs bundled workflow skills and provides a copyable prompt, so the CLI no longer needs a separate desktop onboarding path.
  • MDX previews compile through a dedicated Workerd service with a typed contract, a 512 KiB source cap, and 1-based file, line, and column locations for inspect-to-source.
  • Local development binds its listeners before generated artifacts and watchers finish, and reclaims the previous stack for the same checkout and port offset.

Fixes & polish

913 fixes and 71 performance improvements landed this week. Web previews now serve the isolation policy each browser can follow. Safari gets the compatible policy, while engines that support credentialless isolation keep that behavior. The final document is served without a redirect hop. Preview reload recognizes a session that is already controlled instead of re-registering it. This reduced controller-present readiness from 57.1 seconds to between 5.6 and 12.5 seconds across eight runs. Public pages improved their contrast to a perfect score on pricing, quickstart, and changelog. Sheets now open cleanly at intermediate widths and close with Escape.

Ready?

Create a web, iOS, and Android app in minutes with agents working alongside you.