Resource Naming
Show the whole prompt
Read https://intentius.io/chant/guide/resource-naming/.
Rename this project's exports to clear camelCase names, as the page describes, and update every import of each one.
Where environments must coexist, add an `env` build parameter and put it in each resource's name, and check that `npx chant build --env <name>` gives each environment distinct names.
Run `npx chant build` and `npx chant lint`, list every logical name that changed, and open a pull request.
Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.Optional: hand this page to your coding agent
Read https://intentius.io/chant/guide/resource-naming/.Rename this project's exports to clear camelCase names, as the page describes, and update every import of each one.Where environments must coexist, add an `env` build parameter and put it in each resource's name, and check that `npx chant build --env <name>` gives each environment distinct names.Run `npx chant build` and `npx chant lint`, list every logical name that changed, and open a pull request.Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.chant discovers resources by scanning exports from your src/ files. The export name becomes the logical resource name that lint output, build logs and cross-file imports show.
Export naming
Section titled “Export naming”Exports must use camelCase; lint rule COR005 enforces it.
// ✅ correctexport const appBucket = new Bucket({ ... });export const taskQueue = new Queue({ ... });
// ❌ rejected by COR005export const AppBucket = new Bucket({ ... });export const app_bucket = new Bucket({ ... });Descriptive names
Section titled “Descriptive names”Name exports after what the resource does, not what it is. Suffix with the resource’s role to distinguish resources of the same type.
// ✅ clear purposeexport const uploadBucket = new Bucket({ ... });export const taskQueue = new Queue({ ... });export const apiRole = new Role({ ... });
// ❌ ambiguousexport const bucket1 = new Bucket({ ... });export const myQueue = new Queue({ ... });Shared configuration
Section titled “Shared configuration”When multiple resources share naming prefixes or tags, extract them into a const object. Template literals keep physical names consistent across the stack.
import { Bucket, Queue } from "@intentius/chant-lexicon-aws";
const app = { name: "myapp", team: "platform" } as const;
export const sharedDataBucket = new Bucket({ BucketName: `${app.name}-data`, Tags: [{ Key: "Team", Value: app.team }], PublicAccessBlockConfiguration: { BlockPublicAcls: true, BlockPublicPolicy: true, IgnorePublicAcls: true, RestrictPublicBuckets: true, },});
export const taskQueue = new Queue({ QueueName: `${app.name}-tasks`, Tags: [{ Key: "Team", Value: app.team }],});Because the config object is as const, chant’s evaluator can resolve every value at build time.
Multiple similar resources
Section titled “Multiple similar resources”Plain TypeScript replaces count and for_each. Use Array.map to create a set of resources, then destructure the result into named exports:
import { Bucket } from "@intentius/chant-lexicon-aws";
const envs = ["dev", "staging", "prod"] as const;
const buckets = envs.map( (env) => new Bucket({ BucketName: `myapp-${env}-data`, PublicAccessBlockConfiguration: { BlockPublicAcls: true, BlockPublicPolicy: true, IgnorePublicAcls: true, RestrictPublicBuckets: true, }, }));
export const [devData, stagingData, prodData] = buckets;Each destructured export (devData, stagingData, prodData) is a distinct named resource that can be referenced from other files via import.
Multi-environment coexistence
Section titled “Multi-environment coexistence”Two builds of the same stack produce identical physical names, so deploying both into one account collides. When a project declares more than one environment, put the environment identity into the names. There are two working shapes.
One build per environment
Section titled “One build per environment”Declare an env build parameter, bind the ownership marker to it, and interpolate params.env into every name that must be unique per instance:
export default { ownership: { stack: "billing", env: { param: "env" } }, buildParams: { env: { type: "string", default: "dev" }, }, environments: ["dev", "staging", "prod"],} satisfies ChantConfig;import { params } from "@intentius/chant/params";
export const uploadBucket = new Bucket({ bucketName: `billing-${params.env}-uploads`,});params.env resolves before any file is imported, so the template literal folds to a plain string such as billing-staging-uploads. Build once per environment:
chant build --param env=stagingchant build --param env=prodThe two builds yield disjoint physical names and disjoint ownership markers (chant.intentius.io/env follows the same parameter — see Build-Time Parameters), so --owned filtering, drift, and delete stay scoped to one instance each.
All environments in one build
Section titled “All environments in one build”The alternative keeps every environment in one build: instantiate the same composite once per environment, each call passing its own name (web-dev, web-staging, web-prod). This is the layered configuration pattern: a base config, per-environment overrides via object spread, one manifest containing all instances.
Choose per-env builds when environments deploy independently (separate accounts, separate pipelines, short-lived copies); choose the all-in-one shape when one apply should converge every environment at once.
--env feeds params.env through CHANT_ENV
Section titled “--env feeds params.env through CHANT_ENV”chant build --env <name> sets the CHANT_ENV environment variable before the project is discovered. A build parameter can declare that variable as its fallback, which turns --env into a validated way to supply params.env:
buildParams: { env: { type: "string", default: "dev", env: "CHANT_ENV" },},environments: ["dev", "staging", "prod"],Now chant build --env staging and chant build --param env=staging bind the same value. The --env route has one extra property: the CLI rejects an --env value that is not among the declared environments, so a typo like --env stagign fails before anything builds. --param env= takes precedence over the CHANT_ENV fallback when both are supplied, per the normal precedence rules.
File organization
Section titled “File organization”Group related resources in the same file and keep unrelated ones separate. The lint rule COR009 warns when a single file exports eight or more resources, a sign the file may be doing too much.
A typical layout:
src/ storage.ts # buckets, tables compute.ts # functions, containers networking.ts # VPCs, subnets, security groups iam.ts # roles, policiesNext steps
Section titled “Next steps”- Cross-File References — import resources from other files
- Composite Resources — group related resources into reusable units
- Build-Time Parameters — the
params.envmechanism the multi-environment patterns build on - Layered Configuration — the all-in-one multi-environment pattern in full