Add ty for Type Checking and Better Feedback
Linting and formatting make code cleaner, but they do not answer every question. Type checking helps you catch mismatched values, bad assumptions, and missing returns before the program reaches those paths at runtime. Astral's ty is built for fast Python type checking, and uv gives you two easy ways to start using it.
UV Series
Understand what ty checks and how to add it to a beginner uv project.
Use uvx ty check for a quick trial or uv add --dev ty for a project-pinned workflow.
You will know how ty fits beside Ruff rather than competing with it.
Try ty Without Changing the Project First
If you want to feel ty before committing to it, use a one-off run:
uvx ty check
That is the fastest way to test the idea. uv creates an isolated temporary environment for the tool run, and ty checks the current project or working directory.
This is a good beginner move when you want to experiment without editing dependencies immediately.
Add ty as a Development Dependency
Once you decide ty belongs in the project, install it the same way you installed Ruff:
uv add --dev ty
Then run it from the project environment:
uv run ty check
That gives the project a pinned ty version and makes the command available through the environment uv manages.
If you later want to update ty specifically, you can do that with:
uv lock --upgrade-package ty
Why Type Checking Helps Even in Small Scripts
Suppose you write code like this:
def greet(name: str) -> str:
return "Hello, " + name
def main() -> None:
print(greet(42))
if __name__ == "__main__":
main()
The bug is obvious when you read slowly, but type checkers help when code gets larger, imports grow, and assumptions hide in multiple files. ty can flag that you are passing the wrong kind of value to a function that expects a string.
That is why type checking is not “advanced for the sake of being advanced.” It is feedback about contracts in your code.
Why Running ty Through uv Is a Good Fit
Type checkers need to understand your environment. If your code imports packages, the checker needs to discover those installed dependencies.
That is one reason uv run ty check is a strong default in a uv project. The project environment is already the place where dependencies live, so the type checker runs with the right surrounding context.
In other words, this is not just a convenience pattern. It is also a correctness pattern.
Use Ruff for Code Quality and ty for Type Feedback
uv run ruff check .
uv run ruff format .
uv run ty check
uv run main.py
That is a healthy beginner loop. First clean the code and obvious issues, then check type expectations, then run the program.
Notice that type checking does not replace testing or execution. It adds one more early warning system before runtime.
When ty Starts Paying Off the Most
Type checking becomes more valuable as the codebase grows, but it becomes more pleasant when your editor can surface the same feedback while you type. ty also has editor integrations and a language server, which means the command-line checks you learn here can grow into a more interactive development setup later.
For now, the command-line workflow is enough. The main win is learning how to make the project carry its own tooling instead of relying on invisible local setup.
Frequently Asked Questions
These are the practical questions beginners usually ask at this stage of the uv workflow.
Does ty replace Ruff?
No. They overlap in spirit but not in purpose. Ruff focuses on linting and formatting, while ty focuses on type checking.
Should I start with uvx ty check or uv add --dev ty?
Use uvx if you want a quick trial. Use uv add --dev ty when you want ty to become part of the project workflow.
Why run ty through uv run?
Because the checker often needs access to the project's installed dependencies, and uv run executes in the project environment.
Do I need to type annotate everything immediately?
No. Start with function parameters and return values in code that matters. Type checking is most useful when introduced steadily, not all at once.
What if ty reports errors in beginner code?
That is normal. Treat the output as feedback, not as a judgment. The point is to reveal mismatches early while the code is still easy to fix.
Conclusion
At this point, your project has a full beginner-friendly workflow: uv manages the project, Ruff keeps the code tidy, and ty adds another layer of early feedback.
The final article steps back and answers the broader question many people still have after learning uv: when should you choose uv, when does Miniconda still make sense, and how do you decide between them?
Raell Dottin
Comments