Co-op Translator treats translation as maintenance, not a one-off
Keep Markdown, Jupyter notebooks, and image text translated as your repository changes.
At a glance
- What is it?
- Co-op Translator is a Python tool that keeps translated repository documentation in step with its source, hashing files to find stale translations, chunking Markdown for the model, rewriting relative links into the translations tree, and reviewing the result before you merge.
- Who is it for?
- Co-op Translator fits a maintainer of a repository with translated documentation who has a recurring problem keeping the copies in step, and who can point the tool at Azure OpenAI, OpenAI or Anthropic, with Azure AI Vision added if text inside images has to be translated.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem behind the tool
The README opens with a framing that explains the rest of the design. Translation is not finished when a model returns text, and repository-scale documentation has to stay complete, navigable and synchronised after every source change.
That reframing is the whole project. A one-shot translation script is easy to write and produces a pile of files that drift out of date within a week. Co-op Translator is built for the case where the source keeps moving, and its stated purpose is to keep multilingual GitHub documentation current as the source evolves.
The tool is presented with two sentences of scope: it detects changed source content, updates stale translations, and preserves the links and structure of Markdown, Jupyter notebooks and images. The subject is a repository, and the audience is the person who maintains one with translations in it.
There is real usage behind it. The README points to Microsoft open-source learning repositories that combine lessons, code samples, links, notebooks and supporting assets, and lists AI Agents for Beginners, Generative AI for Beginners and MCP for Beginners with their translations directories. A demo shows the same README section in English and Korean from the AI Agents for Beginners repository, and the repository itself carries a translations directory, which is the tool translating its own documentation.
The rest of the article is about how the mechanics work and where they get in the way of a human translator.
Source hashes decide what is stale
The mechanism for not retranslating everything is hashing. The README's problem table states that source hashes and language-scoped metadata identify stale files and skip unchanged translations, and the CLI section confirms the behaviour in one line: the CLI updates changed files and skips unchanged translations.
The important word in that description is language-scoped. A repository translated into several languages holds several outputs per source file, and each of them has its own state. A file translated into Korean and Japanese is not one artefact with two halves, it is two artefacts, and a Korean file that has been reviewed and accepted should not be invalidated because the Japanese one is out of date. Scoping the metadata by language is what makes per-language review and per-language rollback possible.
The consequence for a user is that the tool is incremental by default, and the cost of a run is proportional to what changed rather than to the size of the repository. That is the difference between a tool you can run on every pull request and one you run once before a release.
The state also has to survive the tool's own upgrades and moves between machines, since a hash based on file content alone would consider every file stale after a change of the translation engine. The README does not describe the on-disk format of that metadata, and the documentation links point to the configuration page for the details, so this is one of the places where the project asks you to read further rather than infer.
Chunking, structure protection and link rewriting
Two distinct problems get solved by two distinct mechanisms, and the README is careful to keep them apart.
The first is that a long document does not fit in one reliable model response. Markdown is split into manageable chunks, and the tool retries and re-chunks a section that fails. That is a straightforward engineering answer to a model failure mode, and it explains the presence of the retry logic and of the concurrency setting described later.
The second is that a model, left alone with Markdown, alters structure and destinations. The answer here is structural rather than textual: structure checks and parser-based protection preserve Markdown URLs, code and Markdown structure. The parser approach matters, because a regex that protects code blocks and URLs will eventually meet a code block inside a list item inside a table cell and get it wrong. Parsing the document and protecting the regions the parser identifies is the more reliable approach, and it is the difference between a translation that renders and one that does not.
The third mechanism is about where the output goes. Links must follow the translated repository tree, so relative links in Markdown, notebooks, images and README files are rewritten for the translations/<lang>/... layout. This is the part that most translation scripts skip and that most translators discover by hand: a translated README that points at ./docs/setup.md has to point at the translated copy, and the number of such references in a documentation set is large enough to make hand-editing impractical.
The net effect is that the tool handles a repository containing more than prose. One workflow covers Markdown, Jupyter notebooks, image text and a repository-level review, which is what the problem table calls out as the fifth row.
Image text needs Azure, and that is not optional
Text translation and image translation have different requirements, and the README separates them explicitly.
Markdown and notebooks are translated with Azure OpenAI, OpenAI or Anthropic, and Azure is described as optional for text translation. Translating text inside images additionally requires Azure AI Vision. That is a hard dependency in the practical sense: if your repository contains screenshots with a UI in another language, or a diagram with English labels, and you want those labels translated, you need an Azure AI Vision endpoint whether or not you would rather use a different provider for the prose.
The project topics list includes azure-ai-vision and image-translation, and the dependency set includes the Azure AI Vision image analysis package alongside the agent framework integrations for Anthropic and OpenAI. Image handling also brings its own dependencies, and the container image installs the runtime system libraries that imaging libraries need, including libgl1 and libglib2.0-0, with the comment naming opencv and pillow as the reason.
Notebooks are the other format that needs specific handling, and they are called out in both the opening description and the problem table, alongside Markdown and images. A notebook is JSON with code cells, outputs and Markdown cells, so translating one is not the same operation as translating a Markdown file, and the tool treats them as a supported type rather than a special case you handle by hand.
The image path is the one part of the scope where the provider choice is not really yours, and that is worth weighing before you commit to a workflow.
The CLI surface and what the entry points do
The package installs several console scripts, and the naming tells you what each one is for:
[tool.poetry.scripts]
translate = "co_op_translator.__main__:main"
evaluate = "co_op_translator.__main__:main"
migrate-links = "co_op_translator.__main__:main"
co-op-review = "co_op_translator.__main__:main"
co-op-translator-mcp = "co_op_translator.mcp.server:main"The translate command does the work, co-op-review is the deterministic review step, evaluate and migrate-links are separate entry points for measurement and for link migration, and the last one exposes the tool as an MCP server, which is what makes it usable by an agent rather than only by a person at a terminal.
The flags carry the behaviour. The language selector takes one code or several, and Markdown is selected with -md. The path rules are handled by -r for the source root, and --translations-dir overrides where the translated tree is written, which the README calls out for documentation sites with a custom translation folder. The concurrency flag processes several files or languages at once:
# For larger text batches, use `translate -l "ko ja" -md --concurrency 4` to process up to four file/language translations at once. The default is one.Concurrency is worth understanding before you raise it, because the tool is calling a rate-limited model API and because the README's own advice for the workflow comparison page is to start from the local translation route and move up.
The repository also carries an action.yml at the top level, which is the GitHub Actions entry point, and a .agents directory and a docs/agents.md file, which the README describes as a skill to install when an AI agent is doing the translating. The point of that skill, as the README puts it, is a repeatable workflow for multiple languages, linked documents and recurring updates.
Where human edits get lost
This is the limitation that a careful reader should weigh, and the README states it plainly rather than burying it.
When you edit a translation by hand, the default CLI and Actions workflows retranslate the whole affected file when the source changes, and that can overwrite your wording. The instruction that follows is to review each update before merging. In other words, the default behaviour of the tool is to treat a translation as derived from the source, and human edits inside that derived file are not protected.
Preserving accepted human edits at Markdown block level requires an optional Python API translation state provider, documented in the API reference. That is a real design decision rather than an oversight. A translation state that records which blocks a human approved, and reuses those blocks on the next run, is a different product from a retranslator, and it is a fair amount of machinery: it needs to know which translated text corresponds to which source block, and it needs to decide what happens when the source block itself changes.
The cost of the default is therefore process rather than code. If your team has translators who review and approve wording, that approval has to live somewhere the tool will not overwrite, or every source edit sends the file back to the model and undoes the review. The optional provider is the way to do that, and it is the first thing to look at if hand-edited translations matter to you.
The review step exists for the same reason. co-op-review is described as a deterministic review, which suggests it checks structural properties rather than judging prose quality, and it is the mechanism to run on the output before a human looks at it.
Where it runs, and what it costs to keep up
The deployment options are the last decision, and the README is unusually helpful here. The workflow page compares local translation, Python automation, GitHub Actions, containers and agent or editor integration, and it is the starting point the README points a first-time user to.
The package is on PyPI as co-op-translator and is built with Poetry, with the source under a src layout and the package included from there. The Python requirement is a range rather than a floor, from 3.11 up to but not including 3.15, and the pinned requirements file marks every dependency with that same range, so the environment is expressed consistently. The container image is published to GitHub Container Registry and is built as a multi-stage Dockerfile: a builder stage on python:3.13-slim that installs Poetry at pinned versions, exports the dependencies with the Poetry export plugin, builds a local wheelhouse with pip wheel, and builds the wheel, and then a runtime stage that installs only the built wheel and its wheels from that local directory, so the final image never reaches the network to resolve dependencies.
The licence is MIT, with the project description, keywords and documentation URL all declared in the packaging metadata. The repository carries the usual governance files, including a SECURITY.md, a CODE_OF_CONDUCT.md and a SUPPORT.md, plus an AGENTS.md.
The release cadence is fast and worth planning around. The recent versions are v0.23.0 on 2026-10-13, v0.22.0 on 2026-10-02 and v0.21.0 on 2026-09-19, and the last push was on 2026-10-22. Two minor versions in three weeks, with the packaging metadata carrying the version, means a workflow that pins the package version will want a deliberate upgrade schedule rather than a floating dependency.
Editorial conclusion
Co-op Translator fits a maintainer of a repository with translated documentation who has a recurring problem keeping the copies in step, and who can point the tool at Azure OpenAI, OpenAI or Anthropic, with Azure AI Vision added if text inside images has to be translated. It is the wrong choice for a repository where translation is a manual, human-led activity, since the default behaviour retranslates the whole affected file and can overwrite wording that a reviewer accepted, and the state provider that preserves block level edits is an optional API. Before running it on real documentation, do the dry run the README demonstrates, read the diff it prints, and check the AI agent skill in docs/agents.md if you intend to let an agent drive the workflow.
Frequently asked questions
How do I install Co-op Translator and preview a translation without credentials?
Install the package with pip install co-op-translator, then run the dry run, which is translate -l "ko" -md --dry-run. The README also links a small translation example that previews two Markdown files, lets you edit the source and then inspect the translation diff and the review results.
Which AI providers does co-op-translator support?
Markdown and notebooks are translated with Azure OpenAI, OpenAI or Anthropic, and Azure is optional for text translation. Translating text inside images additionally requires Azure AI Vision.
Does co-op-translator overwrite my hand-edited translations?
By default it does. The README states that the default CLI and Actions workflows retranslate the whole affected file when the source changes and can overwrite your wording, so each update should be reviewed before merging. Preserving accepted human edits at Markdown block level needs the optional Python API translation state provider.
How does the tool know which translations are out of date?
Source hashes and language-scoped metadata identify stale files, so unchanged translations are skipped. The CLI updates changed files and leaves the rest alone, and the metadata is scoped per language.
Can co-op-translator write to a custom translation folder?
Yes. The README shows the pattern translate -r docs --translations-dir i18n -l "ko" -md, which writes to docs/i18n/ko/, with the path rules described in the CLI reference.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/azure-co-op-translator)Was this useful?