Model or dataset
microsoft/prompty avatar
microsoft/prompty

Prompty: a .prompty file format for prompts that outlive the code that calls them

Prompty makes it easy to create, manage, debug, and evaluate LLM prompts for your AI applications. Prompty is an asset class and format for LLM prompts designed to enhance observability, understandability, and portability for developers.

1,264 stars127 forksRustMIT

At a glance

What is it?
Microsoft's Prompty v2 stores an LLM prompt as YAML frontmatter plus a markdown body, with runtimes in Python and TypeScript and a VS Code extension that executes the file directly. The format is the product; the runtimes are how you consume it.
Who is it for?
Adopt Prompty if your prompts are already drifting between a Python service and a TypeScript front end, or if you want a prompt file a non-engineer can open and edit without touching application code. Do not adopt it if you need a frozen format today: the README states the API, file format and tooling are in alpha and may change, and the released TypeScript packages are at 2.0.0-alpha.1.
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 last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem is prompt drift between runtimes, not prompt authoring

Most teams do not have a prompt problem. They have a duplication problem. The same system message exists as a Python f-string in one service and a template literal in a TypeScript worker, and the two have already diverged. Prompty's answer is to make the prompt a file with a defined shape, so the Python runtime and the TypeScript runtime read the same artifact. The README frames it as an asset class and format for LLM prompts, aimed at observability, understandability and portability. That is a narrower claim than prompt management platforms make, and a more honest one. The intended user is a developer who already writes prompts in code and wants them out of code, not a product manager shopping for a prompt CMS. The portability claim is backed by a concrete mechanism: the model block lives in frontmatter, so the same body can be pointed at a different endpoint or provider without editing the prompt text.

What a .prompty file actually contains

The file has two halves. YAML frontmatter carries name, model (id, provider, connection, options such as temperature), inputs, tools and template settings. The markdown body carries the prompt itself, with lines starting with system:, user: or assistant: acting as message boundaries. The README's example declares a tool with kind: function and a parameters list, so tool calling is part of the format rather than something the caller bolts on. Template syntax is Jinja2 or Mustache, selected under template.format.kind, and the parser is named separately under template.parser.kind, which suggests the two are meant to be swappable independently. Variable references have their own mini-language: ${env:VAR}, ${env:VAR:default} for a fallback, and ${file:path.json} to pull file content. The file reference is scoped to the directory containing the .prompty file by default, and the README states that host applications can opt into additional allowed roots through runtime load options, while prompts cannot grant themselves broader filesystem access. That is a deliberate sandbox boundary, and it is the most interesting security decision in the format.

The pipeline: load, render, parse, execute, process

Both runtimes expose the same five-stage pipeline, and both let you collapse it into one call or drive it stage by stage. In Python, prompty.invoke runs the whole thing; prompty.load returns an agent object, prompty.prepare turns that plus an inputs dict into messages, and prompty.run sends those messages. There is also prompty.invoke_async. In TypeScript the shape is identical: load, prepare, run, invoke, imported from @prompty/core, with a provider package imported for its side effect. The README's TypeScript example is explicit about this, importing @prompty/openai after the core functions, with the comment that it registers the provider. That registration-by-import pattern is the main structural difference from the Python side, where the provider is chosen through extras at install time. The five stage names also appear in the VS Code trace viewer, which shows render, parse, execute and process with timing and payloads. Every execution writes a .tracy trace file. That is the observability story in one sentence: the artifact you edit and the artifact you inspect are the same file.

Getting it running: pip extras, npm packages, F5

Python installs through extras. The README lists pip install "prompty[all]" for everything, and targeted variants such as prompty[jinja2,openai], prompty[jinja2,foundry] and prompty[jinja2,anthropic]. Note that jinja2 appears in every example, so Mustache support is presumably not part of those extra names. TypeScript installs as a core package plus one provider package: @prompty/core with @prompty/openai, @prompty/foundry or @prompty/anthropic. The VS Code route needs no install command at all: open the .prompty file and press F5. The extension also adds a connections sidebar for adding OpenAI, Microsoft Foundry or Anthropic endpoints and setting a default, a live preview that renders markdown and interpolates templates as you type, a chat panel that opens automatically for thread-enabled prompts, and the trace viewer. Scaffolding is a right-click in the explorer under New Prompty. For OpenAI-compatible gateways, the README shows setting model.connection.endpoint to ${env:OPENAI_BASE_URL:https://api.openai.com/v1}, then exporting OPENAI_BASE_URL and OPENAI_API_KEY. The prompt file stays unchanged while the endpoint supplies routing, policy, usage tracking or trace correlation.

Where the alpha bites, and where Prompty is the wrong tool

The README's own warning is the first limitation: this is the v2 branch, in alpha, and the API, file format and tooling are under active development and may change. The release list matches that. The Python package has a 2.0.0 release, but the TypeScript provider packages are at 2.0.0-alpha.1, so a team standardising on the JavaScript side is building on alpha artifacts. Beyond versioning, the format itself has costs. A .prompty file is not valid Python or valid TypeScript, so no linter, type checker or IDE refactoring tool understands it out of the box; you get whatever the Prompty extension and runtimes provide. The ${file:...} mechanism is deliberately constrained to the prompt's directory plus host-approved roots, which means a prompt that wants to pull a shared fragment from a sibling folder will fail unless the host opts in, and that opt-in is a runtime concern rather than something the prompt can express. Prompty is also the wrong tool if your prompts are one line in one language. The format only pays for itself when the same prompt is consumed in more than one place, or when you need the trace. If you want a hosted prompt registry with versioning and A/B rollout semantics, this is a file format, not that.

Compared with keeping prompts in application code

The realistic alternative is not another prompt framework. It is the status quo: prompt strings embedded in Python modules or TypeScript constants, with f-strings or template literals doing the interpolation. That approach has real advantages. Your editor, debugger, type checker and test runner all work on it today, and there is no alpha dependency in your tree. The difference in approach is where the boundary sits. In code, the prompt is a value produced by a function, and the model configuration is scattered wherever the client is constructed. In Prompty, the prompt and its model configuration are one declarative document, and the runtime is a thin consumer of that document. The practical consequence is that changing the model id, the temperature, or the endpoint becomes a frontmatter edit rather than a code change, and the same edit is visible to the VS Code preview. The cost is that you now maintain a second language surface, and the ${env:...} and ${file:...} syntax is one more thing to learn that no general-purpose tool will help you with. Teams that never share prompts across languages should weigh that trade honestly.

Maintenance cost and what the MIT licence leaves you to decide

Prompty is MIT licensed, which is permissive and carries no copyleft obligation, but this is not legal advice and the licence text governs. The maintenance cost is more interesting than the licence. You are depending on a format that is explicitly in flux, so budget for re-reading the frontmatter schema at each upgrade rather than assuming compatibility. The repository also expects contributor hygiene that affects anyone cloning it: a .gitattributes normalises text files to LF, and the README asks you to run git config core.hooksPath .githooks once per clone so staged files are normalised before each commit. The same checks can be run manually with git diff --check and git ls-files --eol | grep 'w/crlf'. If you vendor the repository or contribute patches, that hook setup is part of the workflow. If you only consume the pip and npm packages, it is not. One more cost worth naming: .tracy trace files are generated on every execution, so a long-running service will accumulate them unless you decide where they go. The README does not describe a retention policy, and that is a gap you will have to close yourself.

Editorial conclusion

Adopt Prompty if your prompts are already drifting between a Python service and a TypeScript front end, or if you want a prompt file a non-engineer can open and edit without touching application code. Do not adopt it if you need a frozen format today: the README states the API, file format and tooling are in alpha and may change, and the released TypeScript packages are at 2.0.0-alpha.1. Before committing, verify three things yourself: that your provider has a Prompty package (openai, foundry and anthropic are the ones named), that your Jinja2 or Mustache constructs survive the prompty parser, and that the .tracy trace files land somewhere your CI can read.

Official sources

  1. License: MIT
  2. microsoft/prompty on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes