Skip to content

Pack Format

Understanding the PromptPack specification and .pack.json structure.

PromptPack is an open specification for packaging AI prompts in a vendor-neutral, framework-agnostic format. PackC compiles source files into packs that conform to this standard.

Today’s AI prompt development is fragmented:

  • Each framework uses its own format
  • Switching providers means rebuilding prompts
  • No consistent way to version or test prompts
  • Prompts are treated as disposable, not engineered assets

PromptPack solves this with a universal JSON format that works across any runtime or provider.

From the PromptPack specification:

  1. Vendor Neutrality: Works with any AI framework or provider
  2. Completeness: Everything needed in a single file—prompts, tools, guardrails
  3. Discipline: Treat prompts as version-controlled, testable engineering artifacts

A PromptPack-compliant .pack.json file:

{
"$schema": "https://promptpack.org/schema/latest/promptpack.schema.json",
"id": "customer-support",
"name": "Customer Support Pack",
"version": "v1.0.0",
"template_engine": {
"version": "v1",
"syntax": "{{variable}}"
},
"prompts": {
"greeting": {
"id": "greeting",
"name": "Greeting",
"system_template": "You are a helpful support agent. Help the user with: {{query}}",
"version": "v1.0.0"
}
}
}
FieldDescription
idUnique pack identifier
nameHuman-readable pack name
versionPack version (semver)
promptsMap of prompt definitions

Each prompt in the prompts map (keyed by task type):

{
"id": "task-id",
"name": "Display Name",
"description": "What this prompt does",
"version": "v1.0.0",
"system_template": "System prompt text with {{variables}}",
"variables": [
{
"name": "variable_name",
"type": "string",
"required": true
}
],
"tools": ["tool1", "tool2"]
}

Packs can include a workflow section that defines an event-driven state machine over prompts. Each state references a prompt task type, and transitions are triggered by named events.

{
"workflow": {
"version": 1,
"entry": "intake",
"states": {
"intake": {
"prompt_task": "greeting",
"description": "Initial customer contact",
"on_event": {
"Escalate": "specialist",
"Resolve": "closed"
},
"orchestration": "internal"
},
"specialist": {
"prompt_task": "specialist",
"description": "Specialized support handling",
"on_event": {
"Resolve": "closed"
},
"persistence": "persistent",
"orchestration": "external"
},
"closed": {
"prompt_task": "farewell",
"description": "Conversation complete"
}
}
}
}
FieldDescription
versionWorkflow spec version (currently 1)
entryName of the initial state
statesMap of state definitions
FieldDescription
prompt_taskReferences a prompt in the prompts map
descriptionHuman-readable state description
on_eventMap of event name to target state
persistence"transient" or "persistent" (storage hint)
orchestration"internal", "external", or "hybrid" (control mode)

A state with no on_event entries is a terminal state — the workflow is complete when it reaches one.

  • internal (default) — The agent drives transitions automatically
  • external — External callers (HTTP, queues) drive transitions via the SDK
  • hybrid — Mixed control; both agent and external callers can trigger transitions

The key benefit of PromptPack is portability. A pack compiled with PackC works with:

  • PromptKit SDK (Go) — The reference implementation
  • Other PromptPack runtimes — Any language that reads the spec
  • Custom integrations — Parse the JSON directly
┌─────────────────────────────────────────────┐
│ .pack.json (PromptPack) │
│ Vendor-Neutral, Portable │
└─────────────────┬───────────────────────────┘
┌───────────────────────────┼───────────────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ PromptKit │ │ Python │ │ Your Custom │
│ (Go) │ │ Runtime │ │ Integration │
└─────────────┘ └─────────────┘ └─────────────┘

No vendor lock-in. Build once, deploy everywhere.

The PromptPack spec uses JSON because:

  1. Universal — Supported by all programming languages
  2. Human-readable — Easy to inspect and debug
  3. Fast — Native parsing in most runtimes
  4. Standard — Well-defined (RFC 8259)
  5. Tooling — jq, validators, formatters
FormatWhy Not
YAMLSlower parsing, more edge cases
Binary (Protobuf)Not human-readable, requires codegen
TOMLLimited nesting support

Reusable prompt components, defined once and referenced by multiple prompts:

{
"fragments": {
"company-info": "You work for Acme Corp, a leader in..."
},
"prompts": {
"support": {
"id": "support",
"system_template": "{{company-info}}\n\nYou are a support agent...",
"version": "v1.0.0"
}
}
}

Benefits:

  • DRY — Define once, use many times
  • Consistency — Same content across prompts
  • Maintainability — Update in one place

Packs use semantic versioning:

MAJOR.MINOR.PATCH
2.1.3
│ │ │
│ │ └─ Patch: Bug fixes, no API changes
│ └─── Minor: New features, backward compatible
└───── Major: Breaking changes

The PromptPack format itself is versioned via $schema and compilation.schema:

{
"$schema": "https://promptpack.org/schema/latest/promptpack.schema.json",
"compilation": {
"schema": "v1"
}
}

This allows the specification to evolve while maintaining compatibility.

PromptPackFramework-Specific
✅ Portable — works anywhere❌ Locked to one framework
✅ Standard format❌ Proprietary format
✅ Versioned❌ Often unversioned
✅ Compiled & validated❌ Runtime parsing
PromptPackRaw Files
✅ Compiled, optimized❌ Requires parsing at runtime
✅ Single file❌ Multiple files to manage
✅ Schema validated❌ May have errors
✅ Versioned❌ No version info
PromptPackLangchain
✅ Language agnostic❌ Python-specific
✅ Multi-prompt bundles❌ Single templates
✅ Self-contained❌ Code dependencies

Use the PromptPack spec for maximum portability:

{
"$schema": "https://promptpack.org/schema/latest/promptpack.schema.json",
"id": "my-pack",
"name": "My Pack",
"version": "v1.0.0"
}

One pack per application or feature:

✅ customer-support.pack.json
✅ sales-automation.pack.json
❌ all-prompts.pack.json
1.0.0 → 1.0.1 // Bug fix
1.0.1 → 1.1.0 // New prompt added
1.1.0 → 2.0.0 // Breaking change
Terminal window
packc validate pack.json