CLI tool
remarshal-project/remarshal avatar
remarshal-project/remarshal

remarshal refuses to lose data on the way between formats

Convert between CBOR, JSON, MessagePack, TOML, and YAML 1.1 & 1.2

554 stars37 forksPythonMIT

At a glance

What is it?
remarshal is a command line converter between CBOR, JSON, MessagePack, TOML and YAML that treats a lossy conversion as an error unless you explicitly relax it, and it can transform the data on the way with a Starlark program. The strictness is the design, and it is the main thing to understand.
Who is it for?
Adopt remarshal if you need to move structured data between these formats and you would rather be told when a conversion would lose information than get a subtly wrong file. Do not adopt it for a quick one-off if a library call in your own code will do, since it is a command line tool, and note that its Python output is one way.
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 83 days ago.
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 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A converter that treats information loss as an error

remarshal converts between CBOR, JSON, MessagePack, TOML and YAML, and can also convert all of them to Python code. The README states the design rule immediately: Remarshal tries to convert documents without losing information by default, which means a document converted from format A to B and then back to A should be equal to the original document. When a lossless conversion is impossible, Remarshal exits with an error.

That single rule explains most of the tool's behaviour, and it is a different choice from the one most converters make. The usual approach is to produce output and let the user notice the difference later. Here, a document with a boolean used as a JSON key, or a date-time value, stops the conversion with an error rather than producing a file that has quietly become something else.

The escape hatch is the -k/--stringify option, which relaxes the restriction. When converting to JSON it turns boolean and null keys and date-time keys and values into strings. When converting to TOML it turns boolean, date-time and null keys and null values into strings. The README says this is usually what you want, and that it is not the default as a safeguard against information loss.

Both halves of that sentence matter. The default is the strict one, and the flag exists because most real documents contain something the target format cannot hold.

The project is on PyPI as remarshal, the homepage is the PyPI project page, the licence is MIT, and the repository is not archived with the last push on 2026-08-01, with v2.1.4 released the same day.

The command surface, and the short names for the common cases

Installed, remarshal provides the command remarshal as well as short commands like yaml2json. The console scripts in the project metadata make the pattern explicit, and the set covers the full cross product of the supported formats: cbor2cbor, cbor2json, cbor2msgpack, cbor2py, cbor2toml, cbor2yaml, json2cbor, json2json, json2msgpack, json2py, json2toml, json2yaml, and the same for msgpack and the other sources, all pointing at the same remarshal.main:main entry point.

So there are two ways to use the tool. The long form takes a format flag, remarshal --from json --to yaml, and the short form encodes the same thing in the command name, json2yaml. The short form is what you want in a script where the conversion is fixed, and the long form is what you want when the format is a variable.

The main usage block in the README shows the option set.

none
usage: remarshal [-h] [-v]
                 [-f {cbor,json,msgpack,toml,yaml,yaml-1.1,yaml-1.2}]
                 [-i <input>] [--indent <n>] [-k] [--max-values <n>]
                 [--multiline <n>] [-o <output>] [-s]
                 [--starlark <code> | --starlark-file <path>]

Input and output can be given as positional arguments or with -i and -o, and -v prints the program version. There are also options for YAML specifics, --yaml-expand-aliases, --yaml-style, --yaml-style-newline and --yaml-tags, and for TOML output, --multiline, which sets the minimum number of items to make a non-nested TOML array multiline, with a default of 6.

The repository root holds an example file in each format, example.cbor, example.json, example.msgpack, example.py, example.toml and example.yaml, which is a quick way to see the shape of each.

YAML 1.1 and 1.2, and what that means for your files

The YAML version handling is a known limitation and a quirk in one sentence: remarshal works with YAML 1.2 by default, you can use the format yaml-1.1 to work with YAML 1.1, and yaml-1.2 can be used to select YAML 1.2 explicitly. Conversion between YAML 1.1 and 1.2 is supported.

This matters more than it sounds. The two YAML versions disagree about core scalars, and the disagreement is where configuration files break in surprising ways. Whether a bare yes is a boolean or a string, whether an octal-looking number is parsed as a number, how timestamps are typed, these all differ. A file that round-trips under one version and changes meaning under the other is exactly the kind of bug that survives a review.

Being able to convert between the two versions is a genuinely useful capability and one that most quick converters do not offer.

The implementation choices behind this are visible in the dependencies. ruamel.yaml is the YAML library, and it is the round-trip preserving parser, which is what you need if you care about key order and formatting. tomlkit is in the list for TOML, and it is the library built for preserving formatting and comments when writing TOML back out, and tomli is the read side.

And the README is direct about one consequence: remarshal does not preserve or convert TOML and YAML comments. That is a real loss for a configuration workflow, and no option turns it back on.

The date-time rules, which are the real specification

The date-time section of the README is where the format conversion rules become concrete, and it is worth reading closely because this is where data actually gets mangled.

CBOR, MessagePack, and YAML with binary fields cannot be converted to JSON or TOML. Binary fields can be converted between CBOR, MessagePack and YAML.

For date-times, local dates convert between CBOR RFC 8943 dates at tag 1004, TOML Local Dates, and YAML timestamps without a time or a time zone. Local date-time converts between TOML Local Date-Time and YAML timestamps without a time zone. Date-time with a time zone converts between CBOR standard date-time strings at tag 0, the MessagePack Timestamp extension type, TOML Offset Date-Times, and YAML timestamps with a time zone. And TOML Local Time cannot be converted to a date-time in another format.

That last one is a genuine gap rather than a quirk, because TOML has a local time type that has no counterpart elsewhere, and no amount of stringification can turn it into a date-time.

The escape for all of it is the -k flag again. All date-time types can be converted to JSON with the -k/--stringify option, which turns them into strings, and converting a document with a date-time type to JSON fails without that option.

So the rule of thumb for a user is that date-times in YAML and TOML cross over cleanly, CBOR and MessagePack timestamps map onto YAML and TOML offset date-times, and anything involving a local time or a binary field needs the stringify flag or a different plan.

Starlark transforms, with limits on what they can do

The tool can transform data on the way through, and the README describes this as a Starlark transformation.

The --starlark option takes a Starlark expression or program, the input is bound to data, and the program must assign the output to result. The --starlark-file variant reads the program from a path. The topics list starlark and starlark-python, and the dependency list includes starlark itself.

This is a deliberately small language, and the tool makes the limits explicit with two options. --starlark-max-steps and --starlark-max-allocs both take a number, which is the mechanism for stopping a transformation that does not terminate or that allocates without bound. That is the right design for running user-supplied code inside a CLI that might be in a pipeline, and it is a detail you will not find in most conversion tools because most conversion tools do not execute code.

The input side has a matching limit. --max-values sets the maximum number of values in the input data, with a default of 1000000 and a negative value for unlimited, so there is a guard against a document that would exhaust memory before parsing finishes.

The other Starlark-adjacent option is --unwrap and --wrap, which take a key, and they are for changing the shape of the document around a key rather than its values. The README does not give a worked example of them, so the exact semantics of unwrapping and wrapping a key are something you check in the help output or the tests.

Installing it, including the zero-install path

You need Python 3.12 or later, and earlier versions of Python are not supported. That is a hard floor and it is worth checking before anything else, because the tool is published for recent interpreters only.

The recommended way to run it is to install the latest release from PyPI with pipx or uv.

sh
pipx install remarshal
# or
uv tool install remarshal

Regular installation is not mandatory, which is the most convenient thing in the README. The command pipx run remarshal with arguments will download Remarshal and run it from a temporary location, and it will cache the downloaded version for up to 14 days, and it will not be automatically upgraded during that period. The uvx form works the same way.

So for a one-off conversion on a machine you do not want to install anything on, pipx run or uvx is the whole install story. For a machine where the tool is on your path every day, pipx install or uv tool install is the answer, because both give you an isolated environment per tool.

It is also possible to install the current development version, though the README says to prefer releases unless you have a reason to run a development version.

sh
pipx install git+https://github.com/remarshal-project/remarshal
# or
uv tool install git+https://github.com/remarshal-project/remarshal

The build backend is poetry-core 2.0 or newer, the version is 2.1.4, and the project is classified as Development Status 5, Production or Stable, with a Topic of File Formats and a Topic of Utilities.

Python output, which is one way and needs your own formatter

The Python output mode is the one with the most caveats, and the README is honest about all of them.

Conversion to Python code is one-way. The output is either from repr, which is the default, or formatted by pprint.pformat when you pass the --indent option. The default repr format ignores -s and --sort-keys.

The second caveat is style. The style of pprint may not match your project's coding style, and the README recommends applying your preferred Python formatter to the output. Which is a fair recommendation, and also an admission that the output is not ready to commit.

The third is imports. Python output does not include the necessary import statements, and you may need to add import datetime before the data, for example. So the generated file is a fragment of Python rather than a module, and for a datetime-heavy document it will not even parse until you add the import.

Combined with the one-way constraint, that makes Python output a convenient intermediate format for inspecting or diffing data rather than a source form you would maintain.

It is worth contrasting with the other formats. remarshal can convert to Python, and it can convert between the structured formats, but it cannot convert Python back into JSON, TOML or YAML. The Python mode is a terminal output, not a participant in the round trip that the structured formats support.

Where remarshal is the wrong choice

Three cases, and the first is the most common.

If you need this inside a program rather than on a command line, remarshal is the wrong shape. It is a CLI with a console script entry point, and the data flows through files or standard input and output. A service that converts documents on request would call the underlying libraries directly, since the dependency list is a set of well known format libraries, cbor2, u-msgpack-python, ruamel.yaml, tomlkit and tomli. The CLI is the wrapper, not the engine.

The second is a workflow where you need comments to survive. The README states plainly that remarshal does not preserve or convert TOML and YAML comments. For a configuration pipeline where comments carry intent, the conversion is destructive, and no option changes that.

The third is a document with binary payloads and strict typing requirements. Binary fields cannot cross into JSON or TOML, TOML local time has no counterpart in the other formats, and while the -k flag will stringify the problem cases, the result is a different document rather than the same document in another encoding. If your pipeline needs the binary content to arrive intact, remarshal is only useful between CBOR, MessagePack and YAML.

The upside of all this is that the strictness is not a limitation but the feature. A tool that fails loudly when a conversion is lossy is a tool you can put in a pipeline, and most converters cannot be.

Editorial conclusion

Adopt remarshal if you need to move structured data between these formats and you would rather be told when a conversion would lose information than get a subtly wrong file. Do not adopt it for a quick one-off if a library call in your own code will do, since it is a command line tool, and note that its Python output is one way. Before you put it in a script, decide whether you want the strict default or the -k flag, because that choice changes whether a binary field, a boolean key or a date-time value stops the conversion or gets silently stringified.

Frequently asked questions

What formats does remarshal convert between?

CBOR, JSON, MessagePack, TOML and YAML, with YAML 1.1 and 1.2 both selectable and conversion between the two YAML versions supported. It can also convert to Python code, though that conversion is one-way.

What does the -k/--stringify option do in remarshal?

It relaxes the default rule that a conversion must be lossless. For JSON it turns boolean and null keys and date-time keys and values into strings, and for TOML boolean, date-time and null keys and null values into strings. The README says this is usually what you want, but it is not the default as a safeguard against information loss.

How do I install remarshal without polluting my environment?

Use pipx install remarshal or uv tool install remarshal, as the README recommends. You can also run it without installing anything with pipx run remarshal or uvx remarshal, which downloads it to a temporary location and caches it for up to 14 days without upgrading during that period.

Can remarshal transform data while converting it?

Yes. The --starlark option takes a Starlark expression or program with the input bound to data and the output assigned to result, and --starlark-file reads the program from a path. The --starlark-max-steps and --starlark-max-allocs options bound what such a program can do.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. remarshal-project/remarshal on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/remarshal-project-remarshal.svg)](https://hysenlabs.com/projects/remarshal-project-remarshal)

Was this useful?