image-to-code locks a 750px artboard and makes the PNGs bigger, never the layout
Codex skill for 750px image-to-code reconstruction and transparent PNG slicing
At a glance
- What is it?
- A Codex skill that reconstructs a UI image as code plus sliced transparent PNG assets, with a manifest as the single source of truth for layout, slicing and a later Figma import. The 750px baseline is a measurement grid for QA, and the responsive fit happens in an outer wrapper.
- Who is it for?
- This suits anyone rebuilding a fixed-width mobile design where text has to stay editable and icons have to come out as clean transparent assets. It does not suit responsive work that genuinely needs a reflowing layout, because the skill forbids moving a layer once its 750px coordinate is set.
- 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 113 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 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A Codex skill that constrains a task, not a converter
image-to-code is not a template and not a redesign tool. It is a workflow installed into Codex that constrains the measurement, slicing, code, responsive fitting, QA and Figma import stages of turning one image back into code. The input is a selected UI image, a screenshot or a Figma export.
Installation is a directory move plus one pip command:
python3 -m pip install -r requirements.txtThe directory goes to ~/.codex/skills/image-to-code, and the declared script dependencies are Pillow and NumPy. It is invoked either by naming the skill in Codex or by describing the job in plain language, for instance asking for a mobile design to be restored as HTML and CSS that fits phone widths, with icons and illustrations cut as separate transparent PNGs at 2x or 3x and kept importable to Figma.
750px is a measurement grid, not the page width
Everything is measured against a 750px baseline because a fixed grid makes review possible later. One scale factor is derived from the source width and then applied to coordinates, sizes, corner radii, strokes, shadows, fonts and gradient positions alike:
scale = 750 / source_width
baseline_width = 750
baseline_height = round(source_height * scale)
scaled_x = source_x * scale
scaled_y = source_y * scale
scaled_width = source_width_of_layer * scale
scaled_height = source_height_of_layer * scaleThe resulting board is what a QA screenshot is taken against. What ships is not that board. A responsive fit wrapper scales it as a whole for mobile viewports between 320px and 430px, for a 375px demonstration width, or for a named container width, and the requirement is explicit that individual layers must not reflow inside it.
The wrapper scales and the children never move
The suggested markup nests a fit shell, a fit box and the artboard itself:
<main class="fit-shell">
<div class="fit-box">
<section class="artboard">...</section>
</div>
</main>The artboard root keeps width 750px and a normalised height, and its children keep the manifest coordinates untouched. Scaling happens on the outside, where the wrapper computes scale as the smaller of 1 and the available width divided by 750. A 375px demonstration therefore lands near 0.5, and the fit box takes the scaled width and height as its own placeholder so unscaled 750px content cannot push the page open. When the target is a parent element rather than the viewport, a ResizeObserver sets the same variable instead. Either way, the scale has to return to 1 for the baseline QA screenshot to mean anything.
The manifest is written before any code
layers.manifest.json is the shared source of truth for the layout, the slicing, the generated code and the later Figma export, and the workflow puts it at step three, ahead of implementation. The instruction against it is blunt: do not write an approximate page first and add the assets afterwards.
Each entry records the identifier, a type, the bounding box in the source image, the same box rebased to 750px, a z-index, the asset path, the real pixel dimensions of the PNG file, the display dimensions in CSS, a scale factor, a transparency flag and free-form notes. Pixel dimensions and display dimensions are kept as separate fields on purpose, and the 2x, 3x or 4x choice never moves anything in the layout.
Two scripts check the manifest against reality. A preview pass draws every box on the source before any asset is cut, and an audit pass walks the asset directories to confirm transparency.
The preview and audit scripts bracket every slice
Boxes go on the source image first, filtered to bitmap layers:
scripts/preview_bboxes.py source.png layers.manifest.json qa/bbox-preview.png --only-type bitmapThe cut itself takes coordinates, a scale factor, display dimensions, a background removal method, the manifest and an id:
scripts/extract_png_asset.py source.png assets/icons/icon-home-01.png \
--x 120 --y 88 --width 32 --height 32 \
--scale-factor 3 \
--css-width 32 --css-height 32 \
--remove-bg floodfill \
--manifest layers.manifest.json \
--id icon-home-01The audit walks three directories and demands transparency:
scripts/audit_png_assets.py assets/icons assets/illustrations assets/images \
--require-transparent-bg \
--manifest layers.manifest.jsonFour findings mean the asset goes back for rework: a missing alpha channel, a failed transparency check, opaque corners, or non-transparent pixels touching the edge. The remedy is to widen the box, cut the background again, or raise the scale factor and re-export.
A 3x PNG does not make the page 3x bigger
The arithmetic tying file size to display size is fixed. The scale factor defaults to at least 2, and pixel width and height are each the display size multiplied by that factor. Code references the file by its CSS display dimensions, so a three-times file sitting in a 32 by 32 slot stays 32 by 32 on screen.
The choice of 3 or 4 is conditional rather than aesthetic. Icons smaller than 64px, a source that is visibly compressed, dirty edges, a background that resists removal, or a result that looks soft on the page are the triggers for stepping up. Two rules protect the pixels: background removal happens on the high-resolution canvas instead of cutting cheaply and enlarging afterwards, and the PNG is never auto-trimmed, since the transparent padding and semi-transparent edges are part of the asset. Icons and illustrations require a transparent background unless the manifest marks them as a photograph, a screenshot or a complete rectangular background.
Figma import is a layer spec, not a pasted screenshot
The export path builds editable structure from the same manifest, the computed styles of the finished code, the CSS tokens and the PNG assets. A frame at 750 by the baseline height keeps its background, clipping and ordering. Text becomes a text node carrying the real characters, font, size, line height, letter spacing, colour, opacity and position. Rectangles, circles, lines, buttons, cards, labels and dividers become native shapes. Bitmaps become separate image fills sized by the manifest display dimensions. A hidden, locked 750px render may be included as a reference layer, which the rules say cannot stand in for a production layer.
The delivery order is a fallback chain. With Figma write permission through MCP, an API or a browser and a target file link from the user, the layers go straight into that file. Without that, the output is a local development plugin importer or a layer spec file. Missing a token is not a reason to stop, since a local importer is treated as a sufficient deliverable. The report names the frame, the layer counts, substituted fonts, what stays uneditable, the reference layer state and where the importer lives.
Acceptance rejects a page that only works at 750px
The final checks are written as refusals. A production page with no adaptive outer layer is not accepted, only a fixed 750px page is not enough. The baseline board has to stay usable for precise review at 750px wide with a height derived from the source ratio. At 375px and at least one other phone width there must be no horizontal scrolling, with scrollWidth not exceeding the viewport by much. Every key element position, size, layer and style has to trace back to the manifest, and the real pixel size of each PNG has to match its scale factor while the displayed size matches the display fields.
The list of acceptance criteria breaks off partway through that final point, so anything stated after it is not visible here. The repository root is small and self-contained: a SKILL.md beside the README, an agents directory, a references directory, a scripts directory, requirements.txt and the licence. The last commit on the main branch is dated 2026-06-10, and no release has ever been tagged.
Editorial conclusion
This suits anyone rebuilding a fixed-width mobile design where text has to stay editable and icons have to come out as clean transparent assets. It does not suit responsive work that genuinely needs a reflowing layout, because the skill forbids moving a layer once its 750px coordinate is set. Before starting, install Pillow and NumPy and be ready to keep the manifest current, since a layer that is not in it has nowhere to be traced to. If Figma output matters, settle the import route early: with write permission and a file link the skill writes directly, and without them it falls back to a local importer plus a layer spec.
Frequently asked questions
Where does the image-to-code skill get installed?
The whole directory goes to ~/.codex/skills/image-to-code in Codex, and its scripts need python3 -m pip install -r requirements.txt, which declares Pillow and NumPy.
Why does image-to-code fix everything to 750px?
750px is the baseline coordinate system used for measurement and QA, not the only final display width. The delivered page adds a fit wrapper that scales the locked artboard to phone or container widths without reflowing individual layers.
Does a 3x PNG change the layout in image-to-code?
No. The asset scale factor multiplies the display size to get the pixel size, and code displays the file at the CSS display dimensions, so 2x, 3x or 4x never changes what the layout occupies.
What does the image-to-code PNG audit fail on?
It flags a missing alpha channel, a failed transparency check, opaque corners, or non-transparent pixels touching the edge. The fix is to widen the bounding box, remove the background again, or raise the asset scale factor and re-export.
How does image-to-code handle Figma without an API token?
It writes into a target file only when write permission and a file link are available. Otherwise it produces a local Figma development plugin importer or a layer spec, and a local importer counts as a sufficient deliverable.
When does image-to-code ask for a 4x asset instead of 2x?
The default is at least 2x. Icons under 64px, a visibly compressed source, dirty edges, a background that resists removal, or a result that looks soft on the page are the reasons to step up to 3x or 4x.
Official sources
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.
[](https://hysenlabs.com/projects/yuzhworkhard-wq-image-to-code)