gauge-sh

tach: Enforce Python Module Dependencies

Tach checks Python imports against declared module dependencies and interfaces, helping teams prevent unwanted coupling and dependency cycles. It is actively maintained and suits projects adopting modular architecture incrementally.

Stars
2.8k
Forks
94
Stars, last 10 days
+9
Last commit
1 day ago
Contributors
29

Our take

Activeregular commits and releases

Health score

51/100

How it is scored
Activity
63
Community
59
Issues
42
Pull requests
38

+9 stars in the last 10 days

  • Slower to close issues than 89% of the projects we track

Tach is a focused architecture-enforcement tool with active releases and a broad contributor base, though teams should account for potentially slow issue resolution.

Good fit if

  • You want automated checks for Python module dependencies, interfaces, or cycles.
  • You want to introduce architecture rules incrementally and integrate checks into CI or pre-commit.
  • Your team can use Python 3.10 or newer and accommodate the Rust component; the project is MIT-licensed.

Look elsewhere if

  • You need a dependency enforcement tool for a language other than Python.
  • You cannot add a Rust requirement alongside Python.
  • Your adoption depends on quick issue resolution, since reported issues have taken a long time to close despite recent project activity.
All health signals
Last commit2026-10-06 (1 day ago)
Commits, last 90 days22
Releases, last 12 months15 (latest v0.35.3, 2026-10-06)
Contributors29 (top contributor: 56% of commits)
Issues closed, last 90 days10 (typically closed in 185 days)
Pull requests merged, last 90 days7 (typically merged in 2 days)
Project age2 years

Checked on 2026-10-08 with the GitHub API.

Overview

Tach is a command-line tool for defining and enforcing boundaries between modules in Python projects. It checks that imports follow declared dependencies, cross-module calls use public interfaces, and the dependency graph stays free of cycles.

This is useful when a Python codebase is growing and its intended architecture needs to be checked automatically rather than left to convention. Tach is implemented in Rust, installed via pip, and can be adopted for selected modules rather than requiring an entire project to be reorganized at once. See the repository and documentation for details.

Key Features

  • Checks imports against dependencies declared in tach.toml.
  • Enforces public interfaces for calls across module boundaries.
  • Detects cycles in the module dependency graph.
  • Supports incremental adoption, including unchecked modules and deprecated dependencies.
  • Offers layered architecture rules and domain ownership configuration.
  • Visualizes module dependencies and can produce a local GraphViz DOT file.
  • Reports dependencies and usages for a file or directory, and can generate JSON dependency maps.
  • Integrates with CI/CD and pre-commit hooks.

Use Cases

  • Python teams introducing modular boundaries can enforce dependencies for a few packages first, then expand coverage.
  • Maintainers of modular monoliths can prevent imports that bypass a module's public interface.
  • Teams reviewing architectural changes can inspect dependency graphs or report which modules use a given path.
  • Monorepo maintainers can configure source roots for multiple Python packages and check their module structure.

What you need

Detected in the repository

  • Python >=3.10 (from pyproject.toml)
  • Rust (from Cargo.toml)
  • Automated checks on GitHub Actions

License in plain words

MITpermissive

  • Commercial use: yes
  • Modify and redistribute: yes
  • You must keep: the copyright and license notice
  • Share your changes: no

A summary, not legal advice: the LICENSE file is what applies.

Getting Started

Install Tach with pip:

pip install tach

Run tach init to configure module boundaries, then tach check to validate them. See the README for setup and usage details.

Alternatives

  • fallow: Fallow checks broader repository health and architecture violations, while Tach focuses on Python import boundaries, declared dependencies, and interfaces.
ProjectLanguageLicenseStarsStatus
tachRustMIT2.8kActive
fallowRustMIT5kActive

Considerations

The project is active, with regular commits and releases, and contributions are not concentrated in one person. However, issue closure has been slower than pull request merging, so teams relying on project support should factor that into adoption planning. Tach requires Python 3.10 or newer and a Rust component. Its MIT license is permissive, but teams should still review the license terms for their distribution and use.

Found this useful?

Share it with someone who would like tach.

Comparisons