---
title: Commands
---

## tach init

Tach provides a guided setup process in `tach init`. This command will provide guidance and perform validation,
while walking through `tach mod`, `tach sync` and `tach show`.

New users should start with this command.

```bash
usage: tach init [-h] [--force]

Initialize a new project

options:
  -h, --help  show this help message and exit
  --force     Force re-initialization if project is already configured.
```

## tach mod

Tach provides an interactive editor for configuring your module boundaries - `tach mod`.

```bash
usage: tach mod [-h] [-d [DEPTH]] [-e file_or_path,...]

Configure module boundaries interactively

options:
  -h, --help            show this help message and exit
  -d [DEPTH], --depth [DEPTH]
                        The number of child directories to expand from the root
  -e file_or_path,..., --exclude file_or_path,...
                        Comma separated path list to exclude. tests/, ci/, etc.
```

Running `tach mod` will open an editor in your terminal where you can mark your module boundaries.

You can navigate with the arrow keys, mark individual modules with `Enter`, and mark all siblings
as modules with `Ctrl + a`.

You can also mark your Python [source roots](configuration#source-roots) by pressing `s`.
This allows Tach to understand module paths and correctly identify first-party imports.

You can mark modules as [utilities](configuration#modules) by pressing `u`. This is appropriate for modules like `utils/`, which can be freely used by the rest of the code.

To save your modules, use `Ctrl + s`. Otherwise, to exit without saving, use `Ctrl + c`.

Any time you make changes with `tach mod`, run [`tach sync`](commands#tach-sync)
to automatically configure dependency rules.

## tach sync

Tach can automatically sync your project configuration (`tach.toml`) with your project's actual dependencies.

```bash
usage: tach sync [-h] [--add] [-e file_or_path,...]

Sync constraints with actual dependencies in your project.

options:
  -h, --help            show this help message and exit
  --add                 add all existing constraints and re-sync dependencies.
  -e file_or_path,..., --exclude file_or_path,...
                        Comma separated path list to exclude. tests/, ci/, etc.
```

When this command runs, Tach will analyze the imports in your Python project.

Any undeclared dependencies will be automatically resolved by
adding the corresponding dependencies to your `tach.toml` file.

With `--add`,
any missing dependencies in your `tach.toml` will be added, but does not remove unused dependencies.

When run without the `--add` flag, `tach sync` will remove modules from the `tach.yml` file that do not exist in the project's source roots.

## tach check

Tach will flag any unwanted imports between modules. We recommend you run `tach check` like a linter or test runner, e.g. in pre-commit hooks, on-save hooks, and in CI pipelines.

```bash
usage: tach check [-h] [--exact] [--dependencies] [--interfaces] [-e file_or_path,...]

Check existing boundaries against your dependencies and module interfaces

options:
  -h, --help            show this help message and exit
  --exact               When checking dependencies, raise errors if any dependencies are unused.
  --dependencies        Check dependency constraints between modules. When present, all checks must be explicitly enabled.
  --interfaces          Check interface implementations. When present, all checks must be explicitly enabled.
  -e file_or_path,..., --exclude file_or_path,...
                        Comma separated path list to exclude. tests/, ci/, etc.
```

Using the `--dependencies` or `--interfaces` flag will limit the checks performed to the respective category.
By default, all checks will be performed.

### Dependency Errors
An error will indicate:

- the file path in which the error was detected
- the module associated with that file
- the module associated with the attempted import

If `--exact` is provided, additional errors will be raised if a dependency exists in `tach.toml` that does not exist in the code.

Example:

```bash
> tach check
❌ tach/check.py[L8]: Cannot import 'tach.filesystem'. Module 'tach' cannot depend on 'tach.filesystem'.
```

NOTE: If your terminal supports hyperlinks, you can click on the failing file path to go directly to the error.


### Interface Errors
An error will indicate:

- the file path in which the error was detected
- the module associated with that file
- the module associated with the attempted import
- the non-public member associated with the attempted import

Example:

```bash
❌  tach/mod.py[L13]: Module 'tach.interactive' has a defined public interface. Only imports from the public interface of this module are allowed. The import 'tach.interactive.get_selected_modules_interactive' (in module 'tach.mod') is not public.
```

NOTE: If your terminal supports hyperlinks, you can click on the failing file path to go directly to the error.

## tach report

Tach can generate a report showing all the dependencies and usages of a given module.

```bash
usage: tach report [-h] [--dependencies] [--usages] [--external] [-d module_path,...] [-u module_path,...] [--raw] [-e file_or_path,...] path

Create a report of dependencies and usages.

positional arguments:
  path                  The path or directory path used to generate the report.

options:
  -h, --help            show this help message and exit
  --dependencies        Generate dependency report. When present, all reports must be explicitly enabled.
  --usages              Generate usage report. When present, all reports must be explicitly enabled.
  --external            Generate external dependency report. When present, all reports must be explicitly enabled.
  -d module_path,..., --dependency-modules module_path,...
                        Comma separated module list of dependencies to include [includes everything by default]
  -u module_path,..., --usage-modules module_path,...
                        Comma separated module list of usages to include [includes everything by default]
  --raw                 Group lines by module and print each without any formatting.
  -e file_or_path,..., --exclude file_or_path,...
                        Comma separated path list to exclude. tests/, ci/, etc.
```

By default, this will generate a textual report showing the file and line number of each module dependency, module usage, and external dependency. Each section corresponds to a command line flag.

The given `path` can be a directory or a file path. The [module](../configuration#modules) which contains the given path will be used to determine which imports to include in the report.
Generally, if an import points to a file which is contained by a different module, it will be included.

The `--dependencies` flag includes module dependencies, meaning any import which targets a different module within your project. For example, if `core.api` and `core.services` are marked as modules,
then an import of `core.api.member` from within `core.services` would be included in a report for `core/services`.

The `--usages` flag includes module usages, meaning any import which comes from a different module within your project. For example, if `core.api` and `core.services` are marked as modules,
then an import of `core.services.member` from within `core.api` would be included in a report for `core/services`.

The `--external` flag includes external (3rd party) dependencies, meaning any import which targets a module outside of your project. For example, importing `pydantic` or `tomli` would be included in this report.

<Note>
  It is recommended to run Tach within a virtual environment containing all of
  your dependencies across all packages. This is because Tach uses the
  distribution metadata to map 3rd party module names like 'git' to their distributions
  ('GitPython').
</Note>

Supplying the `--raw` flag will group the results by module name and eliminate formatting, making the output more easily machine-readable.

## tach show

Tach will generate a visual representation of your dependency graph!

```bash
usage: tach show [-h] [--web] [--mermaid] [-o [OUT]] [included_paths ...]

Visualize the dependency graph of your project.

positional arguments:
  included_paths        Paths to include in the module graph. If not provided, the entire project is
                        included.

options:
  -h, --help            show this help message and exit
  --web                 Open your dependency graph in a remote web viewer.
  --mermaid             Generate a mermaid.js graph instead of a DOT file.
  -o [OUT], --out [OUT]
                        Specify an output path for a locally generated module graph file.
```

These are the results of `tach show --web` on the Tach codebase itself:
![tach show](assets/tach_show.png)

## tach test

Tach also functions as an intelligent test runner.

```
usage: tach test [-h] [--base [BASE]] [--head [HEAD]] [--disable-cache] ...
Run tests on modules impacted by the current changes.
positional arguments:
  pytest_args      Arguments forwarded to pytest. Use '--' to separate
                   these arguments. Ex: 'tach test -- -v'
options:
  -h, --help       show this help message and exit
  --base [BASE]    The base commit to use when determining which modules
                   are impacted by changes. [default: 'main']
  --head [HEAD]    The head commit to use when determining which modules
                   are impacted by changes. [default: current filesystem]
  --disable-cache  Do not check cache for results, and
                   do not push results to cache.
```

Using `pytest`, running `tach test` will perform [impact analysis](https://martinfowler.com/articles/rise-test-impact-analysis.html) on the changes between your current filesystem and your `main` branch to determine which test files need to be run.
This can dramatically speed up your test suite in CI, particularly when you make a small change to a large codebase.
This command also takes advantage of Tach's [computation cache](caching).

## tach check-external

Tach can validate that the external imports in your Python packages match your declared package dependencies in `pyproject.toml`.

```bash
usage: tach check-external [-h] [-e file_or_path,...]

Perform checks related to third-party dependencies

options:
  -h, --help  show this help message and exit
  -e file_or_path,..., --exclude file_or_path,...
                        Comma separated path list to exclude. tests/, ci/, etc.
```

For each `pyproject.toml` found from the project root, Tach will scan all imports in the associated Python source and compare them with the declared dependencies.
Tach will report an error for any external import which is not satisfied by the declared dependencies - preventing your users from errors due to missing imports.

This is typically useful if you are developing more than one Python package from a single virtual environment.
Although your local environment may contain the dependencies for all your packages, when an end-user installs each package they will only install the dependencies listed in the `pyproject.toml`.

This means that, although tests may pass in your shared environment, an invalid import can still cause errors at runtime for your users.

In case you would like to explicitly allow a certain external module, this can be configured in your [`tach.toml`](configuration#external-checks)

<Note>
  It is recommended to run Tach within a virtual environment containing all of
  your dependencies across all packages. This is because Tach uses the
  distribution metadata to map module names like 'git' to their distributions
  ('GitPython').
</Note>

## tach install

Tach can be installed into your development workflow automatically as a pre-commit hook.

### With pre-commit framework

If you use the [pre-commit framework](https://github.com/pre-commit/pre-commit), you can add the following to your `.pre-commit-hooks.yaml`:

```yaml
repos:
  - repo: https://github.com/gauge-sh/tach-pre-commit
    rev: v0.25.2 # change this to the latest tag!
    hooks:
      - id: tach
```

Note that you should specify the version you are using in the `rev` key.

### Standard install

If you don't already have pre-commit hooks set up, you can run:

```bash
tach install pre-commit
```

The command above will install `tach check` as a pre-commit hook, directly into `.git/hooks/pre-commit`.

If that file already exists, you will need to manually add `tach check` to your existing `.git/hooks/pre-commit` file.
