CompanionRank
Home / Blog / Character Card Import & Portability
Guide

Character Card Import and Portability: What Actually Transfers

A character card looks like an image file, and that is the whole trick — the persona is stored as JSON hidden inside a PNG. That design is why cards move between apps at all, and also why parts of a character quietly disappear on the way.

Last verified: August 2026Author: CompanionRank Editorial TeamReading time: ~7 min
Character Card Import and Portability
TL;DR: A character card is a PNG with the persona JSON embedded in a text chunk. There are three spec generations — V1 (six fields), V2 (adds system prompt, lorebook, alternate greetings, extensions) and V3 (adds assets, decorators, multilingual notes, stored under a different chunk key) — plus CHARX, a ZIP container for cards that ship images and audio. The core description and greeting travel almost everywhere. Lorebooks, greeting variants, emotion art and app-specific extras travel only if the receiving app implements that generation. Chat history never travels, because it was never in the card.

Moving a character between apps is a different problem from moving your data out of an app. Your conversations, memories and settings live in the service's database; the character is a self-contained artefact you can usually hold in your hand as a file. That difference is what makes cards worth understanding — a card you own is the part of your setup that survives an app shutting down, changing its pricing, or turning into something you no longer want to use.

What a character card is as a file

Under the community specifications, a card is an ordinary PNG (or APNG) image with the character definition written into a tEXt chunk — a labelled block of text that image viewers ignore and card-aware apps read. The JSON is stored base64-encoded as UTF-8. Version 1 and version 2 cards use a chunk named chara; version 3 cards use a separate chunk named ccv3. Some apps also let you export the same object as a plain .json file, which carries identical data without the avatar image.

The V3 spec adds a second container, CHARX (file extension .charx): a ZIP archive with card.json at the root and an assets/ directory beside it, referenced from the card by embeded:// URIs. CHARX exists because a modern card may ship a set of expression images, background art or audio, and none of that fits into a text chunk at a sensible size.

The practical consequence of the two-chunk design is that a card can be simultaneously complete and empty depending on who reads it. An app that only knows the chara chunk sees nothing in a V3-only file. In practice, tools that write V3 commonly write both chunks so a single file opens in old and new clients — but that is a courtesy of the exporting app, not something the format guarantees.

The three generations, field by field

Knowing which generation your card is tells you what can possibly survive an import, before you test anything.

FormatWhere it livesWhat it carriesMain limit
V1chara chunkSix flat fields: name, description, personality, scenario, first message, example messagesNo lorebook, no system prompt, no greeting variants
V2chara chunk, fields nested under dataAll V1 fields plus creator notes, system prompt, post-history instructions, alternate greetings, an embedded character book, tags, creator, character version and a free-form extensions objectNo asset list; extensions are app-specific by design
V3ccv3 chunkEverything in V2 plus an assets list, nickname, multilingual creator notes, a source list, group-only greetings, and lorebook decorators such as insertion depth and activation rulesInvisible to readers that only look at chara
CHARXZIP with card.json + assets/A V3 card plus the actual image and audio files it referencesOnly useful where the receiving app unpacks it

Two details in the specs matter more than they look. First, V2 requires that editors must not destroy unknown key-value pairs — the extensions object is meant to be preserved even by apps that do not understand it, with keys namespaced per app to avoid collisions. Second, V3 is a strict superset of V2, so a downgrade path exists: an app can backfill a V2 object from a V3 card, but the decorators have to be stripped in the process. That stripping is exactly where behaviour changes without any visible field going missing. What each of these fields is for is covered in Character Card Anatomy.

What survives, what degrades, what never travels

Sorting the contents of a card into three buckets makes the risk concrete.

BucketContentsWhy
Travels reliablyName, description, personality, scenario, first message, example dialogueThese are the V1 fields; essentially every card-aware app reads them
Travels if the reader is new enoughSystem prompt, post-history instructions, alternate greetings, embedded lorebook, tags, creator metadataV2 additions — a V1-only importer simply ignores them
Degrades quietlyLorebook decorators, assets and expression art, group-only greetings, namespaced extensionsDropped or flattened when a V3 card is read as V2, or when a CHARX is imported by a PNG-only client
Never travelsChat history, app-derived memories, model choice, sampler settings, subscription stateNone of it is part of the card; it lives in the service

The last row is the one that surprises people mid-migration. Exporting a character is not backing up a relationship — the transcript and any long-term memory the app built for you are separate, usually harder to obtain, and often not portable in any usable form. That side of the problem is covered in Companion App Data Export, and the reasons memory behaves the way it does are in Memory & Continuity.

Two things change without anyone touching them. V3 cards carry creation_date and modification_date as Unix timestamps, and the spec tells applications to write the modification date on export — so a card you merely moved will look edited afterwards, and the original creation date is the only reliable provenance left. If you keep an archive of your own cards, note the date before you export, not after.

A refused import is also not always a damaged card. The spec allows an application to reject a CHARX file outright because it is too large, corrupted, encrypted without a supported decryption path, or simply not a valid zip. If one app refuses a file another opened happily, test it as a zip first before assuming the character is lost.

Why a perfectly imported card still behaves differently

Assume the transfer was lossless and every field arrived intact. The character can still feel like a different person, because the card is only one input among several. The receiving app supplies its own base system prompt, runs a different model, applies its own sampler settings, and allocates a different share of the context window to the lorebook and the running conversation. A card that budgeted a thousand tokens of world detail in one app may see most of it cut in another.

This is worth naming clearly, because the usual reaction is to start editing the card — which then breaks it in the app it came from. Diagnose the configuration first. The comparison method in Rewriting a Stale Roleplay Character works here unchanged: fixed opening messages, one variable at a time. If your lorebook entries stopped firing, the likely cause is a trigger or budget difference rather than lost text — see World-Building for AI Roleplay.

The apps with no door at all

Everything above assumes both apps speak the card format. A large share of consumer companion apps do not. The character exists as rows in a database, the editor exposes a short description box, and there is no export button — not because the data is complex, but because portability is not a product goal. Judging that fairly matters: a closed app is not automatically a worse app, and plenty of people never want to move. But it does change what you are committing to when you spend weeks refining a persona inside it.

Check for the door before you need it, not after. If an app offers card export, it will normally say so in its settings or help pages, and the export will name a format. If the word "export" appears nowhere, assume the character is not recoverable and keep your own copy of the text you wrote — a plain document with the description, personality and greeting is a crude but effective backup that no format change can break. How much editing control each app gives you in the first place is part of what we look at in the app rankings, and the MusePick review covers a roleplay-first app on this dimension.

A pre-move checklist

  1. Export in the richest format offered. If both PNG and JSON are available, take both — the JSON is easier to inspect and repair, the PNG carries the avatar.
  2. Note the generation. The export dialogue usually states V2, V3 or CHARX. If it does not, the safest assumption is V2.
  3. Keep the original file untouched. Re-exporting from the receiving app can silently downgrade a V3 card to V2, and you cannot recover decorators from a downgraded copy.
  4. Import, then read the editor field by field. Compare against the source card: description, personality, example dialogue, greetings, lorebook entry count. Missing entries show up here, not in the chat.
  5. Run three fixed opening messages. One light, one emotionally loaded, one that asks the character to take initiative — the same three in both apps, so a difference means something.
  6. Rebuild what the format could not carry. Avatar and expression images, greeting variants, and any lorebook entries that failed to arrive. Do this last, once you know what is actually missing.

Done in that order, a migration takes under an hour and tells you something durable: which parts of your character were in the file, and which were in the app. That distinction is the real content of portability, and it is worth knowing before you need it. If you are building a character from scratch with a future move in mind, Building Your First Roleplay Character and How AI Character Creators Work cover what belongs in the card rather than in the app.

Frequently asked questions

Can I move a character card from one app to another?

Only if both apps speak the same card format. Apps built around the community character card specs read and write PNG files with the card JSON embedded inside, so a card exported from one usually opens in another. Many consumer companion apps never expose a card file at all, and in those the character cannot be moved out by any supported route.

What is the difference between a V2 and a V3 character card?

V2 wraps the original six V1 fields inside a data object and adds a system prompt, post-history instructions, alternate greetings, an embedded lorebook, tags, creator metadata and an extensions object. V3 is a superset of V2: it keeps every V2 field and adds an assets list, a nickname, multilingual creator notes, a source list, group-only greetings, and lorebook decorators. V3 is stored in a separate chunk, so a V3-only card can look empty to a V2-only reader.

Why does my imported character behave differently in the new app?

The card is only one of several inputs. The new app supplies its own system prompt, model, sampler settings and context budget, and it may truncate or ignore fields it does not implement. A character that reads identically in both editors can still produce different replies, which is a configuration difference rather than a broken import.

Sources: Character Card V3 specification (SPEC_V3.md) · Character Card V2 specification (spec_v2.md). Field lists, chunk names, the CHARX container and the V2 requirement to preserve unknown keys are taken from these specifications; individual app behaviour varies and should be verified in the app you use.