# Enforce directory structure with the Layout system







## Defining where files may be placed

`layout { }` defines where the files for a Role may be placed.

```kt {3-5}
architecture {
    "UseCase" {
        // A UseCase may only be placed as *UseCase.kt inside useCase/
        layout {
            "src/main/kotlin/com/example/useCase" / "*UseCase".ktFile()
        }
    }
}
```

## Styles for writing directory declarations

There are a few ways to write a directory declaration. You can use whichever style you prefer.

### Chaining with slashes

When each level has only one thing in it, you can chain them with `/` on a single line.

```kt
layout {
    "src/main/kotlin/com/example/useCase" / "*UseCase".ktFile()
}
```

### Wrapping in a block

When you want to place multiple things in the same directory, wrap them in a block.

```kt
layout {
    "src/main/kotlin/com/example/useCase" {
        "Get*UseCase".ktFile()
        "Update*UseCase".ktFile()
    }
}
```

Inside the block, you can write `description`. It becomes the explanation of "what this location is for" in the generated documentation.

```kt
layout {
    "src/main/kotlin/com/example/useCase" {
        description = "Used from multiple screens"
        "*UseCase".ktFile()
    }
}
```

## Allowing arbitrary files to be placed

### `anyFile()` — allow only files directly inside

Allows any file to be placed, but **only directly inside** that directory.

```kt
layout {
    "generated" { anyFile() }
}
```

**In this example, subdirectories aren't allowed.** A file one level deeper is still reported as a violation.

### `ignore()` — stop checking everything below

Stops checking everything below that directory, **at any depth**.

```kt
layout {
    "build".ignore()
}
```

You can also write it inside a block as `"build" { ignore() }`.

<Aside type="caution">
`anyFile()` and `ignore()` let you allow files of any kind to be placed, but they are **escape hatches from deny by default**. Use them with care.

If you overuse `ignore()` and `anyFile()` just because "declaring it is a hassle," you undermine the point of adopting katachi. Use them only for **things a machine generates** or **things whose structure is decided by another tool**.
</Aside>

## Naming a wildcard

`capture()`, which names a wildcard in a destination, is used together with templates. For checking layout alone you don't need `capture()`; a plain `*` is fine. See [Generating code from a template](/katachi/guides/generate-code-from-template/#when-the-destination-has-a-wildcard-name-it-and-pass-a-value) for how to write it.

## Best practices

Writing out every directory for every Role is inefficient.
Extract them into constants at a meaningful unit.

```kt {1,6}
val appPackageDir = "src/main/kotlin/com/example"

architecture {
    "UseCase" {
        layout {
            appPackageDir / "useCase" / "*UseCase".ktFile()
        }
    }
}
```

## Summary

- `layout { }` declares **where a Role's files may appear**. A file in an undeclared location is a violation.
- `anyFile()` and `ignore()` let you allow files of any kind to be placed, but they are **escape hatches from deny by default**. Use them with care.
- `capture()`, which names a wildcard in a destination, is used together with templates ([Generating code from a template](/katachi/guides/generate-code-from-template/#when-the-destination-has-a-wildcard-name-it-and-pass-a-value)). For checking layout alone, a plain `*` is fine.

```kt {1,6-8,16,23}
val appPackageDir = "src/main/kotlin/com/example"  // paths can be pulled out into constants

architecture {
    "UseCase" {
        layout {
            appPackageDir / "useCase" / "*UseCase".ktFile()   // join with "/" to declare where files go
            appPackageDir {                                    // wrapping in a block declares the same thing
                "legacy" / "*UseCase".ktFile()
            }
        }
    }

    "GeneratedFile" {
        summary = "Files generated by a tool"
        layout {
            "generated" { anyFile() }   // any file directly inside is allowed (no subdirectories)
        }
    }

    "BuildOutput" {
        summary = "Build output"
        layout {
            "build".ignore()            // nothing below is checked
        }
    }
}
```

## Next steps

- [Role](/katachi/guides/role/) ... Learn how to split a definition into files and functions as it grows.
- [Konsist integration](/katachi/guides/konsist-integration/) ... Learn how to constrain not just placement but also the contents of files.
- [Your first architecture definition](/katachi/get-started/first-architecture/) ... Introduce katachi into your project and actually write a declaration.