Recommended Presets
Four presets to start from, organised by project shape.
CLI tool / script
Small startup time matters; concurrency is rare.
[project]name = "mytool"version = "0.1.0"
[python]target = "3.13"free-threaded = false
[emit]class-default = "dataclass"format = true
[strictness]no-implicit-any = trueunused-import = "error"exhaustive-match = "error"auto-memoise = false # caches extend lifetimes — not worth it for CLIsauto-gather = falseauto-parallel = falsepgo-memoise = false
[env]required = [] # most CLIs don't have build-time required vars
[dependencies]click = ">=8" # or argparse from stdlibUse lazy import for heavyweight dependencies (pandas, torch). Use comptime let for tool metadata (version string baked at build).
HTTP API / web service
Concurrency dominates; data crosses trust boundaries.
[project]name = "myapi"version = "0.1.0"
[python]target = "3.13"free-threaded = false
[emit]class-default = "dataclass" # internal typesformat = true
[strictness]no-implicit-any = trueunused-import = "error"exhaustive-match = "error"unintrospectable-dependency = "error" # CI-gate: every dep must be checkableauto-memoise = falseauto-gather = false # use explicit `gather:` blocksauto-parallel = falsepgo-memoise = false
[checker]external = "ty" # type-check emitted Python against typeshed
[env]required = ["DATABASE_URL", "API_KEY"]
[dependencies]fastapi = ">=0.110"uvicorn = ">=0.27"pydantic = ">=2"sqlalchemy = ">=2"httpx = ">=0.27"
[dev-dependencies]pytest = ">=8"pytest-asyncio = ">=0.23"Use model for request / response bodies (Pydantic validation at the boundary). Use class for internal types. Use gather: for fan-out reads. Use go for fire-and-forget metrics / logging.
Data processing / numerical
Heavy compute on large collections; free-threaded mode helps.
[project]name = "mypipeline"version = "0.1.0"
[python]target = "3.14t" # the free-threaded buildfree-threaded = true # opt into threading parallelism
[emit]class-default = "dataclass"format = true
[strictness]no-implicit-any = trueunused-import = "error"exhaustive-match = "error"auto-memoise = falseauto-gather = falseauto-parallel = true # rewrite pure comprehensions to thread-pool mapparallel-min-size = 64pgo-memoise = true # cache hot pure helpers from profile datapgo-min-calls = 100
[dependencies]numpy = ">=2"polars = ">=1"Mark pure helpers with @pure. After the first profiling run, pgo-memoise will cache the hottest ones automatically. Use lazy import to defer numpy / polars startup for short-running modes.
Library
Strict; no PyPI runtime overhead.
[project]name = "mylib"version = "0.1.0"
[python]target = "3.13"free-threaded = false
[emit]class-default = "dataclass"format = true
[strictness]no-implicit-any = trueunused-import = "error"exhaustive-match = "error"unintrospectable-dependency = "error" # a published lib must check every depauto-memoise = falseauto-gather = falseauto-parallel = falsepgo-memoise = false
[checker]external = "ty" # catch stdlib / C-extension misuse before release
[dependencies]# Keep this minimal — library users inherit your deps.
[dev-dependencies]pytest = ">=8"pytest-cov = ">=4"Make sure to ship .dty stubs for the public API alongside the source, so consumers see the strict Typhon types when they pull your library through a .pyi. Run tyc check --stubs and tyc stubtest in CI.
Migration project
A project that’s progressively rewriting Python → Typhon.
[project]name = "myapp"
[python]target = "3.13"
[emit]class-default = "dataclass"format = true
[strictness]no-implicit-any = trueunused-import = "warn" # softer during the migrationexhaustive-match = "warn"auto-memoise = falseauto-gather = falseauto-parallel = falsepgo-memoise = false
[env]required = ["DATABASE_URL"]Once migration stabilises, raise unused-import and exhaustive-match back to "error".
Where next
- Every key in detail — section by section.
- Migrating from Python — the design patterns.
- CI Integration — wiring
tyc checkinto CI.