A Helix project has exactly one config file: helix.config.ts at the project root. It holds the project’s name, its project and workspace IDs, the Helix environment the CLI talks to, and the map of auth aliases to credential UUIDs. You rarely edit it by hand, because helix init, helix workspace select, helix project set, and helix env set write to it for you.
What the file holds
// helix.config.ts
import { defineConfig } from '@trayai/helix-sdk';
export default defineConfig({
name: 'customer-health',
projectId: 'a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d',
workspaceId: 'f8e7d6c5-4b3a-2190-8765-abcdef012345',
environment: 'us1',
authentications: {
salesforce: '1a0fbf5c-2c9e-4aa1-ada3-ccbba65019ab',
},
});
| Key | What it names |
|---|---|
name | The project name. The first deploy uses it when it provisions the project on the platform. |
projectId | The provisioned project this checkout points at. Unset until a deploy provisions one, or until you set it yourself. |
workspaceId | The Tray workspace the project belongs to. Auth aliases resolve against it, locally and on deploy. |
environment | The Helix environment the CLI talks to, for example us1. |
authentications | Alias to credential UUID, used as ctx.http.authed('alias') in function code. |
workspaceId is the one you need early: ctx.http.authed('alias') resolves against the workspace’s auth service during helix dev, not only in production. projectId matters when you deploy, and for anything the platform provisions for the project. Persistent key-value storage is the clearest case: with no project ID, helix dev has nothing provisioned to read from and falls back to in-memory storage that resets on restart.
See projects and workspaces for what each UUID refers to.
The CLI writes the file
| Command | What it writes |
|---|---|
helix init | Creates the file. --project-id and --workspace-id fill in those IDs; without them the ID is prompted for or left unset. |
helix workspace select [name] | Picks a workspace interactively, then writes workspaceId. |
helix workspace set <id> | Writes workspaceId when you already know the ID, for scripts and CI. |
helix project set <id> | Writes projectId, pointing this checkout at an existing provisioned project. |
helix env set <environment> | Writes the environment and persists it for later commands. |
The file is ordinary TypeScript, so you can edit it directly instead. The commands exist so CI pipelines and agent sessions don’t have to rewrite source to change which project they talk to. Full flags are in the project and auth session commands.
Environments
Two separate mechanisms select an environment, and they don’t overlap.
helix env set sets the environment for the project and stores it in the config file:
helix env set us1
--env sets the environment for a single session command, and reads nothing from the config file:
helix login --env staging
helix whoami --env staging
helix logout --env staging
login, logout, and whoami accept --env <us1|staging> and default to us1. Your session is per environment, which is why authenticating against staging is a flag on the command rather than a change to the committed file. The full set of names helix env set accepts isn’t confirmed; run helix env set --help to see what your version lists.
What stays out of the file
- Credential values. The file maps aliases to UUIDs. The credentials themselves, and the rules for injecting them, stay on Helix’s servers. See the security model.
- Your Tray session. The token from
helix loginlives in~/.tray.config, outside the project and shared withconnector-cli. - Function-level settings. Handlers and input schemas live in the function files, through
defineFunction. - Who can open the deployed app. Access is a setting on the project’s Access Control tab in the dashboard, not a config key. See identity and roles.
Roadmap
For every key the config accepts, see the configuration reference.