Visual editor
A visual editor for your codebase, not a copy of it
Open your project's own .test URL in your own browser. PortBay injects an edit bar into the page, and the element you click resolves to a file, a line and a column you can edit in place.
Hard-wearing gear, quietly designed. Free shipping over $75.
Shop the dropHarbour tote
Trail pant
Wool crew
Start the project and visit its .test hostname in Chrome, Safari or anything else. The bundled Caddy edge routes the page through PortBay's edit proxy, which injects the bar into a shadow root. There is no app webview and nothing to open on the side.
Services
The bar switches from Preview to Inspect to Edit. Selecting an element resolves it to an authored coordinate — the file, line and column that produced it — through five anchor tiers, starting with the dev plugin's location stamp and falling back through a unique id, tag plus DOM ordinal, and more when it is absent.
Checkpoints
Text, classes, attributes and styles, plus structural edits — insert, delete, duplicate, move. Double-click to type into the page directly. The right-hand rail carries layout, spacing, typography, borders and effects, and a Tailwind token you rename is rewritten everywhere it is referenced in the same save.
Round the listing CTA and warm its border.
Done. Two files, 23 bytes. Nothing else moved — open the diff?
The write goes through the same engine the in-app Apply uses: a surgical splice into the byte span, never a parse-and-reprint. Comment placement, quote style, trailing commas and key order outside the patched span come back byte-identical.
Tailwind tokens
Slate
Gray
Zinc
Tailwind tokens
Cyan
Blue
Indigo
Every save sits on a shadow-git checkpoint kept outside your own history. The Diff button shows the working diff against it, and revert restores the pre-apply snapshot — per edit or all of it.
...and so
much more
a.btn-primary
resources/views/listings.blade.php:42:18rounded-md → rounded-full
14 bytes written · nothing else moved
1280pxa.btn-primary
resources/views/listings.blade.php:42:18rounded-md → rounded-full
14 bytes written · nothing else moved
Visual editor
Finding the element by hand
Without a visual editor the loop is: see it in the browser, guess which file it lives in, grep for a string you hope is unique, count how many other places share the class, then edit and alt-tab back to check. On a Blade or ERB template with a partial three directories away, the guess is the expensive part.
Get started
PortBay resolves the element you clicked to a file, line and column across 21 stacks, and replaces only the bytes that changed.
FAQ
Frequently asked questions
How is PortBay's visual editor different from Onlook?
Three ways, and one of them favours Onlook. PortBay writes by splicing the exact byte span in your file, so authored formatting survives and no marker attribute is added to your source; Onlook writes data-oid attributes into your files and reprints them through Prettier. PortBay runs locally against your own dev server on 21 stacks including Laravel, Rails, Django and WordPress; Onlook is Next.js plus Tailwind in a cloud sandbox. In Onlook's favour: it has a multi-frame infinite canvas and PortBay does not. PortBay has one breakpoint canvas, that was a deliberate decision rather than a missing feature, and a designer who works across frames will notice immediately.
Does PortBay's visual editor write markers into my source?
No marker lands in your files. The fastest way to identify an element is a data-pb-loc location stamp, and that is applied by the dev-server transform on the way to the browser, never written back into your source. When the stamp is not there the edit is not refused: four more anchor tiers follow it, starting with a unique id that matches exactly one opening tag across the project's authored markup, then tag plus the captured DOM ordinal.
Which frameworks does PortBay's visual editor work with?
Twenty-one, checked by a standing test rather than a README: static HTML, React, Vue, Svelte, Next.js, Astro, Angular, Remix, Nuxt, SolidStart, Qwik, Laravel, Livewire, Inertia, Rails, Django, WordPress, WordPress block themes, Hugo, Jekyll and Eleventy. The test drives four write lanes — text, attribute, class and page settings — against every one of them and reads the changed bytes back off disk, and any lane that cannot work on a stack has to refuse in a sentence the test checks for. Page settings is the one lane with real gaps: both WordPress rows refuse it.
Can an AI coding agent make the same edits through PortBay's visual editor?
Yes, through the same write-back engine over MCP. portbay_editor_apply is a two-step tool: the agent calls it with dryRun first and gets back the exact set of files the planner would write, which is not just the files it named, then calls again passing every one of those paths back as an exact consent list. If the list does not match the plan the call refuses and writes nothing. The real write also blocks on a human approval, and returns a snapshot id that undoes exactly that apply.
Can I use PortBay's visual editor on the free plan?
No. It needs a Pro plan with the early-access entitlement and the early-access opt-in turned on in Settings, and it is not compiled into the open-source build at all. It is macOS only, and it will not run while the project is shared over a public tunnel: a project with a running tunnel is dropped from the eligible set so the edit bar and its write endpoints never answer public traffic.
