portabletext/portabletext
portabletext/portabletext has 1,453 GitHub stars and 22 forks. GitHot measured +2 stars in 24 hours. Last checked 2026-11-07 06:08 UTC. Last push 2026-10-27.
Portable Text is a JSON based rich text specification for modern content editing platforms.
Measured star growth
- in 24h
- +2
- in 7 days
- Update delayed
- in 15 days
- Update delayed
- in 1 month
- Update delayed
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalSpecification for Portable Text
v0.0.1 - WORKING DRAFT
Portable Text is a JSON based rich text specification for modern content editing platforms.
New to Portable Text? The introduction on portabletext.org walks through the ideas behind this specification with more examples.
Portable Text is an agnostic abstraction of rich text that can be serialized into pretty much any markup language, be it HTML, Markdown, SSML, XML, etc. It's designed to be efficient for real-time collaborative interfaces, and makes it possible to annotate rich text with additional data structures recursively.
Portable Text is built on the idea of rich text as an array of blocks, themselves arrays of children spans. Each block can have a style and a set of mark definitions, which describe data structures distributed on the children spans. Portable Text also allows for inserting arbitrary data objects in the array, only requiring _type-key. Portable Text also allows for custom content objects in the root array, enabling editing- and rendering environments to mix rich text with custom content types.
Example of a text block with some text annotated with some data:
{
"style": "normal",
"_type": "block",
"children": [
{
"_type": "span",
"marks": ["a-key", "emphasis"],
"text": "some text"
}
],
"markDefs": [
{
"_key": "a-key",
"_type": "markType",
"extraData": "some data"
}
]
}
Anatomy
Portable Text is a recursive composition of arrays and objects. In its simplest form it's an array of objects of a type with an array of children.
Fields that start with an underscore, like _type and _key, are part of the structure Portable Text itself defines. The prefix keeps them apart from the data you add, like href on a link. _type names what kind of object something is, and _key identifies an object so that other parts of the content can refer to it, the way a span's marks refer to a mark definition.
Block
A block is what's typically recognized as a section of a text, e.g. a paragraph or a heading.
children (array)
Children is an array of spans or custom inline types that is contained within a block.
_type (string)
All blocks must be of a type. The type makes it possible for a serializer to parse the contents of the block.
style (string)
Style typically describes a visual property for the whole block.
{
"style": "h1",
"_type": "block",
"children": [
{
"_type": "span",
"text": "This is a heading"
}
]
}
markDefs (array)
Mark definitions is an array of objects with a key, type and some data. Mark definitions are tied to spans by adding the referring _key in the marks array.
{
"markDefs": [
{
"_key": "some-random-key",
"_type": "link",
"href": "https://portabletext.org"
},
{
"_key": "some-other-random-key",
"_type": "comment",
"text": "Change to https://",
"author": "some-author-id"
}
]
}
listItem
A block can be given the property listItem with a value that describes which kind of list it is. Typically bullet, number, square and so on. The list position is derived from the position the block has in the array and surrounding list items on the same level.
level
Level is used to express visual nesting and hierarchical structures between blocks in the array.
span
A span is the standard way to express inline text within a block
_type (string)
All children must be typed. The type makes it possible for a serializer to parse the contents of the child.
marks (array)
Marks are how we mark up inline text with additional data/features. Marks comes in two forms: Decorators and Annotations. Decorators are marks as simple string values, while Annotations are keys to a data structure. marks is therefore either an array of string values, or keys, corresponding to markDefs, with the same _key. See the examples below, or check out this live CodeSandbox example with an inline image and a link:
Decorator example:
[
{
"_type": "span",
"marks": [],
"text": "This is"
},
{
"_type": "span",
"marks": ["emphasis"],
"text": "important"
}
]
Annotation example:
[
{
"_type": "block",
"children": [
{
"_type": "span",
"text": "Portable Text",
"marks": ["<markDefId>"] // this corresponds to a `"_key"` in `markDefs`
}
],
"markDefs": [
{
"_type": "link",
"_key": "<markDefId>", // this corresponds to a value in `children.marks`
"href": "https://www.portabletext.org"
}
]
}
]
Text (string)
The text contents of the span.
Custom blocks
Custom blocks are typically images (for inline images, see the marks section), code blocks, tables, video embeds, or any data structure. Custom blocks should be given a _type.
Examples of custom blocks:
{
"_type": "image",
"asset": {
"_ref": "some-asset-reference"
}
}
{
"_type": "code",
"language": "javascript",
"code": "console.log(\"hello world\");"
}
Serialization
Tools
JavaScript
- @portabletext/react
- @portabletext/react-native
- @portabletext/react-pdf
- @portabletext/svelte
- @portabletext/vue
- @portabletext/to-html
- @portabletext/block-tools
- @limitless-angular/sanity/portable-text
- @sanity/block-content-to-hyperscript
- @sanity/block-content-to-markdown
- theisel/astro-portabletext
PHP
- The
Sanity\BlockContentclass in the sanity-php client
Python
C#
- The
SanityHtmlBuilderclass in the Sanity LINQ client - Portable Text .NET, a C# HTML converter to Portable Text, also supporting custom types. (A graceful port of
blockTools.htmlToBlocks()to C#)
Dart/Flutter
- Flutter Widget for Portable Text: Supports the entire spec of Portable Text with an easy to use Widget. It also includes support for custom blocks, marks, gestures, styles in an extensible manner. Use this package in conjunction with the Sanity Client package for deserializing Portable Text in documents from Sanity.
- flutter_portabletext
Portable Text is presented by Sanity.io
Explore related projects
codecrafters-io/build-your-own-x
Master programming by recreating your favorite technologies from scratch.
560,805 starspublic-apis/public-apis
A collective list of free APIs
497,039 starsmorluto/rea
Reverse engineer anything with agents, from app behavior down to native binaries.
441,222 starsopenclaw/openclaw
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
394,149 stars