Axis IS CDK
Most backend frameworks that sit on infrastructure tooling eventually hit the same wall: the wrapper exposes only what its authors thought to expose, and the day you need anything else you’re fighting the framework. Axis is built so that day never comes.
Extend, never wrap
Section titled “Extend, never wrap”Every Axis construct and stack extends the corresponding CDK class, and every Axis props interface extends the CDK props with only the Axis-controlled fields removed:
// ✓ Correct — Axis extends CDKexport interface AtfCognitoProps extends Omit< cognito.UserPoolProps, "userPoolName" | "customAttributes" | "lambdaTriggers" | "removalPolicy"> { // Axis-specific additions…}
// ✗ Wrong — wrapping creates a ceilingexport interface WrappedCognitoProps { mfa?: boolean; // only what the authors thought to expose}The WrappedCognitoProps half is illustrative fiction — no such type exists in Axis, by design. The real interface is AtfCognitoProps; its full, always-current field list is generated straight from the source in the API reference (and linked from the AtfCognito construct page), so it can never drift from what the framework actually accepts.
The consequences are the point:
- Every CDK prop Axis doesn’t control is available directly, with full IDE autocomplete. There is no
cdkOverridesescape hatch, because none is needed. - New CDK features are available immediately. When
aws-cdk-libships a new prop, your Axis project can use it the same day, with no framework release in between. - Defaults are suggestions, not walls. Axis sets defensible defaults (the five pillars) and lets you override anything it hasn’t deliberately taken ownership of.
Index signatures like [key: string]: unknown are prohibited in Axis config types — they kill autocomplete and let typos compile silently. The typed Omit is the whole trick.
What Axis takes ownership of
Section titled “What Axis takes ownership of”The Omit-ted fields are the framework’s responsibility, because they’re the ones that hurt when they go wrong:
- Physical naming — every resource is
${baseName}-${stageName}, so environments never collide and names are predictable everywhere (console, SSM paths, IAM policies). - Removal policies — stateful resources retain in prod and destroy cleanly in dev. You cannot accidentally hand-set a prod table to
DESTROY. - Construct IDs — the CloudFormation logical-ID surface is frozen and CI-gated. See Logical-ID Permanence.
- Cross-stack wiring — always SSM Parameter Store, never CloudFormation exports. See Stacks & SSM Wiring.
Explicit over implicit
Section titled “Explicit over implicit”The second habit that runs through the whole framework: every wiring decision is visible at the call site. Trigger maps name their trigger type; registries import their configs explicitly; nothing is matched up by naming convention, because name-matching breaks silently when a name changes.
Where this shows up next
Section titled “Where this shows up next”The same principle scales from a single construct up to whole applications: stacks are abstract classes you extend, and the composer lets you substitute an entire Axis stack with your own raw-CDK stack as long as it honours the SSM contract. When you extend Axis yourself, the same rules apply — see Extending Axis. Axis is CDK all the way down — there is always a next level of control, and it’s always plain CDK.
© 2026 Axis Tech. Powered by axis-tech.co.