CDK construct development patterns, design principles, and type-driven development. Use when building or modifying AWS CDK constructs.
Scanned 2/12/2026
Install via CLI
openskills install majiayu000/claude-skill-registry---
name: construct-development
description: CDK construct development patterns, design principles, and type-driven development. Use when building or modifying AWS CDK constructs.
---
# Construct Development Guidelines
## Construct Pattern
Use factory functions that return CDK resources:
```typescript
import {Construct} from 'constructs';
import {RemovalPolicy} from 'aws-cdk-lib';
import {Bucket, BucketEncryption, BlockPublicAccess} from 'aws-cdk-lib/aws-s3';
export type BucketProps = {
bucketName: string;
env: {
name: string;
region: string;
account: string;
};
enableVersioning?: boolean;
};
export const createBucket = (scope: Construct, props: BucketProps): Bucket => {
return new Bucket(scope, `${props.bucketName}-bucket`, {
bucketName: `${props.bucketName}-${props.env.name}-${props.env.region}`,
enforceSSL: true,
encryption: BucketEncryption.S3_MANAGED,
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
removalPolicy: props.env.name === 'prod' ? RemovalPolicy.RETAIN : RemovalPolicy.DESTROY,
versioned: props.enableVersioning ?? props.env.name === 'prod',
});
};
```
## Design Principles
### 1. Secure by Default
- Enable encryption (S3_MANAGED or KMS)
- Enforce SSL
- Block public access
- Use private subnets
### 2. Environment-Aware
- Gate expensive features to production
- Use `RemovalPolicy.RETAIN` in prod, `DESTROY` in dev
- Enable enhanced monitoring only where needed
```typescript
// Performance Insights only in prod
performanceInsightRetention: props.env.name === 'prod' ? 7 : undefined,
// Reader instances only in prod
const createReaders = props.env.account === Account.PROD && props.enableReaders;
```
### 3. Cost-Efficient
```typescript
// Performance Insights only in prod
performanceInsightRetention: props.env.name === 'prod' ? 7 : undefined,
// Reader instances only in prod
const createReaders = props.env.account === Account.PROD && props.enableReaders;
```
### 4. Observable
- Include CloudWatch log groups
- Set appropriate retention periods
- Enable metrics where applicable
## Type-Driven Development
**Use types, not interfaces.** This codebase follows type-driven development where we define all data structures using `type` declarations.
### Why Types Over Interfaces?
- More flexible for unions and intersections
- Consistent pattern across the codebase
- Better for functional programming patterns
- Clearer intent for data structures
Define all props types in `src/types/`:
```typescript
// src/types/bucket-types.ts
import {EnvironmentConfig} from '@cdk-constructs/cdk';
export type BucketProps = {
bucketName: string;
env: EnvironmentConfig['env'];
kmsKeyArn?: string;
lifecycleRules?: BucketLifecycleRule[];
};
export type BucketLifecycleRule = {
id: string;
expiration?: number;
transitions?: StorageTransition[];
};
```
## Export Pattern
Export all public APIs from `src/index.ts`:
```typescript
// src/index.ts
// Constructs
export {createBucket} from './constructs/bucket';
export {createLambda} from './constructs/lambda';
// Types
export type {BucketProps, BucketLifecycleRule} from './types/bucket-types';
export type {LambdaProps} from './types/lambda-types';
// Enums
export {StorageClass} from './enums/storage';
// Utilities
export {getAbsoluteLambdaPath} from './util/paths';
```
## JSDoc Requirements
All public functions, types, and enums should have JSDoc comments:
```typescript
/**
* Creates a CodeArtifact domain.
*
* @param scope - The parent construct
* @param id - The construct ID
* @param props - The domain properties
* @returns The created CodeArtifact domain
*
* @public
*/
export const createCodeArtifactDomain = (scope: Construct, id: string, props: CodeArtifactDomainProps): CfnDomain => {
// ...
};
```
No comments yet. Be the first to comment!