Getting started

Init

Set up a new repo in one command: create the project, create its environments, and write the .envless file.

Usage

bash
envless init
envless init [name...]
envless init --name "Payments API" --slug payments
envless init --env development,production
envless init --workspace acme --product web --yes

init is the first command to run in a fresh repo. It creates a project inside a product of your workspace, creates the environments for it one by one, writes the .envless file, and prints the next three steps. There are no subcommands and no flags to remember for the common case, because the name defaults to the current directory and the environments default to development, staging, and production.

The envless command ships in @goenvless/cli. Install it with npm i -g @goenvless/cli@latest.

Nothing here reads or decrypts a value, so init never asks for a passphrase and a locked workspace does not stop it. See Concepts for how a workspace, a product, a project, and an environment nest.

bash
$ envless init --help
envless init
  Create a project with its environments, then link this directory to it.

USAGE
  envless init                            Guided setup, asks for what it needs
  envless init Payments API               Name the project inline
  envless init --name "Payments API" --slug payments
                                         Set the name and slug without prompts
  envless init --env development,production
                                         Pick the environments to create
  envless init --workspace acme --product web --yes
                                         Unattended, no prompts at all

DEFAULTS
  name          the current directory name
  environments  development, staging, production

A first run

Inside an empty payments-api/ directory, in a workspace that has one product:

bash
$ envless init Payments API
┌  envless init
✔ Project Payments API (payments-api)
✔ Environment development (development)
✔ Environment staging (staging)
✔ Environment production (production)
│
└  ✓ Linked to Payments API with development, staging, production
   1. envless passphrase set to unlock the workspace
   2. envless var set KEY=value to add a variable
   3. envless sync to pull them into .env files

The .envless file is written to the current directory once at least one environment exists, with the slugs the API handed back rather than the words you typed. It holds only slugs, so commit it.

.envless
{
    "workspace": "acme",
    "product": "web",
    "project": "payments-api",
    "environments": [
        "development",
        "staging",
        "production"
    ]
}

Follow the three steps in the outro to finish the setup. Run envless passphrase set once per machine to unlock the workspace, add variables with envless var set, then envless sync writes a .env.<slug> file per environment.

Naming the project

The name is the positional words after init, joined with a single space, so quoting is optional. --name is read only when you pass no words at all. With neither, an interactive terminal prompts for the name and pre-fills the current directory name, so pressing enter accepts it.

bash
$ envless init
┌  envless init
│
◆  Project name
│  payments-api

Names are 3 to 50 characters. The prompt refuses a bad answer inline, and a name that comes from a flag or from the directory is checked straight after, before any project is created:

bash
$ envless init AB
┌  envless init
✗ Project name needs at least 3 characters. Pass --name to set one.

The run then closes with Aborted. and exits 1. On a non-interactive shell, and with --yes, there is no prompt at all and the directory name is used, so a directory with a two-character name needs --name.

--slug is optional. Leave it out and the API derives the slug from the name, so Payments API becomes payments-api. Whatever the API returns is what lands in .envless.

Environments

--env takes a comma-separated list and replaces the default three. They are created in the order given, one request each, and a repeated name is only created once.

bash
envless init --env development,production
envless init Payments API --env production

Each environment gets its own line, so a plan limit or a name clash shows up next to the environment it belongs to instead of failing the whole command. Add more later with envless env create, then run envless link again to put them in .envless.

Re-running in a linked directory

init always creates a new project, so it refuses to overwrite a valid existing .envless without your say-so. On a terminal it shows the current binding first and defaults to No, which makes envless init in a linked directory a safe way to read the binding back.

bash
$ envless init
┌  envless init
│
◇  This directory is already linked ─╮
│  workspace   acme                  │
│  product     web                   │
│  project     payments-api          │
│  environment development, staging  │
├────────────────────────────────────╯
│
◆  Create a new project and re-link this directory?  ○ Yes / ● No
│
└  Kept the existing link.

Answering No exits 0 and touches nothing. Answering Yes creates a second project and overwrites .envless with it, and the old project is left alone in the dashboard. To change the binding without creating anything, use envless link instead.

The existing file also feeds the resolver, so a re-init reuses the workspace and product from .envless unless --workspace, --product or ENVLESS_PRODUCT says otherwise.

Without a TTY the confirmation cannot be asked, so init stops rather than guessing. --yes skips the confirmation and is what unattended runs pass:

bash
$ envless init
┌  envless init
✗ This directory is already linked to payments-api. Pass --yes to start over.

Both the question and that stop key off a .envless the CLI can read back. A file that is not valid JSON, or that is missing workspace, missing project, or missing a non-empty list of environments, counts as no link at all, so nothing is asked before the project is created, terminal or not. That file stops feeding the resolver too, so the workspace and the product have to come from a flag, from ENVLESS_PRODUCT, or from the default set by envless workspace use, exactly as in a directory that was never linked.

Unattended use

bash
envless init --workspace acme --product web --env development,production --yes

--yes (or -y) skips both prompts init owns, the re-link confirmation and the name prompt. Pass --workspace and --product too and there is nothing left to ask, which is what makes the command safe in a script.

--project and ENVLESS_PROJECT are ignored here, because init is the command that creates the project. Everything else about resolution matches the other write commands: the workspace comes from --workspace, then .envless, then the default set by envless workspace use, the product from --product, then ENVLESS_PRODUCT, then .envless, then a picker.

When an environment fails

If some environments are created and some are not, the ones that worked are still written to .envless, the rest are named, and the exit code is 1 so a script notices. The free plan allows two environments per project, so the default three stop after the second:

bash
$ envless init Payments API
┌  envless init
✔ Project Payments API (payments-api)
✔ Environment development (development)
✔ Environment staging (staging)
✖ Could not create production (Plan limit reached.).
⚠ Could not create production. Add it with envless env create <name>.
│
└  ! Linked to Payments API with development, staging
   1. envless passphrase set to unlock the workspace
   2. envless var set KEY=value to add a variable
   3. envless sync to pull them into .env files

If no environment is created at all, there is nothing valid to write, so .envless is skipped. The project still exists, so pick up where it stopped rather than running init again:

bash
$ envless init Payments API --env staging
┌  envless init
✔ Project Payments API (payments-api)
✖ Could not create staging (The user is not authorized to create environments in this workspace.).
⚠ Skipped the .envless file because no environment was created.
│
└  ! Payments API exists with no environments. Run envless env create development then envless link.

A failed project create is the same shape one step earlier. It prints ✖ Could not create the project (<reason>)., aborts, and exits 1. Plan limits, slug conflicts and permission errors all arrive as the API reason inside those parentheses.

Flags

FlagDescription
--name <name>Name to create with, read only when you pass no positional words. Falls back to the current directory name.
--slug <slug>Slug for the new project. Left out, the API derives it from the name.
--env <a,b>Environments to create, comma-separated, in the order given. Defaults to development,staging,production. Repeats are dropped.
--workspace <slug|id>Workspace to create in. Falls back to an existing .envless, then to the default set by envless workspace use.
--product <slug|id>Product to create in. Falls back to ENVLESS_PRODUCT, then .envless, then a picker.
--yes, -ySkips the re-link confirmation and the name prompt. Required when there is no TTY and a valid .envless exists.
--help, -hPrints the usage block and exits 0.

A value flag with nothing after it is a usage error, not an empty value:

bash
$ envless init --env
✗ --env needs a value.

That prints the usage block and exits 2, before anything is created. The check covers every value flag the CLI knows, so --name, --slug, --product and --workspace behave the same way, and so does --project, whose value init otherwise ignores.

Requirements

You must be signed in with envless login. With no session, init stops before it prints anything else:

bash
$ envless init
✗ Not signed in. Run envless login first.

This is a write command, so it needs a device login rather than a machine key. An ev_sk_ token in ENVLESS_TOKEN is rejected up front:

bash
$ envless init
✗ Machine keys are read only. Run envless login to write from this machine.

The workspace has to be known. It comes from --workspace first, the .envless file second, and the default set by envless workspace use third, so a saved default is enough to run init in a fresh directory. With none of the three, init names the flag it needs. A workspace with one product picks it silently, a workspace with several opens a picker on a TTY and asks for --product when there is none, and a workspace with no products at all is fine: the API creates a Default product to hold the project.

bash
$ envless init
✗ Missing --workspace. Pass it inline, run envless link, or pick a default with envless workspace use <slug|id>.

That exits 1, as does an identifier that resolves to nothing, for example ✗ Product web not found in Acme.. On a workspace with several products and no TTY it asks for the flag rather than blocking on a picker: ✗ Missing --product. Acme has 3 products, so pass one inline or run envless link first.

No workspace key is involved. init only writes metadata, so there is no passphrase prompt and no ENVLESS_KEY to set. Unlocking comes later, on the first command that touches a value.

Exit codes

CodeWhen
0Success, --help, answering No to the re-link confirmation, and cancelling either of the two prompts init owns.
1Not signed in, machine key rejected, workspace or product unresolved including a cancelled product picker, several products with no --product on a non-TTY, a valid existing .envless with no TTY and no --yes, a name outside 3 to 50 characters, a failed project create, or one or more environments that could not be created.
2A value flag passed with no value.

A partial run exits 1 even though the project, some environments and .envless were all written. Treat a non-zero init as "check what landed", not as "nothing happened".