localhost:

Project files

The YAML file Export writes and Import reads.

localhost keeps each Project’s configuration in its own storage, never in your project folder. To move a Project to another machine, keep it in a dotfiles repo or share it with a teammate, export it as a Project file: one YAML file per Project.

  • Export Project… (macOS: File menu; Linux and Windows: the Project’s ⋯ menu) writes the selected Project to a file you choose.
  • Import Project… (macOS: File menu; Linux and Windows: the + menu in the sidebar) reads one, validates it, and shows what it contains before anything is added.

You can also write a Project file by hand and import it.

Example

localhost: 1
name: My SaaS
key: my-saas
path: ~/Code/my-saas
variables:
  LOG_LEVEL: debug
secrets:
  - SENTRY_DSN
services:
  database:
    name: Database
    command: docker compose up postgres
    cwd: .
    port: 5432
    port_can_change: false
  api:
    name: API
    command: uv run fastapi dev --port $PORT
    cwd: api
    port: 8000
    depends_on:
      - database
    variables:
      DATABASE_URL: postgres://localhost:5432/app
    secrets:
      - STRIPE_KEY
  web:
    name: Web
    command: pnpm dev
    cwd: web
    port: 3000
    url: http://localhost:3000/admin
    start_all: false
    depends_on:
      - api
profiles:
  Development:
    variables:
      NODE_ENV: development
  Testing: {}
active_profile: Development

Fields

Project

Field Required Value
localhost yes The format version: 1. A file without it isn’t a Project file.
name yes The display name.
key yes The Project’s Key: lowercase letters and digits in groups separated by single hyphens (my-saas), at most 64 characters. Unique among your Projects.
path yes The Project’s folder, absolute. ~ stands for your home folder; export writes it that way. A Windows path (C:\Code\shop) for a Project that runs on Windows itself.
wsl no The WSL distro the Project runs in, e.g. Ubuntu (Windows only). path is then the folder inside the distro, written in full. Without it, the Project runs on this machine.
variables no Environment variables for every Service: NAME: value lines.
secrets no Names of Secrets for every Service, as a list. No values.
services no The Services, keyed by their Key (below), in the order they appear in the app.
profiles no Environment Profiles, keyed by name (below).
active_profile no The name of the active Profile. It must be one of profiles.

Service

Each entry under services is keyed by the Service’s Key (same rules as the Project’s; unique within the Project).

Field Required Default Value
command yes The command line, run as $SHELL -l -c "<command>" in the working directory (cmd.exe /s /c "<command>" for a Project on Windows itself).
name no the Key The display name.
cwd no . The working directory, relative to the Project’s path (web, packages/api, ../shared). . is the Project folder. Absolute paths and ~ aren’t allowed.
port no none The Service’s Port, 1–65535. The command gets the actual port as $PORT (%PORT% in cmd), and the Service counts as Running once it accepts connections.
url no none An http or https URL for Open in Browser. Its port is replaced by the actual port of the Run. Without one, Open in Browser uses http://localhost:<port>.
port_can_change no true false: never start this Service on another port when its Port is taken.
start_all no true false: Start All skips this Service (shown as Manual in the app), unless something being started depends on it.
depends_on no none Keys of Services of this file that must be Running (or have Exited) before this one starts, as a list.
variables no none The Service’s own environment variables.
secrets no none Names of the Service’s own Secrets.

Environment Profile

Each entry under profiles is keyed by the Profile’s name (any text, unique within the file). It has variables and secrets, both optional; write {} for a Profile with neither.

Variables and Secrets

On every layer (Project, Service, Profile):

  • variables is a mapping of names to values. A name is a portable shell name: letters, digits and _, not starting with a digit. Values are always text: PORT_OFFSET: 10 is the text 10. An empty value (DEBUG: with nothing after it) is the empty text.
  • secrets is a list of names. A Secret’s value lives in the system’s secret store (Keychain, Secret Service or Credential Manager) and is never written to a Project file. After an import, the review lists the Secrets still to fill in; set them in the Service’s editor or in Edit Environment….
  • A name can’t be both a variable and a Secret on the same layer.

When a Service starts, its environment is built from (later ones win): the login shell’s environment, the Project’s variables, the Service’s, then the active Profile’s. PORT is set when the Service has a Port.

The YAML localhost reads

Project files use a small, strict subset of YAML, read by localhost itself:

  • block mappings (key: value, nested by indentation) and lists of single values (- item, or [a, b] on one line);
  • {} for an empty mapping;
  • plain, 'single-quoted' and "double-quoted" values (with \", \\, \n, \t, … escapes);
  • # comments.

Anything else is rejected with its line number rather than skipped: multi-line | / > values, anchors and aliases, tags, lists of mappings, nested {…} / […].

Unknown fields are errors too, so a typo (dependson:) can’t silently do nothing. A field defined twice is an error.

How export writes it

  • Fields at their default are left out (cwd is always written), and variables and Secret names are sorted, so the same configuration always gives the same file: export, import and export again gives an identical file.
  • Values that another YAML reader could take for something else than text (true, no, 8080, ~, a leading - or #, …) are written in double quotes.
  • What isn’t exported: Secret values, internal identifiers, the Projects’ order in the sidebar, whether a Project is a favourite, the app’s settings, and logs.

Importing

The import review shows the Project’s Services, its environment and the Secrets to set, and checks the file with the same rules as the app’s editors: Keys, working directories, ports, URLs, Dependencies (a Key no Service has, or a cycle such as api → web → api) and the active Profile. An invalid file is rejected with what is wrong and where, for example “Line 27, services › web › depends_on: No service in this file has the key “ap”.”

  • Folder: prefilled from path. If that folder isn’t on this machine, choose where the Project is. A file from a WSL Project imported on macOS or Linux runs on this machine, in the folder you choose.
  • Key already used by one of your Projects: choose
    • Keep both: the import gets a free Key (my-saas-2); or
    • Replace: the existing Project takes the file’s configuration and keeps its logs. Services matching by Key and Profiles matching by name keep their logs and stored Secret values; Services the file doesn’t have are stopped and removed. The review lists them.

Nothing is ever overwritten without choosing Replace.

Versions

localhost: 1 is the only format version so far. A file with a newer version than your localhost knows is refused with a message saying so; update localhost to import it.

Edit this page on GitHub

Install localhost for macOS

Two quick steps, usually under a minute.

  1. Drag it to Applications

    Open localhost-<version>.dmg and drag localhost to Applications.

    Download localhost-<version>.dmg
  2. Open it the first time

    localhost isn’t notarized by Apple yet, so macOS blocks the first launch once:

    1. Click Done in the warning.
    2. Open System Settings › Privacy & Security and scroll to Security.
    3. Click Open Anyway, and confirm with your password or Touch ID.

    Or run this in Terminal, then open localhost:

    xattr -dr com.apple.quarantine /Applications/localhost.app

macOS 15 or later · Apple silicon or Intel

  1. Run the installer

    Open localhost_<version>_x64-setup.exe. It installs for your user only, no administrator rights needed.

    Download localhost_<version>_x64-setup.exe
  2. Get past SmartScreen

    The installer isn’t signed by a known publisher yet, so Windows says “Windows protected your PC”:

    1. Click More info.
    2. Check that the file is localhost_<version>_x64-setup.exe.
    3. Click Run anyway.

Windows 10 or 11 · x64 · WSL 2 for Projects in WSL

  1. Download your package

  2. Install it

    From the folder you downloaded it to:

    sudo apt install ./localhost-app_<version>_amd64.deb
    sudo dnf install ./localhost-app-<version>-1.x86_64.rpm
    chmod +x localhost-app_<version>_amd64.AppImage && ./localhost-app_<version>_amd64.AppImage

    Secrets need a Secret Service (GNOME Keyring, KWallet). On stock GNOME the tray icon needs the AppIndicator extension.

x86_64 · Ubuntu 22.04+ · Debian 12+ · Fedora

On another system?Install guide →