FREE is an open source format for vector graphic files designed to be compact, human-readable, back-compatible, and optimized for multithreaded parsing.
A FREE file is a ZIP archive with the following structure:
pages
— folder with JSON files containing layer structure and properties.images
— folder with raster assets. PNG, JPG, BMP, WEBP, GIF, TIFF, and ICO are supported.fonts
— folder with fonts embedded into the document, if any.shared
— folder with JSON files containing structure and properties of components and styles used from shared libraries.document.json
— file with document info data.meta.json
— file with app version, file format, last saved by, when, and other info.preview.png
— a preview of the file.
Lunacy has the support for the Sketch format from the very beginning. Including both opening and saving such files. It's actually a great format with lots of advantages (JSON, everything bundled in a ZIP archive, extensions via UserInfo, a time-proved data structure, and many others) but over time, we've accumulated a long list of drawbacks that have been limiting Lunacy’s growth.
- No support for nested artboards (frames).
- You can’t rotate artboards.
- You can’t apply styling options to artboards, round their corners, etc.
- Component overrides are only possible for a few fields supported by Sketch.
- There's no way to introduce new layer types.
And there are reasons for this:
-
Cumbersome MacOS-tied naming style for parameters:
MSImmutableFreeformGroupLayout
,MSJSONFileReference
,MSAttributedStringColorAttribute
,NSCTFontSymbolicTrait
. -
Some of the parameter names are overly verbose:
allowsDefaultTighteningForTruncation
,textStyleVerticalAlignmentKey
,automaticallyDrawOnUnderlyingPath
,includeBackgroundColorInInstance
,MSAttributedStringColorDictionaryAttribute
. -
The same applies to how the shape points are stored, resulting in enormous json files and slow file open times.
{ "_class": "curvePoint", "cornerRadius": 0, "cornerStyle": 0, "curveFrom": "{0, 0}", "curveMode": 1, "curveTo": "{0, 0}", "hasCurveFrom": false, "hasCurveTo": false, "point": "{0, 0}" },
-
Lots of fields have to be explicitly specified even for default values, i.e. they do not affect anything. But if you try to optimize a file, Sketch won’t open it. Take the fields from the above example and multiply it by millions of points in an average document.
"cornerRadius": 0, "cornerStyle": 0, "curveFrom": "{0, 0}", "curveMode": 1, "curveTo": "{0, 0}", "hasCurveFrom": false, "hasCurveTo": false,
-
Also, object types are often explicitly defined, though they are self-evident from the context. Take
"_class": "curvePoint"
from the above example. And, again, multiply it by the number of points in the document. -
All Lunacy features that are not supported by Sketch we have to squeeze into userInfo, which is also far from being effective.
-
Points are described as strings, which adds extra complexity to parsing. First, you read a string like
"{0, 0}"
from JSON, and then you parse the values within that string. This impacts file reading performance. -
All IDs are specified as full GUIDs, like
"1FCC7597-95CD-43E9-B264-18E8006C60B1"
, which is great in terms of data integrity but not the most efficient in terms of file size. -
Overrides have a peculiar format. For some reason, the data from this complex object is crammed into a single serialized string, containing an array of the target layer's IDs, the override type, and occasionally the override object's number:
"42AB34F8-C748-46D5-9373-073296D64ABA/1FCC7597-95CD-43E9-B264-18E8006C60B1_color-1"
This approach is inefficient for parsing. Multiple JSON properties would work way better here.
While working on import from Figma, we thoroughly explored the .fig format. It has one huge advantage — it’s binary and therefore extremely efficient in terms of disk space usage. But there are also serious downsides of the format:
- Not human-readable.
- Proprietary with no public format specification.
- No backward compatibility. Every new version can introduce a completely new format if the Figma team deems it necessary.
Due to this, supporting the .fig format is costly. It requires at least one experienced full-time developer with reverse engineering expertise dedicated solely to this task. And during Figma updates, sleepless nights may be required to quickly roll out an update to support the new format. Lots of products that previously supported the format have given up.
We've made the decision to take the Sketch format and address all of its drawbacks while introducing new advantages. Therefore, the FREE format can be considered the successor to the Sketch format. We aimed for the format to be:
- Open source
- Fully back-compatible
- Human-readable
- Compact
- Easily extendable for third parties
- Optimized for high-performance multithreaded reading
We didn't rush the development and release of this format. We worked on it for an extended period, carefully refining all ideas and solutions, so that after new releases its back-compatibility would be as seamless as possible.
-
All fields have short, understandable names. For example,
"hidden": true
. -
The object type field is given a concise name,
"_t,"
and is only specified where necessary, which is in just three places: layer type, grid layout type, and layout type. -
If a value is default, it is simply omitted from the file, even for complex objects.
-
All GUIDs are written as ShortGUIDs, which are the base64 serialization of the byte data of the GUID. They retain all the GUID data but occupy 39% less space:
-
1FCC7597-95CD-43E9-B264-18E8006C60B1
- 36 characters -
_w7kV9AThEiBBxn5BtFCBA
- 22 characters
-
-
The Point data type is specified as an array of two numbers rather than a serialized string, which not only takes up slightly less space but also parses much faster:
-
Sketch format:
"To": "{367, 566}"
-
FREE format:
"To": [367, 566]
- 3 characters shorter
-
-
The Size data type is also specified as an array:
-
Sketch format:
"Width": 367, "Height": 566
-
FREE format:
"Size": [367, 566]
- noticeably shorter
-
-
The Matrix data type has two notation options: simple and with rotation.
"Transform": [4, 6]
- x and y coordinates of an object."Transform": [0.9, 0.1, 4, 0.1, 0.9, 6]
- ScaleX, SkewX, TransX, SkewY, ScaleY, TransY - this matrix includes the values of the following Sketch fields: x, y, rotation, isFlippedHorizontal, and isFlippedVertical. This is significantly more efficient. -
The key difference. The Vertex data type, which defines path points, and has several notation options. It's simply an array of numbers and can include up to eight values:
[x, y, flags, radius, fromX, fromY, toX, toY]
. If the points on the right end of the array have default values, they are omitted. So, if toX, toY, fromX, fromY are all zeros, the array will look like[x,y,flags,radius]
. And if flags and radius are zeros, it becomes[x, y]
. Compare these two definitions of points of a rectangle, the most frequent element in all documents:- Sketch (682 characters)
"points":[ {"_class":"curvePoint","cornerRadius":0,"cornerStyle":0,"curveFrom":"{0, 0}","curveMode":1,"curveTo":"{0, 0}","hasCurveFrom":false,"hasCurveTo":false,"point":"{0, 0}"}, {"_class":"curvePoint","cornerRadius":0,"cornerStyle":0,"curveFrom":"{1, 0}","curveMode":1,"curveTo":"{1, 0}","hasCurveFrom":false,"hasCurveTo":false,"point":"{1, 0}"}, {"_class":"curvePoint","cornerRadius":0,"cornerStyle":0,"curveFrom":"{1, 1}","curveMode":1,"curveTo":"{1, 1}","hasCurveFrom":false,"hasCurveTo":false,"point":"{1, 1}"}, {"_class":"curvePoint","cornerRadius":0,"cornerStyle":0,"curveFrom":"{0, 1}","curveMode":1,"curveTo":"{0, 1}","hasCurveFrom":false,"hasCurveTo":false,"point":"{0, 1}"}]
- FREE (34 characters)
"points":[[0,0],[1,0],[1,1],[0,1]]
20 times less in size! Considering that Vertex is the most frequently encountered data type in the format, and a file may contain millions of them. Sacrificing some human-readability in this specific area, where it's not as crucial as in others, was a well-considered choice.
-
For colors the FREE format uses HEX strings, while Sketch uses a complex object. Given that color is the second most frequently used object after Vertex, reducing its complexity is also highly critical:
-
Sketch:
{"_class":"color","alpha":1,"blue":0.827451,"green":0.76862746,"red":0.27058825}
- 80 characters. -
FREE:
“45C4D3”
- 8 charecters, 10 times less. -
Also, the color 333333 in the FREE format will go as 3, the color 4455FF — as 45F.
-
-
Simplified, compact, and unbounded overrides. You can override any value. A single override can affect several values. In Sketch, the set of overrides is limited. Each field requires its own override. The number of fields is also limited and strictly defined. Plus parsing of complex strings can impact performance. The FREE format eliminates all these issues.
"overrides":[{ "target":["bmlSSK7GO0SzhLA-YSdg3Q","TE1yOSobJkONa7C7EvKfig"], "locked":true, "hidden":false, "fills":[{"color":"B2EBF2"}], "link":"back" }]
-
document.json
does not include any foreign properties. They are stored in a separate file, namedforeign.json
. This preventsdocument.json
from growing to enormous sizes, up to several gigabytes in some cases. Instead, it remains small and quick to parse. Foreign objects are parsed in a separate thread, ensuring it doesn't impact the file's opening speed. -
[Currently not implemented, coming soon] If a page size exceeds 20MB, it will be divided into 20MB parts, with the division occurring at the top-level artboards. For example, if a page features top-level artboards of 30MB, 10MB, 5MB, 1MB, and 10MB in size, it will be split into parts of 30MB, 16MB, and 10MB. We've observed that in very large files, there's typically one page that is 5-50 times larger than the others. Consequently, parsing it takes N times longer, monopolizes one execution thread, and significantly slows down the file opening. This approach will allow parallel parsing of large pages across multiple CPU threads, and greatly improve the opening speed of such files.
On small files or files with few layers but many images, improvements might not be very noticeable. But you will definitely see them on massive files with dozens or even hundreds of thousands of layers.
-
JSON file sizes are reduced by a factor of 5-10. It's worth noting that JSON compresses well, and after compression, the difference consistently leads to a substantial reduction by a factor of 2. In our case, when transmitting JSON data over the internet, especially in cloud documents, this 5-10 times reduction significantly saves bandwidth for users and our servers.
-
The size of images remains unchanged because they are already maximally compressed. However, it's important to mention that the FREE format supports various image formats, including JPG, PNG, WEBP, GIF, and others, without the need to convert them to PNG, as some competitors do. Converting JPG to PNG often significantly increases image size. Lunacy doesn't do this.
-
The file opening process has improved by an average of 30%, and in some cases, especially with very large files, the speedup can be as high as 200%.
Assume that we have a red rectangle on the canvas. In Sketch, it would result in a JSON representation of 1639 characters (measured with the JSON formatted into a single line).
{
"_class": "rectangle",
"do_objectID": "5FF2A422-C956-4F7A-9E49-C295DB00A4D9",
"booleanOperation": -1,
"isFixedToViewport": false,
"isLocked": false,
"isVisible": true,
"isTemplate": false,
"layerListExpandedType": 0,
"name": "Rectangle",
"nameIsFixed": false,
"resizingConstraint": 63,
"resizingType": 0,
"rotation": 0,
"shouldBreakMaskChain": false,
"exportOptions": {
"_class": "exportOptions",
"includedLayerIds": [],
"layerOptions": 0,
"shouldTrim": false,
"exportFormats": []
},
"frame": {
"_class": "rect",
"constrainProportions": false,
"height": 428,
"width": 431,
"x": 1887,
"y": -751
},
"clippingMaskMode": 0,
"hasClippingMask": false,
"style": {
"_class": "style",
"endMarkerType": 0,
"miterLimit": 10,
"startMarkerType": 0,
"windingRule": 1,
"fills": [
{
"_class": "fill",
"isEnabled": true,
"fillType": 0,
"color": {
"_class": "color",
"alpha": 1,
"blue": 0,
"green": 0,
"red": 1
}
}
]
},
"edited": false,
"isClosed": true,
"pointRadiusBehaviour": 1,
"points": [
{
"_class": "curvePoint",
"cornerRadius": 0,
"cornerStyle": 0,
"curveFrom": "{0, 0}",
"curveMode": 1,
"curveTo": "{0, 0}",
"hasCurveFrom": false,
"hasCurveTo": false,
"point": "{0, 0}"
},
{
"_class": "curvePoint",
"cornerRadius": 0,
"cornerStyle": 0,
"curveFrom": "{1, 0}",
"curveMode": 1,
"curveTo": "{1, 0}",
"hasCurveFrom": false,
"hasCurveTo": false,
"point": "{1, 0}"
},
{
"_class": "curvePoint",
"cornerRadius": 0,
"cornerStyle": 0,
"curveFrom": "{1, 1}",
"curveMode": 1,
"curveTo": "{1, 1}",
"hasCurveFrom": false,
"hasCurveTo": false,
"point": "{1, 1}"
},
{
"_class": "curvePoint",
"cornerRadius": 0,
"cornerStyle": 0,
"curveFrom": "{0, 1}",
"curveMode": 1,
"curveTo": "{0, 1}",
"hasCurveFrom": false,
"hasCurveTo": false,
"point": "{0, 1}"
}
],
"fixedRadius": 0,
"needsConvertionToNewRoundCorners": false,
"hasConvertedToNewRoundCorners": true
}
In Lunacy's FREE format the same will take only 110 characters. A 15-fold difference.
{
"_t": "RECT",
"id": "IqTyX1bJek-eScKV2wCk2Q",
"transform": [1887,-751],
"size": [431,428],
"fills": [{"color":"F00"}]
}
After fully adapting the new format and polishing it, we plan to develop, test, and, once acceptable results are achieved, introduce support for a binary variation of the format. This means that within the ZIP archive, you'll have .BIN files instead of .JSON. The idea is to maintain the same structure and practices but represent the data in the most efficient manner. Additionally, in the case of providing such serialization options, we will offer a converter that will be able to convert the data to JSON and back, preserving user-readability and maximum file size efficiency. If successful, we can attain the efficiency of the .fig format without its drawbacks.
Free format is NULL-free, NaN-free and Infinity-free - if any of this values are in JSON - it's broken.
- float - 32bit single-precision floating-point number
- int - 32bit signed integer
- byte - 8-bit unsigned integer
- bool - Boolean (true or false) value
- string - text as a sequence of UTF-8 code units
- GUID - globally unique identifier, with base64 encryption
A component is a reusable groups of layers.
Has all properties of Frame
, plus:
- _t: string =
COMPONENT
- ComponentId: GUID - unique component identifier.
- Predefined: bool =
False
- indicates that the component belongs to the Lunacy default component library (see the Component Tool on the Toolbar) - ComponentType: ComponentType =
None
- reserved for future use. Will be used for component filters.
Sketch compatibility
- BackgroundInInstance: bool =
False
- defines whether to include background in component instances.
An oval is a shape drawn on the canvas with the Oval tool.
Has all properties of Path
, plus:
- _t: string =
OVAL
- Angle: float =
0
- end angle for donuts measured clockwise from the X axis. - Ratio: float =
0
- inner radius for donuts. - StartAngle: float =
0
- start angle for donuts measured clockwise from the X axis.
A polygon is a shape drawn on the canvas with the Polygon tool.
Has all properties of Path
, plus:
A rectangle is a shape drawn on the canvas with the Rectangle tool.
Has all properties of Path
, plus:
- _t: string =
RECT
- SmoothCorners: bool =
False
- if the smooth corners option is enabled. Works only if the rectangle is not edited.
A star is a shape drawn on the canvas with the Star tool.
Has all properties of Path
, plus:
- _t: string =
STAR
- Rays: float =
0
- defines the number of rays in a star. - Ratio: float =
0
- defines the star ratio value.
A triangle is a shape drawn on the canvas with the Triangle tool.
Has all properties of Path
, plus:
- _t: string =
TRIANGLE
Sketch compatibility
- Equilateral: bool =
False
- if the triangle is equilateral.
A frame is a special type of layers that serves as a container for other layers or layer groups. Frames are a must for prototypes.
Has all properties of Styled
, plus:
- _t: string =
FRAME
- CornerRadius: float[] =
float[4]
- sets the corner radius of the frame. - SmoothCorners: bool =
False
- enables smooth rounded corners like in iOS interfaces. - ClipContent: bool =
False
- when enabled, hides the content outside the frame boundaries. - FlowHome: bool =
False
- sets the frame as a prototype starting point. - Viewport: PrototypeViewport - defines the area that should be displayed on a prototype, when the frame is resized to ensure scrolling effect.
- ResizesContent: bool =
False
- enables adjusting and resizing the frame content as the frame is resized. - Layouts: IGridLayout[] - grid, Row and Column layouts of the frame.
- Rulers: Rulers - rulers and guidelines info.
- Layers: Layer[] - list of layers on the frame.
Sketch compatibility
- OverlayStyle: Style - style settings for the frame if it acts as an overlay in Sketch prototyping.
- GroupLayout: SketchGroupLayout - sketch Layout settings. Not supported in Lunacy, but keeping data for compatibility.
- BackgroundInExport: bool =
False
- when enabled, the frame background is included into export files. - OverlayInteraction: OverlayBackgroundInteraction =
None
- overlay interaction for Sketch prototyping. - Overlay: bool =
False
- defines whether the frame acts as an overlay in prototyping. - HasBackground: bool =
False
- defines whether the frame has background. - Background: Color =
ffffffff
- defines the frame background color. - BackgroundId: GUID - defines the background color variable ID.
- OverlaySettings: OverlaySettings - sketch prototyping overlay feature settings.
A layer group is two or more layers unified into a single entity that can be manipulated, organized, and treated as a single layer.
Has all properties of Styled
, plus:
- _t: string =
GROUP
- SkipSelect: bool =
False
- when enabled, users can select group items without first selecting the group. - Layers: Layer[] - list of layers within the group.
Sketch compatibility
- SkipConstraints: bool =
False
- serves for constraints compatibility with Sketch. If the file is imported from the Sketch format, the parameter should be set to false to handle constraints properly. - GroupLayout: SketchGroupLayout - sketch group layout. We don't support it but keep it for compatibility
An instance is a copy of the main component. With instances, you can reuse the same design element in multiple places in your project while retaining a connection to the main component.
Has all properties of Styled
, plus:
- _t: string =
INSTANCE
- CornerRadius: float[] =
float[4]
- sets the corner radius of the instance frame. - SmoothCorners: bool =
False
- enables smooth rounded corners like in iOS interfaces. - Scale: float =
0
- scale of the instance. - ComponentId: GUID - unique component identifier.
- Overrides: Override[] - defines the overrides applied to the instance.
Sketch compatibility
A vector path determines the outline and form of a vector object. A path is made up of points and segments.
Has all properties of Styled
, plus:
- _t: string =
PATH
- Edited: bool =
False
- if the shape is edited in the path editor. - Open: bool =
False
- indicates whether the path is open. - Points: Vertex[] - list of path's points.
A shape is a rectangle, oval, polygon, triangle, or star drawn with the respective shape tool. You can draw a triangle, rectangle, etc. with the Pen tool, but they won't be treated as shapes.
Has all properties of Styled
, plus:
Sketch compatibility
- SkipConstraints: bool =
False
- serves for constraints compatibility with Sketch. If the file is imported from the Sketch format, the parameter should be set to false to handle constraints properly. - GroupLayout: SketchGroupLayout - sketch group layout. We don't support it, but keep it for compatibility.
Text is a block or line of text on the canvas.
Has all properties of Styled
, plus:
- _t: string =
TEXT
- text: string - content of the text layer.
- TextStyle: TextStyle - style applied to the text.
- Inlines: InlineStyle[] - styling options applied to the text within a text block.
- Behavior: TextBehavior =
Flexible
- behavior of the text layer size on text value change: flexible, fixed-width, or fixed. - ClipContent: bool =
True
- valid for files imported from Figma. Defines whether to truncate text content.
Sketch compatibility
- DrawOnPath: bool =
False
- this property enabled drawing text on path in Sketch.
A hotspot is a special type of layers used to define clickable areas on prototypes.
Has all properties of Layer
, plus:
- _t: string =
HOTSPOT
A slice is a special type of layers used for exporting certaing parts of designs.
Has all properties of Layer
, plus:
- _t: string =
SLICE
- HasBackground: bool =
False
- defines whether the slice includes background. - Background: Color =
00000000
- defines the background color. - BackgroundId: GUID? - unique color variable ID.
A styled layer is a layer that has layer styling options.
Has all properties of Layer
, plus:
- StyleId: GUID - unique style identifier.
- MiterLimit: int =
10
- limit on the ratio of the miter length to the stroke-width used to draw a miter joint. When the limit is exceeded, the joint is converted from miter to beveled. - Opacity: float =
1
- opacity value. - BlendMode: BlendMode =
Normal
- blend mode. - StartMarker: Arrowhead =
None
- determines the appearance of the tail of an open path drawn with the Line, Arrow, or Pen/Pencil tool. - EndMarker: Arrowhead =
None
- determines the appearance of the head of an open path drawn with the Line, Arrow, or Pen/Pencil tool. - Winding: PathFillType =
EvenOdd
- defines the filling options for overlapping paths. - Fills: Fill[] - list of fills.
- Borders: Border[] - list of borders.
- Shadows: ShadowEffect[] - list of shadows.
- InnerShadows: ShadowEffect[] - list of inner shadows.
- Blur: BlurEffect - information about blurs.
- BorderOptions: BorderOptions - information about border options.
- ImageFilters: ImageFilters - filters applied to an image (hue, saturartion, etc.), if any.
A layer is any ungrouped element available on the canvas.
- Id: GUID - unique layer identifier.
- NameIsFixed: bool =
False
- name can be auto-generated or user-specified. User-specified fixed names will not be renamed after some operations. - BooleanOp: BoolOp =
Union
- defines the boolean operation applied to the layer. - Fixed: bool =
False
- if the Fix position option is enabled: the layer preserves its position when you scroll a prototype (for instance, a floating button). - Locked: bool =
False
- defines whether the layer is locked for editing. - Hidden: bool =
False
- defines whether the layer is hidden. - IsTemplate: bool =
False
- defines whether tha layer is marked as a template. - Expand: bool =
False
- defines whether the layer is expanded in Layer List. - Trim: bool =
False
- when enabled, trims empty pixels in exported images. - Transform: Matrix =
Free.Schema.Matrix
- position, rotation and flips of an object, stored in a single 3x2 matrix. - Size: Size =
[100,100]
- defines the layer size. - LockAspect: bool =
False
- defines whether the layer's aspect ratio should be remain unchanged upon resizing. - Mask: bool =
False
- defines whether the layer is used as a mask. - BreakMask: bool =
False
- defines if the layer is set to ignore the mask. - KeepScroll: bool =
False
- if the Keep scroll position option is enabled (prototyping). - Animation: AnimationType =
FromRight
- defines the animation type (prototyping). - MinWidth: float =
0
- defines the minimum layer width (auto layout). - MinHeight: float =
0
- defines the minimum layer height (auto layout). - MaxWidth: float =
0
- defines the maximum layer width (auto layout). - MaxHeight: float =
0
- defines the maximum layer height (auto layout). - LayoutStretch: bool =
False
- determines if the layer should stretch along the parent’s counter axis (auto layout). - LayoutGrowStretch: bool =
False
- determines whether a layer should stretch along the parent’s primary axis (auto layout). - LayoutFixPos: bool =
False
- enables absolute position for the layer (auto layout).
Lunacy specific
- PhotoId: string - identifier of a photo from the Lunacy gallery.
- IllustrationId: string - identifier of an illustraion from the Lunacy gallery.
- IconId: string - identifier of an icon from the Lunacy gallery.
- AvatarId: string - identifier of a Lunacy-generated avatar.
- Data: DataInfo - information about auto generated texts.
- Upscaled: bool =
False
- if the image has been upscaled in Lunacy. - BackgroundRemove: BackgroundRemovalState =
None
- background removal procedure info.
Defines the appearance of borders.
Has all properties of Fill
, plus:
- Thickness: Thickness =
[0,0,0,0]
- defines border thickness. - Pos: BorderPosition =
Center
- defines border position.
Defines auto layout settings.
- Orientation: LayoutOrientation =
Horizontal
- layout orientation: horizontal or vertical. - Spacing: float =
0
- spacing value - WrapSpacing: float =
0
- spacing between rows of wrapped content. - Padding: Thickness =
[0,0,0,0]
- padding value. - Align: HorizontalAlignment =
Left
- horizontal children alignment - Valign: VerticalAlignment =
Top
- vertical children alignment - Sizing: SizingMode =
Auto
- horizontal resizing mode: fixed or hug. - Vsizing: SizingMode =
Auto
- vertical resizing mode: fixed or hug. - TextBaseline: bool =
False
- if text baseline alignment is enabled. - StrokesIncluded: bool =
False
- if the Include Borders option is enabled. - ReverseZIndex: bool =
False
- if the Last on Top option is enabled. - Wrap: bool =
False
- if wrapping is enabled. - WrapDistribute: bool =
False
- if auto distribute is enabled for wrapped content.
Defines the settings of the blur effect.
- Saturation: float =
1
- saturation. Only for background blur. - Radius: float =
10
- blur Radius. - Enabled: bool =
False
- if the blur is enabled. - Type: BlurType =
Gaussian
- sets the blur type.
Sketch compatibility
Defines the advanced options of borders, arrows, lines, and paths drawn with the Pen or Pencil tools.
- IsEnabled: bool =
False
- if an advanced option is enabled. - LineCap: LineCap =
Butt
- defines the shape of line caps. - LineJoin: LineJoin =
Miter
- defines the appearance of line folds. - Dash: float[] - defines the size of dashes.
Colors stored in the document (color picker > dropdown list (global) > document).
- Id: GUID - unique color asset ID.
- Name: string - color asset name.
- Color: Color =
00000000
- color value.
Color variables stored in the document.
- Id: GUID - unique color variable ID.
- Name: string - color variable name.
- Value: Color =
00000000
- color value of the variable.
Defines column settings in a layout grid.
- Enabled: bool =
False
- if columnns are enabled. - Align: LayoutHorizontalAlignment =
Left
- horizontal alignment settings. - Offset: int =
0
- offset value. - Count: int =
0
- number of columns. - Gutter: int =
0
- gutter value. - Width: int =
0
- column width. - Color: Color =
00000000
- column color.
The document's .json structure.
- Id: GUID - unique document ID.
- Nudge: Point =
[1,10]
- nudge Amount. X - small nudge. Y = large nudge. - FromFigma: bool =
False
- if the document is imported from Figma. - CurrentPageIndex: int =
0
- index of the currently open page. - Images: string[] - images stored in the document.
- Colors: ColorAsset[] - colors stored in the document (color picker > dropdown list (global) > document).
- Gradients: GradientAsset[] - gradients stored in the document (color picker > dropdown list (global) > document).
- Fonts: Font[] - embedded fonts stored in the document.
- ColorVariables: ColorVariable[] - color variables stored in the document.
- Styles: SharedStyle[] - styles stored in the document.
- Pages: GUID[] - list of document pages.
Sketch compatibility
- ColorSpace: ColorSpace =
Unmanaged
- сolor scheme the document uses.
Export settings.
- Size: float =
0
- defines the width/height of the exported object. Valid only when ScaleType is Width or Height. - Format: string =
png
- export format. Default: PNG. - Name: string - user-defined suffix/preffix (string) added to the export file name. Default: empty.
- Naming: NamingScheme =
Suffix
- defines whether a suffix or preffix will be added to the export files name. Default: suffix. - Scale: float =
1
- defines the scale used when exporting an object. Valid only when ScaleType is set to Scale. - Type: ScaleType =
Scale
- defines the scale type: Scale(px)/Width/Height. The Width and Height types are currently not supported.
Defines the fill applied to a layer.
- Enabled: bool =
False
- if a fill is added. - Color: Color =
00000000
- fill color. - ColorId: GUID? - color variable ID.
- Type: FillType =
Color
- defines the fill type. - Opacity: float =
0
- defines the fill opacity. - BlendMode: BlendMode =
Normal
- defines the blend mode. - Pattern: Pattern - contains pattern fill properties in case the fill is a pattern fill.
- Gradient: Gradient - contains gradient properties in case the fill is a gradient.
Embedded fonts stored in the document.
- Data: string - name of the font file in the fonts folder.
- Name: string - font name.
- FileName: string - font file name.
- PostscriptNames: string[] - postScript names of the font.
An object that represents a gradient.
- Type: GradientType =
Linear
- type of the gradient. - From: Point =
[0,5,0]
- position of the gradient start point. - To: Point =
[0,5,1]
- position of the gradient end point. - Side: Point =
[0,0]
- position of the gradient side point. Valid for radial and angular gragients. - Stops: GradientStop[] - list of other gradient points.
Gradients stored in the document (color picker > dropdown list (global) > document).
A position-color pair representing a gradient stop.
- Pos: float =
0
- value between 0 and 1 representing a position along gradient axis. - Color: Color =
ffffffff
- color attached to a corresponding position.
Defines square grid settings for a frame.
- Enabled: bool =
False
- if the square grid is enabled. - Color: Color =
00000000
- grid color. - Size: int =
10
- size of grid cells.
Sketch compatibility
- ThickTimes: int =
10
- every N line should be thick.
Defines filters that can be applied to images.
- Enabled: bool =
False
- if a filter is applied to the image layer. - Brightness: float =
0
- brightness filter. - Contrast: float =
1
- contrast filter. - Hue: float =
0
- hue filter. - Saturation: float =
1
- saturation filter.
Style (bold, italic, etc.) applied to a part of text or single word within a text block.
- Start: int =
0
- position where the style starts. - Length: int =
0
- length of the selection. - Style: TextStyle - style applied to the selection.
Contains metadata about the document.
- Version: int =
0
- free Format version. - App: string - app name.
- Variant: string - app variant: beta/standalone/store/web/etc.
- AppVersion: string - app version.
Defines overrides for components.
- ComponentId: GUID? - unique component identifier.
- Image: string - defines the image name used as a fill.
- Link: string - defines the target frame (prototyping).
- Locked: bool? - if the layer is locked for editing.
- Hidden: bool? - if the layer is hidden.
- ClipContent: bool? - if the clip content feature is enabled.
- LockAspect: bool? - if the aspect ratio is locked.
- Ratio: float? - defines the star ratio value.???
- VertexCount: float? - the number of vertices.
- ArcAngle: float? - end angle for donuts measured clockwise from the X axis.
- ArcRatio: float? - inner radius for donuts.
- ArcStartAngle: float? - start angle for donuts measured clockwise from the X axis.
- CornerRadius: float[] - corner radius value.
- SmoothCorners: bool =
False
- if smooth corners are enabled. - StyleId: GUID? - identifier of the style applied to a layer.
- Tint: Color? - defines the tint color.
- TintId: GUID? - tint identifier.
- BorderOptions: BorderOptions - definition of border options.
- Blur: BlurEffect - information about blurs.
- ImageFilters: ImageFilters - filters applied to an image (hue, saturartion, etc.), if any.
- Opacity: float? - opacity value.
- BlendMode: BlendMode? - blend mode.
- StartArrowhead: Arrowhead? - determines the appearance of the tail of an open path drawn with the Line, Arrow, or Pen/Pencil tool.
- EndArrowhead: Arrowhead? - determines the appearance of the head of an open path drawn with the Line, Arrow, or Pen/Pencil tool.
- Text: string - content of the text layer.
- TextStyle: TextStyle - style applied to the text
- TextBehavior: TextBehavior? - behavior of the text layer size on text value change: flexible, fixed-width, or fixed.
- Size: Size? - text size.
- Orientation: LayoutOrientation? - layout orientation: horizontal or vertical.
- Spacing: float? - spacing value
- WrapSpacing: float? - spacing between rows of wrapped content.
- MinWidth: float? - defines the minimum layer width (auto layout).
- MinHeight: float? - defines the minimum layer height (auto layout).
- MaxWidth: float? - defines the maximum layer width (auto layout).
- MaxHeight: float? - defines the maximum layer height (auto layout).
- Padding: Thickness? - padding value.
- Align: HorizontalAlignment? - horizontal children alignment.
- VAlign: VerticalAlignment? - vertical children alignment.
- Sizing: SizingMode? - horizontal resizing mode: fixed or hug.
- VSizing: SizingMode? - vertical resizing mode: fixed or hug.
- TextBaseline: bool? - if text baseline alignment is enabled.
- StrokesIncluded: bool? - if the Include Borders option is enabled.
- ReverseZIndex: bool? - if the Last on Top option is enabled.
- Stretch: bool? - determines if the layer should stretch along the parent’s counter axis (auto layout).
- GrowStretch: bool? - determines whether a layer should stretch along the parent’s primary axis (auto layout).
- Wrap: bool? - if wrapping is enabled.
- WrapDistribute: bool? - if auto distribute is enabled for wrapped content.
Sketch compatibility
- LegacyColor: ColorOverride - color override.
- LegacyTextColor: TextColorOverride - text color override.
- LegacyTextWeight: TextWeightOverride - text weight override.
Document page properties.
- Id: GUID - unique page ID.
- Name: string - page name.
- Background: Color =
00000000
- canvas color. - IsComponentPage: bool =
False
- if the page is used to store components. - Rulers: Rulers - rulers applied by the user.
- Origin: Point =
[0,0]
- point where the user left off the page. - Zoom: float =
0
- zoom scale last applied to the page. - Layers: Layer[] - list of layers in the page.
Defines the image fill options.
- Type: PatternFillType =
Fill
- defines the fill type: tile, fill, stretch, fit, or crop. - Image: string - defines the image name used as a fill.
- Rotation: float =
0
- image rotation value, in degrees. Applicable to all types, except for crop. - TileScale: float =
1
- tile scale value. Applicable to the tile type only. - Transform: Matrix? - defines how the image is cropped. Applicable to the crop type only.
This is a frame preset. Also used to determine viewport size for a large frame to scroll it properly.
- Id: GUID - unique frame identifier.
- Name: string - frame name.
- Size: Size =
[0,0]
- frame size. - LibraryId: GUID - library identifier.
Defines row settings in a layout grid.
- Enabled: bool =
False
- if rows are enabled. - Align: LayoutVerticalAlignment =
Top
- vertical alignment settings. - Offset: int =
0
- offset value. - Count: int =
0
- number of rows. - Gutter: int =
0
- gutter value. - Width: int =
0
- row width. - Color: Color =
00000000
- row color.
An object containing ruler origins and guideline positions.
- Guides: int[] - positions of vertical guidelines on the Horizontal Ruler.
- VGuides: int[] - positions of horizontal guidelines on the Vertical Ruler.
Sketch compatibility
- Origin: Point =
[0,0]
- ruler origin. Not supported in Lunacy. Sketch Compatibility
Defines the shadow options.
- Enabled: bool =
True
- if a shadow effect is enabled. - Radius: float =
0
- radius of the shadow blur. - Color: Color =
00000000
- shadow color. - ColorId: GUID? - color variable ID.
- Spread: float =
0
- shadow spread value. - Offset: Point =
[0,0]
- how far the shadow is projected in the x and y directions. - Opacity: float =
0
- shadow opacity. - BlendMode: BlendMode =
Normal
- shadow blend mode.
Contains components, styles and variables from external library that is used in current document. Every file in the shared folder is Shared Library.
- Id: GUID - unique library document identifier.
- ColorVariables: ColorVariable[] - color variables from a shared library.
- Styles: SharedStyle[] - styles from a shared library.
- Components: Component[] - components from a shared library.
Style saved in the document.
Defines a set of properties that make up a style.
- MiterLimit: int =
10
- defining a limit on the ratio of the miter length to the border thickness used to draw a miter join. - Opacity: float =
1
- opacity of a layer. - BlendMode: BlendMode =
Normal
- blend mode: how a layer blends with the layers behind it. - StartMarker: Arrowhead =
None
- defines the appearance of the starting point for arrows, lines, and open paths. - EndMarker: Arrowhead =
None
- defines the appearance of the end point for arrows, lines, and open paths. - Winding: PathFillType =
EvenOdd
- fill options for overlapping paths: non-zero or even-odd. - Fills: Fill[] - list of fills applied to a layer.
- Borders: Border[] - list of borders applied to a layer.
- Shadows: ShadowEffect[] - list of shadows applied to a layer.
- InnerShadows: ShadowEffect[] - list of inner shadows applied to a layer.
- Blur: BlurEffect - definition of the blur effect applied to a layer.
- BorderOptions: BorderOptions - definition of border options.
- ImageFilters: ImageFilters - image filters applied to a layer.
Defines a set of properties that make up a text style.
- Color: Color =
ff000000
- text color. - ColorId: GUID? - color variable ID.
- Font: string =
Inter
- text font. - Size: float =
12
- text size. - ParagraphSpacing: float =
0
- paragraph spacing. - Kerning: float =
0
- letter spacing. - BaselineOffset: float =
0
- text offset from the baseline. - LineHeight: float? - line spacing.
- Casing: CharacterCasing =
Normal
- character case. - Align: TextHorizontalAlignment =
Left
- horizontal alignment applied to the text. - Valign: TextVerticalAlignment =
Top
- vertical alignment applied to the text. - List: ListMarkerType =
None
- list type: numbered, bulleted, none. - RTL: bool =
False
- if the text is RTL. - Underline: bool =
False
- if the text is underlined. - Strikethrough: bool =
False
- if the strikethrough option is applied to the text. - BaselinePos: BaselinePosition =
Normal
- text position against the baseline.
Defines layout grid settings for a frame.
Defines an auto layout.
- _t: string =
AUTO
32-bit ARGB unpremultiplied color value.
- Alpha: byte =
0
- gets the alpha component of the color. - Red: byte =
0
- gets the red component of the color. - Green: byte =
0
- gets the green component of the color. - Blue: byte =
0
- gets the blue component of the color.
A transformation matrix is standard way in computer graphics to represent translation and rotation. These are the top two rows of a 3x3 matrix. The bottom row of the matrix is assumed to be [0, 0, 1]. This is known as an affine transform and is enough to represent translation, rotation, and skew. The identity transform is [1, 0, 0, 0, 1, 0]. A translation matrix will typically look like: [1, 0, tx, 0, 1, ty] and a rotation matrix will typically look like: [cos(angle), -sin(angle), 0, sin(angle), cos(angle), 0] If a matrix contains only translation it will be printed like point [0,5]
- ScaleX: float - scale by x-coord. Usually should be 1. If it's -1 - the layer is flipped horizontally. If it's some random number - it's a cos(angle).
- SkewX: float - skew by x-coord. Usually should be 0. If it's some random number - it's a -sin(angle).
- TransX: float - translation by x-coord.
- SkewY: float - skew by y-coord. Usually should be 0. If it's some random number - it's a sin(angle).
- ScaleY: float - scale by y-coord. Usually should be 1. If it's -1 - the layer is flipped vertically. If it's some random number - it's a cos(angle).
- TransY: float - translation by y-coord.
A utility class to represent a point.
A utility class to represent a rectangle.
- Left: float - the x coordinate of the top-left corner of the rectangle.
- Top: float - the y coordinate of the top-left corner of the rectangle.
- Width: float - the width of the rectangle.
- Height: float - the height of the rectangle.
A utility class to represent layer size.
Thickness struct. Used for Border thickness and Padding values
A utility class to represent a vertex.
- Point: Point =
[0,0]
- base point of a vertex - From: Point =
[0,0]
- first control point, curve from. - To: Point =
[0,0]
- second control point, curve to. - Radius: float - corner radius of a vertex point. It's stored in half because we don't need that much precision for corner radius.
- Flags: VertexFlags =
None
- vertex flags, including: CurveMode, hasFrom, hasTo, and CornerStyle.
Defines animation types in prototypes.
-1
None0
FromRight1
FromLeft2
FromBottom3
FromTop
Defines the appearance of arrowheads.
0
None - no arrowheads.1
Arrow - angle.2
ArrowFilled - triangle.3
Line - perpendicular Line.4
Circle - cirlce arrowhead.5
CircleFilled - filled circle arrowhead.6
Square - square arrowhead.7
SquareFilled - filled square arrowhead.
Defines text position against the baseline.
0
Normal - text is aligned with the baseline.1
Superscript - text is raised above the baseline.-1
Subscript - text is lowered below the baseline.
Defines the type of blend mode applied to a layer.
0
Normal1
Darken2
Multiply3
ColorBurn4
Lighten5
Screen6
ColorDodge7
Overlay8
SoftLight9
HardLight10
Difference11
Exclusion12
Hue13
Saturation14
Color15
Luminosity16
PlusDarker17
PlusLighter
Defines the blur type.
0
Gaussian - gaussian blur.1
Motion - motion blur. Currently not supported. // Sketch Compatibility2
Zoom - zoom blur. Currently not supported. // Sketch Compatibility3
Background - background blur.
Types of boolean operations used to combine shapes.
-1
None - not set. Works like Difference or like Union depending on the context.0
Union - creates a shape from the sum of the areas of the selected shapes.1
Subtract - the opposite of Union. Removes the overlapping area(s) from the shape layer at the bottom of the selection.2
Intersect - the resulting shape only includes the area where all selected shapes overlap.3
Difference - the opposite of Intersect. Creates a shape from the areas where the selected shapes do not overlap.
Defines the border postion.
0
Center - center.1
Inside - inside.2
Outside - outside.
Defines letter case.
0
Normal - normal letter case.1
UpperCase - upper case.2
LowerCase - lower case.3
TitleCase - title case.
Types of components. Currently used for filtering only. Some of the types are not supported yet.
0
None10
Button11
RadioButton12
CheckBox13
Toggle14
ToggleButton15
SpinButton16
SplitButton17
SpeedDial18
SocialButton40
TextInput41
TextArea42
TextEditor43
NumberInput44
DateInput45
TimeInput46
DateTimeInput47
PasswordInput48
SearchBar49
DropDownInput70
DropDown71
ProgressBar72
Slider73
Knob74
Rating75
ScrollBar76
Paginator77
Preloader80
NavigationBar81
StatusBar82
ToolBar83
SideBar90
MenuBar91
ContextMenu92
MenuItem100
Breadcrumbs101
List102
ListItem103
Tree104
TreeItem105
TabStrip106
TabItem110
Table111
TreeTable112
TableHeader113
TableRow114
TableCell120
Window121
Dialog122
Popup123
ToolTip124
Notification125
Toast126
Message130
Avatar131
Badge132
Chip133
Skeleton134
Tag135
Card136
DropArea137
Ad140
Expander141
Splitter142
Carousel143
GroupBox150
Map151
Browser152
Calendar153
ColorPicker154
MediaPlayer155
ImageGallery156
Timeline157
Graph158
Diagram159
SourceCode160
Barcode161
Gauge162
Captcha200
Keyboard201
Cursor202
DeviceFrame
Defines the types of points on Bézier curves.
0
None - undefined.1
Straight - straight.2
Mirrored - mirrored.3
Asymmetric - asymmetric.4
Disconnected - disconnected.
Defines the fill type.
0
Color - solid color fill.1
Gradient - gradient fill.4
Pattern - image fill.
List of Gradient types.
0
Linear - linear gradient: two colors appear at opposite points of an object and blend, or transition into each other.1
Radial - radial gradient: the transition between color stops is a circular pattern.2
Angular - angular gradient: sweeps around the circumference.
Defines how a set of layers is aligned horizontally.
0
Left - layers are aligned to the left.1
Center - layers are horizontally centered.2
Right - layers are aligned to the right.3
Distribute - layers are horizontally justified.
Defines horizontal alignment settings in layout grids.
0
Left1
Center2
Right3
Stretch
Orientation of an auto layout.
0
Horizontal - horizontal orientation.1
Vertical - vertical orientation.
Defines vertical alignment settings in layout grids.
0
Top1
Middle2
Bottom3
Stretch
Defines the shape of the end caps of open paths drawn with the Line, Arrow, or Pen/Pencil tools.
0
Butt - no cap (default).1
Round - adds a rounded end to a path that extends past the vector point.2
Square - similar to the rounded cap, but with straight edges.
Defines the appearance of the corners for arrows and paths with corners drawn with the Pen/Pencil tool.
0
Miter - square.1
Round - rounded.2
Bevel - bevelled.
Defines the type of a text list.
0
None - list without markers.1
Bullet - bulleted list.2
Numbered - numbered list.
Defines the filling options for overlapping paths.
0
Winding - applies the non-zero rule.1
EvenOdd - apllies the even-odd rule.
Defines the image fill type.
0
Tile - duplicates the image in a tile pattern to fit the layer. The size of tiles is adjustable.1
Fill - adjusts the image size to the layer’s width.2
Stretch - stretches the image to fit the layer’s width and height.3
Fit - adjusts the image size to fit the layer’s height.4
Crop - crops the image at user's discretion.
Defines the scale type for exported objects.
0
Scale1
Width2
Height
Defines the behavior of auto layout containers as their content is changed.
0
Auto - the container adjusts to the size of the content (hug).1
Fixed - the container has a fixed size (fix).
Defines textbox behavior options.
1
AutoHeight - the width of the textbox is fixed. Characters wrap to fit in the textbox. The height of the textbox automatically adjusts to fit its content.2
Fixed - the size of the textbox is fixed and is independent of its content.0
Flexible
Defines how a text is aligned horizontally.
0
Left - text is aligned to the left.1
Right - text is aligned to the right.2
Center - text is horizontally centered.3
Justify - text is horizontally justified.
Defines how a text is aligned vertically.
0
Top - text is aligned to the top.1
Middle - text is vertically centered.2
Bottom - text is aligned to the bottom.
Defines vertex flags.
0
None1
Mirrored2
Asymmetric3
Disconnected4
HasCurveFrom8
HasCurveTo
Sketch compatibility
16
RoundedInverted32
Angled48
Squared
Defines how a set of layers is aligned vertically.
0
Top - layers are aligned to the top.1
Center - layers are vertically centered.2
Bottom - layers are aligend to the bottom.3
Distribute - layers are vertically justified.
Information about auto generated texts. //Lunacy Specific
- Type: DataType =
Unknown
- category of generated text (person, address, date, etc.). - Field: DataFieldType =
Unknown
- type of generated text (full name or first name, city or ZIP code, etc.). - Format: string - format for Data Type. Used for Date/Time values.
Background removal procedure info. //Lunacy Specific
0
None1
InProgress2
Done3
Failed
Defines the type of generated text. //Lunacy Specific
0
Unknown1
FullName2
FirstName3
LastName4
Phone5
Email6
FullAddress7
State8
City9
ZipCode10
Theme11
Header12
Paragraph13
Company14
Department15
JobTitle16
Amount17
CreditCard18
Day19
DayOfWeek20
Year21
Month22
DateSlash23
DateDot24
DateFull25
Time1226
Time2427
Country28
Language29
Url30
UserName31
FileName
Defines the category of generated text. //Lunacy Specific
0
Unknown1
Address2
Article3
Business4
Country5
Date6
Language7
Person8
Technology9
Time
Defines color overrides for components. //Sketch Compatibility
- Color: Color =
00000000
- color value. - ColorId: GUID? - color variable ID.
- Property: ColorOverrideType =
Unknown
- color override type: none, fill, border, shadow, or inner shadow. - Index: int =
0
- fill index. Starts from 0.
Defines overlay settings. //Sketch Compatibility
- Offset: Point =
[0,0]
- OverlayAnchor: Point =
[0,0]
- OverlayType: OverlayType =
0
- SourceAnchor: Point =
[0,0]
Sketch Group Layout Properties //Sketch Compatibility
- Axis: GroupLayoutAxis =
Horizontal
- layout Orientation - LayoutAnchor: GroupLayoutAnchor =
Begin
- layout Align - MaxSize: float =
0
- maximum Container Size - MinSize: float =
0
- minimum Container Size
Defines text color overrides for components. //Sketch Compatibility
Defines text weight overrides for components. //Sketch Compatibility
Defines types of color overrides for components. //Sketch Compatibility
0
Unknown1
Fill2
Border3
Shadow4
InnerShadow
Сolor scheme the document uses. //Sketch Compatibility
0
Unmanaged1
sRGB2
P3
Sketch legacy, not supported in Lunacy //Sketch Compatibility
0
Rounded1
RoundedInverted2
Angled3
Squared
Layout alignment on axis. For vertical it's: left, center or right. For horizontal: top, middle or bottom. //Sketch Compatibility
0
Begin1
Middle2
End
Group Layout Orientation //Sketch Compatibility
0
Horizontal1
Vertical
Controls the use of suffixes/prefixes in the names of export files. //Sketch Compatibility
0
Suffix - indicates that the file name comes with a user-defined suffix.1
SecondaryPrefix - indicates that the file name comes with a user-defined prefix.2
PrimaryPrefix - indicates that the file name comes with a user-defined prefix.
Overlay-background interaction options. //Sketch Compatibility
0
None1
CrossOverlay2
AllowAll
Defines overlay types. //Sketch Compatibility
1
Screen2
Layer
Link
property is replaced byFlows
list of prototyping interactions.
Shared.json
is removed. Now all shared libraries data have a new efficient structure and can be found insideshared
folder. Separate file is created for every library source - this will significantly increase document open speed in multithreaded way if document use a lot of components from different shared libraries.- Now
SharedStyle
s are not grouped by text/layer category. All in one container. To check if style is text style - check if it has textTextStyle
property. Export
optimized to be a simple list ofExportOption
. Some sketch-related fields removed.
- Initial Version
by Icons8 LLC 2023