
This follows [Introducing Via](/articles/introducing-via/), which lays out the platform before comparing it with older deployment systems.

Heroku made deployment feel small.

Before that, shipping a web app often meant learning a server, installing packages, configuring a process supervisor, wiring logs, and hoping production still looked enough like the developer's laptop. Heroku changed the shape of the job: give the platform source, let it build the app, attach config, start processes, and show what happened.

That is the part Via should steal.

## The Heroku move

Heroku was founded in 2007 by James Lindenbaum, Adam Wiggins, and Orion Henry. It started with Ruby app hosting, launched commercially in 2009, added a marketplace for add-ons in 2010, and joined Salesforce after the December 2010 acquisition.

The famous command was simple:

```bash
git push heroku main
```

The command was not the whole story. The useful part was the lifecycle behind it. Heroku received source, detected the app, built a slug, attached config, ran dynos, streamed logs, and made the app operable.

The Twelve-Factor App gave names to much of that model: strict dependencies, config outside code, backing services as attached resources, build/release/run as separate stages, disposable processes, and logs as event streams. Those ideas outlived Heroku's original Ruby focus. They show up in hosted platforms, internal developer platforms, and app runners that do not look much like Heroku.

## The lifecycle

```mermaid
flowchart TB
    SOURCE[Source selected by developer]
    RECEIVE[Platform receives source]
    BUILD[Build and test]
    RELEASE[Create release with config]
    RUN[Start runtime]
    OBSERVE[Status, logs, audit]

    SOURCE --> RECEIVE
    RECEIVE --> BUILD
    BUILD --> RELEASE
    RELEASE --> RUN
    RUN --> OBSERVE
```

That split is worth keeping. Source is not the production artifact. A build is not yet a release. A release is artifact plus config. A runtime instance is replaceable. Logs and status belong to the platform.

## Via's version

Via takes the Heroku model, but not the exact interface.

The main workflow is:

```bash
vary app deploy my-app --target prod
```

The command sends source to Via and follows the operation. Under the hood, Via may use Git, deploy tokens, pre-receive validation, and server-side repository storage. Users should not have to add a Via Git remote, manage credentials, or remember refspecs. The command is the interface.

That fits [Via Server](/articles/via-server-vary-app-platform/): app owners submit source, and the platform owns the controlled path to a running service. It also matches [Golden Path: Install Via and the Echo Server](/articles/deploy-echo-server-on-via-minimal-commands/), where deploy, config, routes, and runtime status are one workflow instead of four unrelated chores.

| Heroku lesson | Via choice |
|---|---|
| Source is the deploy input | `vary app deploy` sends source to Via. |
| Build happens on the platform | Via checks out, typechecks, tests, packages, and signs. |
| Release includes config | Via combines artifact, config profile, secrets policy, add-ons, and route state. |
| Services are attached | Managed SQLite and future add-ons are named bindings. |
| Logs belong to the platform | Via records operations, deploy states, runtime logs, and audit events. |

The same pattern shows up in [managed SQLite](/articles/managed-sqlite-on-via/): the app asks for a named binding, and Via owns the operational resource.

## Branches and tags

Via should keep the familiar Heroku branch idea without making Git the user interface.

An app can have a configured deploy ref, defaulting to `main`. A normal deploy uses the current source and sends it to that deploy ref:

```bash
vary app deploy my-app --target prod
```

A developer can deploy another branch to the app's deploy ref through the Vary command:

```bash
vary app deploy my-app --target prod --ref feature-x --deploy-ref main
```

That means what people expect from Heroku-style branch mapping: take this branch and deploy it as the app's main release line. The internal transport can use Git mechanics. The user does not need to see them.

Tags should be explicit:

```bash
vary app deploy my-app --target prod --tag v1.2.3
```

Via should record the tag and the resolved commit. If the tag moves later, that is a new event, not a rewrite of an old deploy.

## Where Via should be picky

Via should hide Git mechanics from users, but it still has to be strict inside the receive path.

| Rule | Reason |
|---|---|
| The Vary command owns deploy credentials. | Deploy tokens stay short-lived, scoped, and outside normal Git credential storage. |
| Accepted source must be buildable. | If the builder cannot check out or archive it, the platform should reject it before creating a deploy. |
| Ref names normalize everywhere. | `main`, `heads/main`, and `refs/heads/main` should mean the same deploy ref. |
| Git failures become Via errors. | Non-fast-forward, stale hook, expired token, and wrong-ref failures need stable Via codes and next commands. |

This is where Heroku is an influence, not a template. The simple experience is worth preserving. The raw Git edge cases are not.

## The lesson

Vary tries to make application contracts explicit: HTTP contracts, typed handlers, generated clients, managed persistence, config, secrets, and tests. Deployment should live at the same level.

The useful lesson from Heroku is plain:

```text
source in
platform-owned build
platform-owned release
platform-owned runtime
clear status out
```

For Via, the command is `vary app deploy`. The platform receives source, builds from a clean checkout, signs the artifact, attaches declared resources, starts a verified runtime, and records the path.

That is the Heroku idea worth keeping.

## References

| Source | Why it matters |
|---|---|
| [Heroku company history](https://www.heroku.com/about/) | Timeline for Heroku's founding, launch, add-ons, Postgres, and Salesforce acquisition. |
| [Heroku Dev Center: How Heroku works](https://devcenter.heroku.com/articles/how-heroku-works) | Heroku's own description of app lifecycle, builds, releases, dynos, config vars, and add-ons. |
| [Heroku Dev Center: Deploying with Git](https://devcenter.heroku.com/articles/git-branches) | The branch deployment model that informs Via's branch semantics. |
| [The Twelve-Factor App](https://12factor.net/) | The app design model behind source, build, release, run, config, and logs as platform concerns. |
