Overview
Projen turns a single TypeScript definition into all repository configuration. Instead of maintaining dozens of JSON and YAML files by hand, you describe everything in .projenrc.ts and run npx projen to regenerate.
What is Projen?
Projen was created by former AWS CDK maintainers to bring CDK's infrastructure-as-code philosophy to project configuration. It ensures formatting, linting, workflows, and task automation stay consistent with the definition you check into source control.
Key principle: The .projenrc.ts file is the single source of truth. All generated files are outputs, not inputs.
Why the starter kit uses Projen
| Benefit | Description |
|---|---|
| Environment-aware automation | Each environment in .projenrc.ts produces matching npm scripts and GitHub Actions workflows with correct AWS accounts, regions, and branch settings |
| Governed defaults | Enforces shared settings (Biome formatting, Dependabot grouping, Node.js versions, gitignore patterns) so new projects start with recommended baselines |
| Self-healing config | When dependencies or settings change, updating .projenrc.ts and rerunning Projen regenerates the repo to match |
| Reviewable changes | Configuration changes show up as diffs in pull requests |
How it works
Configuration flow
The regeneration cycle
- Edit
.projenrc.ts - Run
npx projen - Review generated file changes
- Commit all changes together
Key sections in .projenrc.ts
Environment configuration
const environmentConfigs: (EnvironmentConfig & { name: Environment })[] = [
{ name: 'test', accountId: '987654321012', enableBranchDeploy: true },
{ name: 'production', accountId: '123456789012', enableBranchDeploy: false },
];
This array drives task and workflow generation. Each entry creates:
- npm scripts for synth, diff, deploy, destroy
- GitHub Actions workflows for deployment
- Branch deployment tasks (if enabled)
Task generation
for (const config of environmentConfigs) {
addCdkActionTask(project, {
CDK_DEFAULT_ACCOUNT: config.accountId,
CDK_DEFAULT_REGION: awsRegion,
ENVIRONMENT: config.name,
GITHUB_DEPLOY_ROLE: githubRole,
});
}
Workflow generation
for (const config of environmentConfigs) {
createCdkDeploymentWorkflows(
project.github,
config.accountId,
awsRegion,
config.name,
githubRole,
nodeVersion,
config.enableBranchDeploy,
orderedEnvironments,
);
}
Files Projen manages
| File/Directory | Purpose |
|---|---|
package.json | Dependencies, scripts, metadata |
tsconfig.json | TypeScript configuration |
.github/workflows/ | CI/CD workflows |
.gitignore | Git ignore patterns |
biome.json | Code formatting and linting |
.projen/ | Projen internal files |
Warning: Never edit generated files directly. Changes will be overwritten on the next
npx projenrun.
Common operations
Add a new environment
// In .projenrc.ts
{ name: 'staging', accountId: '111222333444', enableBranchDeploy: false },
Then regenerate:
npx projen
Change Node.js version
// In .projenrc.ts
const nodeVersion = '22';
Add a dependency
// In .projenrc.ts
project.addDeps('lodash');
project.addDevDeps('@types/lodash');
Modify npm scripts
Projen generates scripts via task definitions. To add custom tasks:
project.addTask('my-task', {
exec: 'echo "Hello from custom task"',
});
Escape hatches
Sometimes you need to override generated content. Projen provides escape hatches:
// Override a specific file
project.tryFindObjectFile('package.json')?.addOverride('scripts.custom', 'my-command');
// Add content that won't be overwritten
project.gitignore.addPatterns('my-custom-file.txt');
Use escape hatches sparingly. If you find yourself using many overrides, consider whether Projen is the right fit for that configuration.
Learn more
- Projen GitHub repository
- AWS CDK Starter Kit repository
- Install guide - Setup that relies on Projen
- Environments - Environment configuration
- Helpers - Task and workflow generators