# Using Custom Component Types

Beyond the native component types, Atmos lets you define **custom component types** so you can manage _any_ tool—AWS CDK, Pulumi, Bicep, database migrations, and more—with the same stack-based configuration system used for Terraform, Helmfile, and Packer.

:::note CloudFormation components
Use the built-in [CloudFormation component](/stacks/components/aws-cloudformation)
and [CloudFormation commands](/cli/commands/aws/cloudformation) to deploy templates.
The component type is currently experimental.
:::

Custom component types are defined through [custom commands](/cli/configuration/commands). Unlike the native types, which ship with built-in orchestration, a custom type is one you wire up yourself: you declare the type on a custom command and supply the execution `steps`, while Atmos handles stack resolution, inheritance, and configuration merging exactly as it does for native components.

## How It Works

Define a `component.type` on a custom command and tell Atmos which argument provides the component name and which provides the stack name. Atmos then looks up `components.<type>.<name>` from your stack manifests and exposes the fully resolved configuration via `{{ .Component.* }}`.

```yaml
# atmos.yaml
commands:
  - name: example
    description: "Run example components"
    arguments:
      - name: component
        provides: component      # Provides the component name
        required: true
    flags:
      - name: stack
        shorthand: s
        provides: stack           # Provides the stack name
        required: true
    component:
      type: example               # Your custom component type
    steps:
      - 'echo "App: {{ .Component.vars.app_name }}"'
      - 'echo "Version: {{ .Component.vars.version }}"'
```

Configure the component in stack manifests just like a native type—with full imports and inheritance:

```yaml
# stacks/deploy/dev.yaml
components:
  example:                        # Matches component.type
    deploy-app:
      vars:
        app_name: "myapp"
        version: "1.0.0"
```

Run it:

```shell
atmos example deploy-app --stack dev
# App: myapp
# Version: 1.0.0
```

Global `vars`, `settings`, and `env` are merged automatically, and a component's `env` section is exported as real environment variables—making it straightforward to pass [secrets](/cli/configuration/secrets) securely.

## Implement components with Starlark

Use [Atmos scripting](/scripting), based on Starlark, to implement custom components
with validation, conditions, loops, and reusable functions. The interpreter ships
with Atmos. Replace the command's shell steps with a `type: script` step:

```yaml
    steps:
      - type: script
        interpreter: starlark
        script: |
          component = ctx.component
          if not component.vars.get("app_name"):
              fail("app_name is required")
          print("App: {}".format(component.vars["app_name"]))
          print("Version: {}".format(component.vars["version"]))
```

[`ctx.component`](/functions/automation/ctx.component) provides the resolved
component configuration. Use its [`exec()` method](/functions/automation/component.exec)
to call tools from the component directory, and move shared logic into `.star`
files with [`!include`](/steps/type/script#loading-files). Atmos supports
[tests](/scripting/testing) for these functions and commands.

Here, `example` names the custom command and component type; `script` names the
step type that runs the Starlark implementation.

## Native vs. Custom

| Aspect | Native types (Terraform/Helmfile/Packer/Ansible) | Custom types |
|--------|--------------------------------------------------|--------------|
| Orchestration | Built into Atmos | You supply the `steps` |
| Definition | Always available | Defined via a custom command |
| Stack configuration | `components.<type>.<name>` | `components.<type>.<name>` |
| Configuration access | Native flags/varfiles | `{{ .Component.* }}` templates or `ctx.component` in Starlark |

## Try It

Explore a complete, working example that defines a custom `example` component type and configures it through stacks.

## Related

- [Custom Component Types](/cli/configuration/commands/component#custom-component-types) — Full reference, including template variables and configuration options
- [Custom Commands](/cli/configuration/commands) — How to define custom commands
- [Introducing Custom Component Types](/changelog/custom-component-types) — Background and real-world examples
