# Port code to another language

Have Claude Code port a module to another language while keeping the API and behavior you name, with the tests ported and run against the new code.

Paste into: **Claude Code**, started in your project folder

## Prompt template

How the builder on the page fills in this template, so you can do the same:

- `{{key}}` becomes the text entered for that field, exactly as typed. Empty text, or text that is only whitespace (spaces, tabs or line breaks), counts as empty: a required field then becomes `[fill in: <label>]` with its label, and an optional field becomes nothing.
- For a choice field, `{{key}}` becomes the text of the chosen option, or of the default when none is chosen.
- Text between `{{#key}}` and `{{/key}}` stays only when that field is not empty; a choice field always counts as filled. The markers themselves are removed, and a marker that stands alone on its line takes its line break with it.
- Each value is inserted once, as it is: `{{…}}` inside a value stays as typed.

```text
Port {{source}} to {{target}}, keeping the same {{keep}}.
{{#conventions}}

Constraints for the new code:
{{conventions}}
{{/conventions}}

1. Read the source and its tests first. Write down what the port must preserve: public functions and types, inputs and outputs, error cases, side effects, and behavior the tests rely on. Show me this list before you write the port.
2. List anything without a direct equivalent in {{target}}, such as dynamic typing, exceptions, null values, integer overflow or third-party libraries, and say how you will handle each one. Ask me where the choice changes behavior.
3. Write idiomatic {{target}}, not a line-by-line transliteration. Follow the project's existing {{target}} code if there is any. Prefer the standard library and dependencies the project already has, and ask before adding new ones.
4. Port the tests as well, so the same cases run against the new code. Run them{{#check}} with: {{check}}{{/check}} and keep going until they pass. Do not drop or weaken a test case to make it pass.
5. Leave the original code in place. Do not delete it or switch callers over to the port.

If part of the source is unclear or looks like a bug, ask before deciding whether to carry it over.

Finish with the files you created, a table mapping each original public item to its port, any behavior that differs and why, and anything you could not port.
```

## Fields

- `{{source}}` (required): Code to port. A file, module or package. In Claude Code you can type @ to reference it.
- `{{target}}` (required): Target language.
- `{{keep}}` (required): What must stay the same.
- `{{conventions}}`: Constraints for the new code. Optional. Where the code goes, libraries to use or avoid, error handling style.
- `{{check}}`: Command that runs the ported tests. Optional. Leave empty and Claude will find how the project runs tests in that language.

This site doesn't run Claude or show model output. Results depend on your input and the model you use.

## When to use this template

- A module needs to move to another language, for speed, for a shared runtime, or because the rest of the system has moved, and its behavior must not change on the way.
- The original code has tests, so there is something concrete to port alongside it and run against the new version.
- You know the target language less well than the source and want an idiomatic result, with the places where the languages differ called out for you.

## When not to use it

- You want to move a whole codebase at once. Port it module by module, using this template for each piece, and plan the order first.
- The original code has no tests and its behavior is not written down anywhere. Add tests first with the write and run tests template, or the port has nothing to be checked against.
- The goal is to redesign the module as well. Changing the language and the design in one step makes it hard to tell which change caused a difference; port first, then refactor.

## Why this structure

- The opening line names what must stay the same, not only the target language. That turns "port it" into something Claude can check the result against.
- Step 1 asks for the list of what must be preserved before any code is written. You can add a forgotten case or correct a misreading while it is still cheap.
- Step 2 brings the hard parts forward. Differences in typing, errors and number handling are where ports change behavior quietly, so Claude has to name them and ask where it matters.
- Porting the tests and running them in step 4, with your command when you give one, gives Claude a pass or fail check and a reason to keep going until the new code behaves like the old.
- Step 5 keeps the change additive. The original stays in place and callers are untouched, so you can compare both versions and switch over when you are ready.
- The closing table maps each public item to its port, which makes gaps easy to see in review.

## Example input (fictional)

Code to port:

```
the Python module billing/invoice.py
```

Target language:

```
Rust
```

What must stay the same:

```
public API and test behavior
```

Constraints for the new code:

```
Put it in the existing crate under rust/billing. Return errors as Result values and never panic on bad input. Use rust_decimal for money.
```

Command that runs the ported tests:

```
cargo test -p billing
```

## Follow-ups to send Claude

- Run the original tests and the ported tests on the same inputs and list any case where the results differ.
- Which parts of the port are least idiomatic for this language? Rewrite them and keep the tests passing.
- Plan how to switch callers from the old module to the port in small steps, without changing anything yet.

## Common mistakes

- Naming only the target language. Without a statement of what must stay the same, Claude has to decide on its own which behavior matters.
- Porting the code but not the tests. The tests are the main way to show the new version behaves like the old one.
- Accepting a port that copies the source line by line. It may pass the tests but is harder to maintain in the new language; ask for idiomatic code.

## Related templates

- [Migrate a pattern across a codebase](https://awesomeclaudeprompts.com/prompts/migrate-code-pattern/): Move every use of an old API, library or pattern to its replacement: Claude Code lists each place first, then changes them in checked batches.
- [Write tests, run them, fix failures](https://awesomeclaudeprompts.com/prompts/write-and-run-tests/): Ask Claude Code to write tests for a file, run them and work through the failures in one go, without weakening a test just to make it pass.
- [Plan a code change before editing](https://awesomeclaudeprompts.com/prompts/plan-code-change/): Have Claude Code read the relevant code and propose a file-by-file plan for a multi-file change, without editing anything until you approve it.

## Sources

- [Claude Code docs: Prompt library](https://code.claude.com/docs/en/prompt-library) (Anthropic documentation)
- [How Anthropic teams use Claude Code](https://claude.com/blog/how-anthropic-teams-use-claude-code) (Anthropic documentation)
- [Claude Code docs: Common workflows, refactor code](https://code.claude.com/docs/en/common-workflows#refactor-code) (Anthropic documentation)
- [Claude Code best practices: Give Claude a way to verify its work](https://code.claude.com/docs/en/best-practices#give-claude-a-way-to-verify-its-work) (Anthropic documentation)

---

Awesome Claude Prompts is an independent project. It is not affiliated with, endorsed by, or sponsored by Anthropic. Claude is a trademark of Anthropic, PBC.
