NapukinNapukin
What is Napukin?
  • Welcome
  • Installing the PWA
  • Using Napukin
  • openNapkin File Format
  • npkd Specification
  • Credits & Licenses
FAQ
Roadmap
Changelog
GitHub
What is Napukin?
  • Welcome
  • Installing the PWA
  • Using Napukin
  • openNapkin File Format
  • npkd Specification
  • Credits & Licenses
FAQ
Roadmap
Changelog
GitHub
  • Documentation

    • openNapkin File Format (.npkd)
    • .npkd File Format Specification
    • Credits & Licenses

.npkd File Format Specification

Version: 1
Application: Napukin (openNapkin)


1. File Structure

A .npkd file is a ZIP archive using STORE compression (no deflation). It contains:

├── manifest.json       (required)
├── document.json       (required)
├── thumbnail.png       (optional)
└── assets/             (required, may be empty)
    ├── <id>.png
    ├── <id>.jpg
    └── ...

The STORE compression mode means files are stored uncompressed inside the ZIP. This keeps the format simple and makes the JSON contents accessible to tools that can parse ZIP entries without decompression.

The MIME type is application/zip. The file extension is .npkd.


2. manifest.json

{
  "app": "Napukin",
  "version": 1,
  "name": "My Design",
  "createdAt": 1711900000000
}
FieldTypeDescription
appstringAlways "Napukin"
versionintegerFormat version, currently 1
namestringHuman-readable document name
createdAtintegerUnix timestamp in milliseconds (Date.now())

3. document.json

Top-Level Structure

{
  "name": "My Design",
  "version": 1,
  "artboardWidth": 393,
  "artboardHeight": 852,
  "artboardFill": true,
  "artboardFillColor": "#ffffff",
  "layers": [],
  "comments": [],
  "assetManifest": []
}
FieldTypeDescription
namestringDocument name (matches manifest)
versionintegerFormat version, currently 1
artboardWidthnumberArtboard width in pixels
artboardHeightnumberArtboard height in pixels
artboardFillbooleanWhether the artboard has a background fill (default true)
artboardFillColorstringArtboard background color as hex string (default "#ffffff")
layersarrayOrdered list of layer objects (bottom to top)
commentsarrayList of comment objects
assetManifestarrayReserved for future use, currently []

Standard Artboard Sizes

DeviceWidthHeight
iPhone 17393852
iPhone 17 Pro402874
iPad Mini 77441133
iPad Pro 11"8341194
MacBook Air M51470956
MacBook Pro M51512982
MacBook Neo1280800
FHD 1080p19201080
4K UHD38402160

Custom sizes are supported — any positive integer width and height.


4. Coordinate System

  • (0, 0) is the top-left corner of the artboard.
  • X increases to the right, Y increases downward.
  • All coordinates are in world space (absolute pixels, not relative to a parent).
  • Layers can extend beyond artboard boundaries.
  • Rotation is in radians, clockwise, around the layer's center point.

5. Layer IDs

Every layer and comment has a unique string id in this format:

el_<timestamp_base36>_<counter_base36>

Example: el_m1a2b3c_1, el_m1a2b3c_2, el_m1a2b3c_a

  • The timestamp prefix is a base-36 encoding of a millisecond timestamp.
  • The counter suffix increments in base 36: 1, 2, ... 9, a, b, ... z, 10, 11, ...
  • All IDs within a document must be unique across layers, group children, and comments.

6. Layer Types

There are 11 layer types: rectangle, ellipse, line, arrow, star, polygon, triangle, text, image, path, group.

6.1 Common Properties

Every layer object includes these properties:

PropertyTypeDefaultDescription
idstring—Unique layer ID
typestring—One of the 11 layer types
namestringCapitalized typeDisplay name
xnumber0Left edge X position (world coords)
ynumber0Top edge Y position (world coords)
widthnumber100Width in pixels
heightnumber100Height in pixels
rotationnumber0Rotation in radians, clockwise, around center
flipXbooleanfalseFlip layer horizontally
flipYbooleanfalseFlip layer vertically
opacitynumber1Overall opacity (0–1)
visiblebooleantrueWhether the layer is rendered
lockedbooleanfalseWhether the layer is locked from editing
aspectLockedbooleanfalseWhether aspect ratio is locked on resize
fillstring"#cccccc"Fill color (hex string or "transparent")
fillEnabledbooleantrueWhether the fill is rendered
fillOpacitynumber1Fill opacity (0–1)
strokestring"#333333"Stroke color (hex string or "transparent")
strokeEnabledbooleantrueWhether the stroke is rendered
strokeOpacitynumber1Stroke opacity (0–1)
strokeWidthnumber1Stroke width in pixels
strokeAlignstring"center"Stroke alignment: "center", "inside", or "outside"
strokeJoinstring"miter"Stroke line join: "miter", "round", or "bevel"
cornerRadiusnumber0Corner rounding in pixels

All properties must be present on every layer — there are no optional common properties.

6.2 Rectangle

The default shape. Used for buttons, cards, containers, input fields, backgrounds, etc.

  • cornerRadius rounds all four corners equally, clamped to half the smaller dimension.
  • For a pill/capsule shape, set cornerRadius to half the height.

Optional cover image properties:

PropertyTypeDefaultDescription
imageAssetIdstring | nullnullID of an asset in the assets/ folder to display as a cover image
imageNamestring | nullnullOriginal filename of the cover image
imageHiddenbooleanfalseWhether the cover image is temporarily hidden

When imageAssetId is set, the image is rendered inside the shape using object-fit: cover (centered, cropped to fill, maintaining aspect ratio).

6.3 Ellipse

For circular or oval shapes — avatars, status indicators, radio buttons.

  • For a perfect circle, set width equal to height.
  • Use aspectLocked: true to maintain the ratio.
  • Supports the same optional cover image properties as Rectangle (imageAssetId, imageName, imageHidden).

6.4 Line

Horizontal or angled lines — dividers, separators, underlines.

  • fill must be "transparent".
  • The line draws from (x, y) to (x + width, y + height).
  • height: 0 produces a horizontal line.
  • strokeWidth is the line thickness.
  • cornerRadius > 0 enables rounded line caps.

6.5 Arrow

Same as line, but with an arrowhead at the end point.

  • fill must be "transparent".
  • Arrowhead is drawn at (x + width, y + height).
  • Arrowhead size: min(14, lineLength * 0.3).

6.6 Star

Multi-pointed star shape.

Additional properties:

PropertyTypeDefaultDescription
pointsinteger5Number of outer points
  • Inner radius ratio is fixed at 0.4.
  • Oriented with one point facing up.

6.7 Polygon

Regular polygon with configurable sides.

Additional properties:

PropertyTypeDefaultDescription
sidesinteger6Number of sides

6.8 Triangle

Shortcut for a 3-sided polygon.

Additional properties:

PropertyTypeDefaultDescription
sidesinteger3Always 3

6.9 Text

Text labels, headings, body text, button labels.

Additional properties:

PropertyTypeDefaultDescription
textstring"Text"The text content
fontSizenumber16Font size in pixels
fontFamilystring"Roboto, sans-serif"Font family
fontWeightstring"normal""normal", "bold", or "100"–"900"
textAlignstring"left""left", "center", or "right"

Available font families:

  • "Roboto, sans-serif" (default)
  • "Poppins, sans-serif"
  • "Merriweather, serif"
  • "Caveat, cursive"
  • "Dancing Script, cursive"
  • "Shadows Into Light Two, cursive"
  • "Roboto Mono, monospace"
  • "BLOKK Neue, sans-serif" (wireframe placeholder font)

Any CSS font-family string is accepted in the format; the above are the fonts bundled with the application.

Rendering rules:

  • fill is the text color (not a background — default "#000000").
  • stroke must be "transparent" and strokeWidth must be 0.
  • Text wraps within the layer's width.
  • Line height is fontSize × 1.3.
  • Layer height should be approximately (number of lines) × fontSize × 1.3.

6.10 Path

Custom vector paths drawn with the Pen or Pencil tools — freehand sketches, bezier curves, custom shapes.

Additional properties:

PropertyTypeDefaultDescription
pathPointsarray[]Ordered list of anchor point objects
closedbooleanfalseWhether the path forms a closed shape

Each anchor point object:

PropertyTypeDescription
xnumberX position relative to the layer's origin
ynumberY position relative to the layer's origin
cp1xnumberIncoming bezier control point X offset from anchor
cp1ynumberIncoming bezier control point Y offset from anchor
cp2xnumberOutgoing bezier control point X offset from anchor
cp2ynumberOutgoing bezier control point Y offset from anchor

Rendering rules:

  • Segments between anchor points are straight lines when both control point offsets are (0, 0), otherwise cubic bezier curves.
  • When closed is true, a closing segment connects the last point back to the first (with bezier handles if present), and the path is filled.
  • When closed is false, fill defaults to "transparent" (stroke only).
  • Line cap is round. The strokeJoin property defaults to "round" for paths (vs "miter" for other layer types).
  • The layer's x, y define the origin — each point's x, y are relative to this origin.
  • The layer's width and height are the bounding box of all anchor points.

6.11 Image

Displays an embedded image from the assets/ folder.

Additional properties:

PropertyTypeDefaultDescription
assetIdstring | nullnullID of the asset in the assets/ folder

Rendering rules:

  • fill and stroke are both "transparent", strokeWidth is 0.
  • When assetId is null, renders as a light gray rectangle with an X through it (placeholder).
  • Use aspectLocked: true to maintain image proportions.

6.12 Group

Contains other layers as children.

Additional properties:

PropertyTypeDefaultDescription
childrenarray[]Ordered list of child layer objects

Rules:

  • fill and stroke are "transparent", strokeWidth is 0.
  • The group's x, y, width, height must be the bounding box of its children:
    • x = min of all children's x
    • y = min of all children's y
    • width = max(child.x + child.width) − min(child.x)
    • height = max(child.y + child.height) − min(child.y)
  • Children use absolute world coordinates, not positions relative to the group.
  • Groups can be nested.

7. Layer Ordering

Layers in the layers array are rendered bottom to top — index 0 is drawn first (behind everything), and the last element is drawn on top.


8. Comments

Comments are stored separately from layers and appear as numbered pins on the canvas.

{
  "id": "el_abc123_b",
  "x": 200,
  "y": 400,
  "text": "Revisit this button style",
  "resolved": false,
  "createdAt": 1711900000000
}
PropertyTypeDescription
idstringUnique ID (same format as layers)
xnumberX position on the artboard
ynumberY position on the artboard
textstringComment body
resolvedbooleanWhether the comment is resolved
createdAtintegerUnix timestamp in milliseconds

9. Assets

Image files are stored in the assets/ folder with filenames in the format <assetId>.<ext> (e.g., a1b2c3.png).

Image layers reference their asset by assetId. The extension is determined by the original file's type.

The assetManifest field in document.json is reserved for future use and should be an empty array [].


10. Thumbnail

On save, the application generates a thumbnail.png in the ZIP root. This is a downscaled PNG rendering of the artboard, fitting within 400×300 pixels while preserving aspect ratio.

The thumbnail is optional — readers should not depend on it being present. It's intended for use by file browsers, galleries, or preview UIs.


11. Implementation Notes

Reading .npkd Files

  1. Open the file as a ZIP archive.
  2. Parse manifest.json — verify app === "Napukin" and check version.
  3. Parse document.json — read artboard dimensions, iterate layers.
  4. Load assets from the assets/ folder as needed (match by assetId).
  5. Optionally read thumbnail.png for preview display.

Writing .npkd Files

  1. Create a ZIP archive with STORE compression (no deflation).
  2. Add manifest.json with app metadata.
  3. Add document.json with the full document model.
  4. Add an assets/ folder containing any embedded images.
  5. Optionally render the artboard to a downscaled PNG and add as thumbnail.png.
  6. Save with the .npkd extension.

Generating .npkd from Code

Since the format is JSON inside an uncompressed ZIP, any language with a ZIP library can produce valid .npkd files. The minimum viable file contains:

  • manifest.json with app, version, name, and createdAt
  • document.json with name, version, artboardWidth, artboardHeight, layers (can be []), comments ([]), and assetManifest ([])
  • An empty assets/ folder

Known Consumers

  • Napukin (openNapkin) — the primary editor
Prev
openNapkin File Format (.npkd)
Next
Credits & Licenses