Slab
stencil-hq/slab
Writing, editing, and rendering Slab documents (.slab) — the declarative design language for app screens, posters, terminal UIs, and interactive components.
Expert guidance for Satori, the library that converts JSX/HTML and CSS into SVG (the engine behind dynamic Open Graph images and social cards).
$ npx skills add usenotra/notra --skill satori -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install usenotra/notra satori --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/usenotra/notra.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/satori .claude/skills/satori && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "satori" agent skill from https://github.com/usenotra/notra/tree/main/.agents/skills/satori into .claude/skills/satori/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "satori", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/usenotra/notra/tree/main/.agents/skills/satoriType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add usenotra/notra --skill satori -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install usenotra/notra satori --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/usenotra/notra.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/satori .agents/skills/satori && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "satori" agent skill from https://github.com/usenotra/notra/tree/main/.agents/skills/satori into .agents/skills/satori/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "satori", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add usenotra/notra --skill satori -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install usenotra/notra satori --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/usenotra/notra.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/satori .cursor/skills/satori && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "satori" agent skill from https://github.com/usenotra/notra/tree/main/.agents/skills/satori into .cursor/skills/satori/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "satori", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/usenotra/notra.git --path .agents/skills/satori--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add usenotra/notra --skill satori -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install usenotra/notra satori --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/usenotra/notra.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/satori .gemini/skills/satori && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "satori" agent skill from https://github.com/usenotra/notra/tree/main/.agents/skills/satori into .gemini/skills/satori/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "satori", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install usenotra/notra satoriInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add usenotra/notra --skill satori -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/usenotra/notra.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/satori .github/skills/satori && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "satori" agent skill from https://github.com/usenotra/notra/tree/main/.agents/skills/satori into .github/skills/satori/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "satori", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add usenotra/notra --skill satori -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install usenotra/notra satori --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/usenotra/notra.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/satori .opencode/skills/satori && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "satori" agent skill from https://github.com/usenotra/notra/tree/main/.agents/skills/satori into .opencode/skills/satori/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "satori", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
satoriExpert guidance for Satori, the library that converts JSX/HTML and CSS into SVG (the engine behind dynamic Open Graph images and social cards).
Satori is an agent skill from usenotra/notra. Expert guidance for Satori, the library that converts JSX/HTML and CSS into SVG (the engine behind dynamic Open Graph images and social cards). Use whenever writing or debugging Satori markup e.g. authoring JSX for OG images, choosing CSS that Satori actually supports, fixing layout that renders wrong, embedding fonts, rendering emoji or images, or resolving Satori errors like "Expected length unit" or unsupported property issues. Reach for this any time someone renders HTML/CSS to SVG or PNG with Satori, even if…
Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/css-support.md`).
It sits in Media & Creative, covering Social media graphics, React components and Embeddings. The repository describes itself as: Notra is a modern GEO tool that asks ChatGPT, Claude and Gemini the questions your buyers ask. See if you show up, who shows up instead and how to fix it. The licence is AGPL-3.0.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 55d4d5d. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript).
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
picsum.photoscdnjs.cloudflare.comunpkg.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Satori loads about 3k tokens when it runs, and up to ~4.6k if it reads all its reference files. Until then it costs about 137 tokens; SKILL.md has 1,411 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from usenotra/notra at commit 55d4d5d, republished under its AGPL-3.0 licence (© usenotra). 1,411 words, ~2,974 tokens.
.claude/skills/satori/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.Satori converts JSX-like HTML and CSS into SVG. It runs its own Flexbox layout engine (the same Yoga engine React Native uses) and handles font shaping and typography, then emits an SVG string that closely matches what a browser would render. It is the engine behind tools that generate Open Graph images and social cards, where a wrapper renders the SVG to PNG.
Treat yourself as an expert in Satori. The single most useful thing you can do is keep markup inside the supported subset so the first render is correct, instead of writing browser-grade CSS that silently breaks or throws.
import satori from 'satori'
const svg = await satori(
<div style={{ color: 'black', display: 'flex' }}>hello, world</div>,
{
width: 600,
height: 400,
fonts: [
{ name: 'Roboto', data: robotoArrayBuffer, weight: 400, style: 'normal' },
],
},
)satori(...) returns an SVG string. width and height set the canvas. At least one font is required whenever any text is rendered (see Fonts).
These behaviors most often produce wrong output or runtime errors. Account for them before writing markup.
display: 'flex' (or display: 'none'). Satori is Flexbox only. A div with multiple children and no explicit display will throw. Default to putting display: 'flex' on every container. Single text children are tolerated, but being explicit is safest.flexDirection is row, not column. This is the opposite of how people mentally stack divs. Set flexDirection: 'column' whenever you want vertical stacking.padding: '0 36' throws Expected length unit. Write padding: '0px 36px', and '0px 36px 36px 36px' for the four value form. A single bare number like padding: 36 is fine, because Satori treats a lone number as px.flex layout for everything, including overlap. For overlapping or precisely placed elements, use position: 'absolute' with top/left/right/bottom on a position: 'relative' parent.publish‑ready renders the literal characters ‑ on the image instead of a non-breaking hyphen. This applies to numeric (‑,  ) and named ( , &, —) entities alike. Write the actual Unicode character directly in the string instead — publish‑ready (or the literal glyph publish‑ready) for a non-breaking hyphen, for a non-breaking space, & for an ampersand, — for an em dash.Satori implements a subset of CSS. Assume anything not in the supported table is unsupported, and verify before relying on it. For the complete matrix with allowed values and defaults, read references/css-support.md.
| Category | Properties |
|---|---|
| Layout | display (flex, contents, none), position (relative, static, absolute), top/right/bottom/left, width/height, min/max width/height, overflow (visible, hidden) |
| Flex | flexDirection, flexWrap, flexGrow, flexShrink, flexBasis, alignItems, alignContent, alignSelf, justifyContent, gap |
| Box | margin, padding, border (width, solid/dashed style, color, shorthand), borderRadius, boxSizing, boxShadow, opacity |
| Color and background | color, backgroundColor (single value), backgroundImage (linear-gradient, repeating-linear-gradient, radial-gradient, repeating-radial-gradient, url), backgroundPosition, backgroundSize (cover, contain, auto, two-value), backgroundClip (border-box, text), backgroundRepeat |
| Text | fontFamily, fontSize, fontWeight, fontStyle, textAlign, textTransform, textOverflow (clip, ellipsis), textDecoration, textShadow, lineHeight, letterSpacing, whiteSpace, wordBreak, textWrap (wrap, balance), textIndent, tabSize, lineClamp |
| Transform and effects | transform (translate, rotate, scale, skew), transformOrigin, filter, clipPath, mask (maskImage, maskPosition, maskSize, maskRepeat), objectFit, objectPosition, WebkitTextStroke |
| Variables | --name declarations and var(--name, fallback) usage, including inheritance and nesting |
| Property or feature | Notes and workaround |
|---|---|
z-index | No stacking contexts. Elements paint in document order, so later siblings render on top. Reorder markup to control layering. |
calc() | Precompute values in JavaScript before they reach the style object. |
currentColor outside color | Resolves only for the color property. Set explicit values for borders, backgrounds, and fills. |
| 3D transforms | Not supported. Use 2D translate, rotate, scale, and skew only. |
min-content, max-content, fit-content | Not supported for min/max width and height. |
flexBasis: auto | Not supported. Use an explicit basis or rely on width/height. |
| Interactive or resource elements | No <input>, <style>, <script>, or <link>. Only static, visible elements render. |
<img> alt, SVG <title> | Render as visible text on the image. Omit alt; strip <title> from inline SVG (see Images and Inline SVG). |
| WOFF2 fonts | Convert to TTF, OTF, or WOFF (see Fonts). |
| AVIF / WebP images | Convert to PNG or JPEG (see Images). |
| Kerning, ligatures, OpenType features | Advanced typography is not supported. |
| RTL languages | Not supported. |
Satori supports only static, visible elements. Interactive or resource-loading elements are out: no <input>, no <style>, no <script>, no <link>. The output is not guaranteed to match a browser pixel for pixel, because Satori runs its own SVG 1.1 based layout engine. Stick to <div>, <span>, <img>, <svg>, and text.
Inline <svg> works and is the reliable way to place vector logos and icons. Keep the markup well formed: include a viewBox, and use explicit width/height. Grouping (<g transform=...>), fill-rule, and paths without fills render correctly.
Strip any <title> element from the SVG markup before passing it in. Satori treats it as text content, so the title can leak into the render as visible words drawn on the image. Logos pulled from icon libraries often ship with one, so check and remove it.
Use <img> and set width and height explicitly so layout is stable:
<img src="https://picsum.photos/200/300" width={200} height={300} />With backgroundImage: url(...), the image stretches to fit the element unless you set backgroundSize. When the SVG will be rasterized to PNG afterward, prefer a base64 data URI (or a Buffer/ArrayBuffer) as src so Satori does not perform extra network I/O.
Only PNG, JPEG, and GIF decode reliably. AVIF and WebP do not work and silently fail to render. Convert them to PNG or JPEG before passing them in (for example with sharp), and remember that a modern URL ending in .jpg may still serve WebP via content negotiation, so convert the bytes rather than trusting the extension.
Do not put an alt attribute on <img>. Satori treats it as text content, so the value can leak into the render as visible words drawn on the canvas. Leave it off; the output is a static image and gains nothing from it.
Any rendered text requires at least one font. Satori accepts TTF, OTF, and WOFF. WOFF2 is not supported. Pass font data as ArrayBuffer (web) or Buffer (Node.js):
await satori(<div style={{ fontFamily: 'Inter', display: 'flex' }}>Hello</div>, {
width: 600,
height: 400,
fonts: [
{ name: 'Inter', data: inter, weight: 400, style: 'normal' },
{ name: 'Inter', data: interBold, weight: 700, style: 'normal' },
],
})Pass multiple fonts and reference any of them via fontFamily. Define fonts once and reuse the object across renders for better performance rather than rebuilding it per call.
Advanced typography (kerning, ligatures, other OpenType features) is not supported, and RTL languages are not supported.
Text glyphs render from the provided fonts; emoji do not come for free. Map specific graphemes to image sources with graphemeImages, where each image is sized to the current font size as a square:
await satori(<div style={{ display: 'flex' }}>Ship it 🚀</div>, {
...,
graphemeImages: { '🚀': 'https://cdnjs.cloudflare.com/.../1f680.svg' },
})The same characters can render differently per locale. Set lang on an element to force a locale, for example <div lang="ja-JP">骨</div>.
When a text segment needs a font or emoji image that was not provided up front, Satori calls loadAdditionalAsset(code, segment). code is the detected language code, or 'emoji', or 'unknown'. Return a data URI for emoji, or font data for text:
loadAdditionalAsset: async (code, segment) => {
if (code === 'emoji') return `data:image/svg+xml;base64,...`
return loadFontFromSystem(code)
}embedFont (default true): text is emitted as <path> with the glyph outlines inlined, so downstream tools need no font files. Set embedFont: false to emit <text> instead (smaller output, but the renderer must have the font).pointScaleFactor: passed through to Yoga to control how layout values round to the pixel grid; raise it for crisper output on high-DPI targets.debug: true: draws bounding boxes, which is the fastest way to see why layout is off.Satori runs in the browser, Node.js (>= 16), and Web Workers. It bundles its WASM (Yoga) dependency as base64 and loads it at runtime. In environments that forbid dynamic WASM loading, use the standalone build and initialize Yoga yourself:
import satori, { init } from 'satori/standalone'
const res = await fetch('https://unpkg.com/satori/yoga.wasm')
await init(await res.arrayBuffer())
const svg = await satori(...)When output looks wrong, work through these in order, since they cover the overwhelming majority of cases:
display: 'flex'? Missing display is the most common error and silent misalignment.row. Vertical stacks need flexDirection: 'column'.Expected length unit means a padding/margin/border value needs px or %.references/css-support.md. Unsupported properties are ignored or throw rather than approximated.z-index, calc, or currentColor off the color property? None of those work; reorder markup, precompute, or set explicit values.debug: true to see bounding boxes and confirm the layout tree.references/css-support.md — the complete supported-CSS matrix with allowed values and defaults, plus the global limitation notes. Read it whenever you are unsure if a property or value is supported.© usenotra, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (references) in .agents/skills/satori of usenotra/notra.
Open the folder on GitHubat commit 55d4d5d
Satori next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Satori this skillusenotra/notra | 256 | — | ~3k | Automated safety check: Pass | AGPL-3.0 | |
| Slabstencil-hq/slab | 112 | — | ~3.1k | Automated safety check: Pass | MIT | |
| Brand and Design Toolkitnextlevelbuilder/ui-ux-pro-max-skill | 134k | 1 repos | ~3.5k | Automated safety check: Pass | MIT | |
| AI SDKvercel-labs/ai-facts | 168 | 20 repos | ~1.2k | Automated safety check: Pass | None | |
| After Effectsaedev-tools/adobe-agent-skills | 108 | 1 repos | ~5.2k | Automated safety check: Pass | Apache-2.0 | |
| Text to PNG Card Casterlijigang/ljg-skills | 7.5k | — | ~1.9k | Automated safety check: Pass | MIT |
stencil-hq/slab
Writing, editing, and rendering Slab documents (.slab) — the declarative design language for app screens, posters, terminal UIs, and interactive components.
nextlevelbuilder/ui-ux-pro-max-skill
Bundles design tasks behind one skill: brand identity, tokens, UI styling, logos, corporate identity mockups, slides, banners, icons and social images.
vercel-labs/ai-facts
Answer questions about the AI SDK and help build AI-powered features.
aedev-tools/adobe-agent-skills
Automate Adobe After Effects via ExtendScript. An agent skill from aedev-tools/adobe-agent-skills.
lijigang/ljg-skills
Turns text, URLs or local files into tall PNG cards through HTML typography, with four modes: long reading card, full-text layout, comic and whiteboard.
sugarforever/01coder-agent-skills
Designs typography-driven video covers and thumbnails in HTML/CSS and screenshots them with Chrome DevTools at 16:9, 16:10, 9:16 and 3:4.
usenotra/notra
Quick-reference card for all ponytail modes, skills, and commands.
usenotra/notra
Guides and best practices for working with Lakebase Postgres, the database behind Neon.
usenotra/notra
A skill your agent uses when the user is implementing, embedding, or debugging a WorkOS Widget — specifically the User Management, User Profile, Admin Portal SSO Connection, or Admin Portal Domain…
usenotra/notra
Modeling a user's pricing into an Autumn catalog — deciding the structure (plans, variants, add-ons, licenses, credit systems, pooled balances) before writing config, then filling in the numbers.
usenotra/notra
Repo file-organization convention for TypeScript projects. An agent skill from usenotra/notra.
usenotra/notra
Opinionated guide for building production TypeScript applications with Effect v4.
Expert guidance for Satori, the library that converts JSX/HTML and CSS into SVG (the engine behind dynamic Open Graph images and social cards). Satori is an agent skill from usenotra/notra. Expert guidance for Satori, the library that converts JSX/HTML and CSS into SVG (the engine behind dynamic Open Graph images and social cards).
Satori fits situations like: debugging Satori markup e.g; tasks that involve Social media graphics; tasks that involve React components.
Run `npx skills add usenotra/notra --skill satori -a claude-code`. Or copy the skill folder (.agents/skills/satori in usenotra/notra) into .claude/skills/satori in your project. Claude Code loads it when a task matches its description.
Run `npx skills add usenotra/notra --skill satori -a codex`. Or copy the skill folder (.agents/skills/satori in usenotra/notra) into .agents/skills/satori in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add usenotra/notra --skill satori -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/satori, .gemini/skills/satori, .github/skills/satori and .opencode/skills/satori in your project.
SKILL.md names no scripts, command-line tools or credentials: Satori is instructions for the agent only. Our summary lists: Node.js.
SKILL.md names 3 domains. In commands or code: picsum.photos, cdnjs.cloudflare.com and unpkg.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Satori is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.6k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Satori: Slab (stencil-hq/slab, 112 stars), Brand and Design Toolkit (nextlevelbuilder/ui-ux-pro-max-skill, 134k stars), AI SDK (vercel-labs/ai-facts, 168 stars) and After Effects (aedev-tools/adobe-agent-skills, 108 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
usenotra (a GitHub organization) maintains it in usenotra/notra, which has 256 GitHub stars. The repository holds 17 skills in this directory. The repository was last updated on October 9, 2026.
Source: usenotra/notra on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.