Skip to content
Concepts

The application graph

Components, the node each environment has for them, references as the edges between them, and the external services the application depends on. The one picture the rest of Kuppit is drawn from.

Kuppit keeps one picture of your application and derives everything else from it. The picture has four kinds of thing in it: components, nodes, references and external services. Understanding them explains why environments behave as they do, what a reference costs and does not cost, and why the overview looks the way it does.

Components

A component is a thing your application is made of, named once per project: the web service, the database database. The component owns the name and the kind. That is why the same component is web in Production, in staging and in every preview, and why nothing can be api in one environment and backend in another.

Nodes

An environment has a node for each component it includes. The node is the environment's instance of the component: the service that deploys this environment's branch, the database this environment's services connect to. A node's status, hostname, deployments and variables are its own.

A node normally is its own instance. Two decisions change that:

  • Share. The node points at another environment's instance. It reports that instance's status and credentials, keeps its own place in this environment, and creates nothing new.
  • Clone. The node is its own instance, seeded from a copy of another environment's data when the environment was created. Afterwards it is independent, and Kuppit records where the data came from and consults it for nothing.

An environment also records the components it deliberately does not have, so Don't include stays distinguishable from a component added to the project later.

References

A reference is a variable on one node whose value is a variable another node exposes:

database ── DATABASE_URL ──▶ web

Read it as: web references a variable exposed by database. The arrow follows the data. The database provides the value; the service consumes it. That direction is what the overview draws, and what the Connections list says in words on a phone.

A connection is the deliberate form of this: web → database made as one act, injecting every variable the database exposes and owning those references. The graph draws an edge either way — for a connection, and for references written by hand — and a connection and a hand-written reference to the same database are two edges between the same pair.

Three rules give references their character:

  • A reference targets a node in the same environment, always. Staging's web references staging's database; a database in another environment is, to it, indistinguishable from one that does not exist. Sharing is how an environment deliberately brings another environment's instance inside that rule — and the overview draws that reference as it resolves, from staging's web into Production's box, as a cross-environment connection. Choosing another environment's database under Connect to… makes the share and the connection in one step; see connections.
  • A reference is resolved when a deployment is prepared, from the target's state at that moment, and the resolved value is frozen into that deployment. The service is connected to the database as it is now, and a rollback restores the connection as it was then.
  • A reference is a dependency, and Kuppit treats it as one. A deployment waits for a database still being created, fails clearly for one that no longer exists, and names every connected service before a database is deleted.

External services

An external service is something the application depends on that Kuppit does not run: Stripe, an email sender, an error tracker, an API of your own. It is not a component and has no node — nothing instantiates it — and the project knows it once, however many environments use it. The overview draws it per environment: beside each box whose nodes use anything stands one External services card, saying how many and whether the environment has set what they read, with one line to it from every node that uses something; open the card and the services stand behind it, one card each, so Stripe appears beside Production and beside Staging when both use it while Kuppit still holds one Stripe. Which environments' web reach Stripe is what each environment's own commit says: Kuppit reads every deployment's commit for what the component uses there, so a service a pull request began using stands behind its preview and not behind Production until the change deploys there. A service detected in an environment's commit that nobody has decided about is counted on that environment's card as suggested, and asked about in its panel.

Kuppit detects these when it analyses the repository, asks you which belong on the graph, and draws the ones you confirm. External services has what it looks for and how a service is confirmed, ignored or added by hand.

Changes and findings

Every deployment's commit is read for what it requires — the names each component reads, the services it uses, the resources it connects to — and remembered. A change is what one commit says relative to another: a pull request began reading RESEND_API_KEY, started using Resend, now requires PostgreSQL. A finding is what that means for one environment: the preview does not have RESEND_API_KEY. The same change reads differently in each environment, which is why the two are kept apart. A preview's box counts both; its panel lists them, and offers to set what is missing. Application changes has the whole of it.

What is derived from the graph

SurfaceWhat it reads
The project's OverviewEvery environment as a box, its nodes as cards inside it, references as edges, unlabelled — at the sm breakpoint and up. Point at an edge and it says what travels along it; select it and the panel opens. A reference that resolves to another environment's instance is drawn as an edge into that environment's box, dashed, and amber when the box is Production's. Beside each box that uses anything outside Kuppit stands its External services card, joined by a dotted line from every node that does; open it and the services stand behind it. Production's box is drawn firmer, a preview's dashed. Drag a card inside its box to arrange the picture, and the arrangement is kept. Your place in the picture is kept too when the panel opens or the window changes; an arrangement that grows past the frame is fitted again, so what you just placed is not left off the edge. Fit to frame brings the whole of it back into view. On a phone, each environment's cards and a Connections list, then the external services.
An environment's OverviewThe same picture, with that environment's box brought into the frame and its panel open — reached from the environment selector, which on the project's Overview reads All environments.
The panelWhatever is selected — beside the picture on a wide window, beneath it otherwise: a resource's own front page, an environment's branch, pull request, Application changes and what it uses from elsewhere, an environment's External services — each with a check or how many names it is missing, and the two things to do about services — an external service seen from that environment, or a connection's variables and which environment it reaches into, headed Staging / web → Production / database. Selecting a card, a box or an edge opens it; the panel's header carries the actions the thing has of its own. With nothing selected, it lists the external services waiting for a decision.
A card's, a box's or an edge's menuThe same list, on a right-click or behind the ellipsis: for a resource, what that kind of resource can do — Open, Deploy, Redeploy, View logs, Pause or Resume, Connect to…, How to connect, Copy to environment…, Delete; for an environment, Focus, Add resource, Clone environment, Manage variables, Preview settings, Delete environment; for a preview, Focus, Open preview, View pull request and Preview settings; for an environment's External services, Show services or Hide services, View external services, Add external service… and Detect external services; for an external service, Open service and Ignore, or Edit… and Delete external service for one you added; for a connection, in its panel's header once the line is selected, Open variables, Rename variable…, Change target… and Disconnect. Nothing is offered that the thing cannot do.
The picture's menuA right-click on empty canvas: Add resource (to one of the environments, when there is more than one), New environment, Add external service…, Detect external services and Fit to frame.
A service's Connect and Variables tabsThe references it holds, and what it inherits.
A database's Connect tabWhich services reference it.
The plan for a new environmentEvery component, what it may become, and every reference to re-create.
Deleting anythingWhat would be disconnected, named before you confirm.

Nothing reads the raw list of resources or connections; a third rendering would read the same graph.

Was this page helpful?