← All blog posts

Product update

One app, one mesh

A complete ForkMesh instance now fits behind one domain: the application and its API ship together, while the public website and immersive World can evolve independently.

August 8, 2026Product update7 min read
One luminous ForkMesh core connected to a public website, an optional World, and five healthy mirror nodes

ForkMesh began with one Cloudflare Worker carrying the public website, repository app, API, and three-dimensional World. That made early iteration wonderfully direct. It also meant a documentation edit, a dashboard release, and a World asset change all shared one deployment and one operational envelope. As each surface grew, the convenient boundary became the bottleneck.

Our first answer was to split every surface into its own Worker. The cleaner answer emerged while doing the work: the app and API are not two products. They form the complete ForkMesh instance that another operator should be able to deploy at one memorable address.

One complete instance, two optional companions

app owns Git browsing, collaboration, accounts, REST, WebSockets, federation, routing, and developer information at app.forkmesh.com. The official www service owns the landing page, marketing pages, documentation, and blog at forkmesh.com and www.forkmesh.com. world owns the immersive network view at world.forkmesh.com.

That shape is intentionally asymmetric. An independent operator can deploy the app at forkmesh.theirdomain.com and have everything required to run ForkMesh. If they want the World, they can add forkmesh-world.theirdomain.com. They do not need to reproduce our marketing website or coordinate a second backend domain.

Separation is useful only when it survives the release path. Deploy controls expose distinct app, www, and World actions, and target fingerprints skip a service whose inputs have not changed.

The API belongs to the app

Every web and native client resolves API and WebSocket requests through the selected app origin. On the hosted services that defaults to https://app.forkmesh.com; a self-hosted app uses its own origin, local development can remain local, and a saved remote instance can provide another HTTPS origin. The polished developer and live-statistics page now lives at app.forkmesh.com/api, beside the product it describes.

Cross-origin requests also have an explicit security contract. Hosted frontends receive narrowly scoped CORS responses, credentialed requests are allowed only for recognized origins, preflight requests get the methods and headers the route actually supports, and caches vary on Origin. The API is shared infrastructure, not an open reflection of whichever origin a browser sends.

That boundary makes multi-instance work practical. A person can add another ForkMesh instance, sign in with an account from that instance, and keep the session alongside their other saved accounts. The avatar menu becomes the switch: choose an account and its instance together, move between them without repeatedly signing out, and manage the active instance from the same account surface. Tokens stay attached to the API origin that issued them.

A repository that matches the product

The source tree now uses the same names people see in the architecture. The stateful app and API live together in app. The Qt client and desktop icons live in desktop. The Flutter application lives in mobile. Editor integrations live in extensions. The former mirror-node runtime is now server, alongside its service packaging. Pull-request artifacts live under .forkmesh/pulls, and the maintained documentation lives with the www worker that publishes it.

These moves are more than tidying. Build manifests, tests, release scripts, operations guides, and developer links now point at the product boundary they support. A new contributor can tell which runtime a file belongs to before opening it, while the repository-native records that make ForkMesh portable remain under .forkmesh.

Mirrors get a cleaner operational path

The server runtime remains the part that turns an ordinary Linux host into a ForkMesh mirror. Provisioning from the Network hosts page now walks a new node through provider creation, installation, registration, gateway health, repository sync, and signed endpoint verification as visible stages. A failed stage stays actionable instead of leaving a half-known host behind.

Existing mirrors receive the same scrutiny. Fleet controls can update or restart a specific node, request a targeted sync, and show whether the public gateway and the repository refs have converged. Retired registrations no longer get to masquerade as active failures, while an active mirror must provide fresh health and integrity evidence before it contributes a green status.

Production evidence is part of “done”

The repository changes and focused tests are only the first half of this migration. The release gate is deliberately operational: deploy every changed service and only those services, confirm the active mirror fleet is current and serving, verify that /status is green, exercise cross-origin authentication and instance switching against the hosted domains, and observe Cloudflare logs without errors for a continuous hour.

We do not use this post as evidence that those checks passed. The rollout record and live status are the evidence. If a production observation is still running, it remains in validation even when the implementation and local suite are complete. That distinction is especially important during an architectural split, where the most interesting failures live between otherwise healthy systems.

Simple to run, strong underneath

This is one mesh with a deliberately complete center: the app and protocol deploy together, the public site can tell the story without carrying application load, the optional World can grow on its own rendering budget, and independent servers keep source code available underneath all of them.

Open the ForkMesh app, explore the API, enter the World, or read the documentation.