Tinker AI
Read reviews
intermediate 4 min read

Aider on multi-language projects: TypeScript frontend, Python backend, shared types

Published 2026-01-29 by Owner

Most non-trivial projects mix languages. The frontend is TypeScript or JavaScript; the backend is Python, Go, Ruby, or Rust; there’s some shell for scripts; maybe SQL migrations. Aider handles polyglot codebases reasonably well, but a few patterns make it work much better.

The basics work

By default, aider reads all the files you /add regardless of language. The model handles language transitions naturally — it can edit a Python file, then a TypeScript file, in the same session.

The repo map is similarly language-agnostic. Aider’s tree-sitter-based summarization works for all major languages.

For most polyglot projects, this default works without configuration. You don’t need separate aider sessions for separate languages.

Where polyglot gets tricky

A few specific challenges:

Shared types. A TypeScript type that mirrors a Python Pydantic model needs to stay in sync. Aider doesn’t automatically know they should match.

Naming conventions. Python uses snake_case; TypeScript uses camelCase. The same field crosses the boundary with different names. Aider sometimes forgets which side it’s on.

Build pipeline awareness. A Python change might require a typegen step to update TypeScript types. Aider doesn’t run that pipeline automatically.

Cross-language imports. When a TypeScript file references types generated from Python (via OpenAPI, gRPC, etc.), aider may not realize the Python file is the source of truth.

A pattern that works

For polyglot projects, my workflow:

Pin schema files in chat. Files that define the cross-language contract (Pydantic models, GraphQL schema, OpenAPI YAML, .proto files) get added to chat context at session start.

Be explicit about which side is canonical. When asking aider to add a field, specify whether it’s adding to the schema (with downstream propagation) or to one side (without propagation). This avoids confusion.

Use code generation aggressively. If your project generates TypeScript types from Python, generates Python types from .proto, etc., let the codegen handle the cross-language consistency. Aider edits the canonical source; codegen handles the rest.

Run codegen explicitly when needed. Aider can run shell commands; explicitly run the codegen step:

> /run python -m generate_types

After this, the generated types are updated. Aider sees the new types in subsequent context.

A specific example

A real workflow on a TypeScript + Python project:

I want to add an is_premium: bool field to the user model. The field needs to flow through:

  • The Pydantic model in backend/models/user.py (source of truth)
  • The generated TypeScript type in frontend/types/api.ts (auto-generated)
  • The user form in frontend/components/UserProfile.tsx
  • The Python service in backend/services/users.py
  • The migration in backend/migrations/

The session:

> /add backend/models/user.py
> add an is_premium boolean field, default False, to the User model

[aider edits the model]

> /run python -m generate_types

[the codegen runs; backend/api/openapi.json updates; frontend/types/api.ts regenerates]

> /add frontend/components/UserProfile.tsx
> add a "Premium member" badge that shows when user.is_premium is true

[aider edits the component]

> /add backend/services/users.py
> the upgrade_to_premium method should set is_premium to true and
> emit a UserUpgraded event

[aider edits the service]

> create a migration for the is_premium column

[aider creates the migration file]

Total time: maybe 12 minutes. The key is doing the codegen step in the middle so subsequent edits see the updated types.

What aider can and can’t track

Tracks reasonably well:

  • Changes within one language at a time
  • Naming convention differences (snake vs camel) when explicitly told
  • Cross-file references within one language

Doesn’t track:

  • That a Python change requires regenerating TypeScript types
  • That a schema change has downstream implications without being told
  • Build pipeline ordering

You handle the tracking; aider does the editing within each step.

Per-language conventions

A polyglot project usually has different conventions per language. A .aider.conf.yml might encode this:

read:
  - CONVENTIONS.md
  - frontend/CONVENTIONS.md
  - backend/CONVENTIONS.md

CONVENTIONS.md describes shared patterns. frontend/CONVENTIONS.md describes TypeScript-specific patterns. backend/CONVENTIONS.md describes Python-specific patterns.

Aider reads all three. When you’re working on frontend code, the frontend conventions apply. When on backend, backend conventions apply. The shared conventions apply throughout.

The python+typescript mistake to avoid

The most common cross-language mistake I see aider make: mixing snake_case and camelCase.

Example: aider adds a field on the Python side as is_premium. When asked to use it on the TypeScript side, aider sometimes references it as is_premium (using Python’s name) instead of isPremium (the camelCased TypeScript form).

The mitigation: explicit rules in frontend/CONVENTIONS.md:

TypeScript field names are always camelCase, even when they correspond
to Python snake_case fields. The conversion happens automatically in
the generated types. Reference fields by their TypeScript names in
TypeScript code.

After this rule, aider stops conflating the two. Subtle but important.

When aider’s polyglot handling falls down

A few cases where polyglot work outpaces aider:

Tight Python-Rust FFI. When Python calls Rust through PyO3 or similar, the type mapping is non-trivial. Aider’s understanding is partial.

Complex codegen with custom templates. If your codegen is hand-written Jinja or similar, aider may not know the templates well. Hand-coding is faster.

Cross-language refactors. Renaming a concept across all languages simultaneously is hard. Aider handles each language but the cross-language coordination requires you to explicitly walk through each.

Build system understanding. Bazel, Pants, Buck — these polyglot build systems have specific patterns aider doesn’t always understand. Generated code in a Bazel repo can confuse aider’s repo map.

For these, the workflow is “one language at a time, with you holding the cross-language context.” Aider helps within each language but isn’t the conductor.

Worth investing in patterns

The setup time for a polyglot aider workflow is a few hours, mostly writing the conventions docs and ensuring the codegen pipeline is reliable.

The payoff is significant. A polyglot project where each language has clear conventions and the codegen flows correctly works much better with AI assistance than a polyglot project where everything is implicit.

For greenfield polyglot work, this is part of the up-front investment. For existing projects, it’s worth retrofitting the patterns over a few weeks.

A note on Go in the mix

Go fits polyglot patterns well because of its Codegen culture. tools like protoc-gen-go, go generate, etc. produce reliable artifacts. Aider works well in Go portions of polyglot projects.

If you’re starting a polyglot project and have a choice, Go for the backend is one of the better fits for AI-assisted polyglot work. The codegen patterns flow naturally; the language is well-trained.