perxel-social-kitSAFE
One post, every size: social images and reels, and blog visuals, from React templates your project owns.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
One post, every size. Write a post once as a few props, and the kit renders it as a square, a 16:9 and a 9:16 image (or video), plus a contact sheet to review them side by side. Templates are plain React components in your own repo, so they look like your brand, not like ours.
It also makes the images and short clips a site's blog posts need: screenshots and recordings of your live site, and designed images from the same templates, written down as a recipe so one command makes them again when the site changes.
Made by Perxel for its own posts and blog. MIT licensed.
Install
npx @perxel/social-kit init
init adds the kit as a dev dependency (and React if the project has none), creates social/ with a config and a first post, adds the kit's work files to .gitignore, installs the agent skill with `npx skills` (it asks which agents: Claude Code, Cursor and others) and checks your setup.
By hand:
pnpm add -D @perxel/social-kit react react-dom npx skills add perxel/perxel-social-kit --skill social-kit npx social-kit doctor
Update both with pnpm update @perxel/social-kit && npx skills update.
Needs: Node 22+, React 19 in the project, Chrome for Testing (npx @puppeteer/browsers install chrome@stable, or set CHROME_PATH). For video and the web presets: ffmpeg; for WebP output: ImageMagick. social-kit doctor checks each one and says how to get it.
Every day
social-kit new launch-day --template announcement # social/posts/-launch-day/post.ts social-kit render launch-day # out/launch-day-square.png, -landscape.png, -portrait.png + launch-day-sheet.png social-kit render launch-day --only portrait social-kit templates | eject | sheet
966c53ad8faaOBSERVED · 2026-10-13Install
Commands as the repository documents them. They are shown, not run.
npx skills add perxel/perxel-social-kit --skill social-kit
Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned | |
| cursor | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: social-kit
description: "Make social media images and short videos (reels) in every size from React templates, and the images and clips a site's blog posts need (visual recipes: capture, record, compose), with @perxel/social-kit. Use when the user asks for a social post image, a LinkedIn/Instagram/X/Facebook/TikTok graphic, a reel, a story, an announcement card, \"the same post in other sizes\", or mentions social-kit, `social/`, `social-kit render`, a post's contact sheet, a beat-synced video, or `social-kit visuals`."
---
# social-kit
One post, every size, from one source. A post is a folder with a `post.ts` that names a template and its props; `social-kit render` turns it into every format at once (images: square 1080×1080 and landscape 1920×1080; reels also portrait 1080×1920), plus a contact sheet to review them together.
Run it as `npx social-kit ...` (or the project's script for it, e.g. `pnpm social ...`). Everything lives in the project's `social/` folder:
```
social/
social.config.ts brand (colours, fonts, logo), extra formats, default formats
templates/ the project's templates (.tsx); a file starting with _ is a helper, not a template
assets/ logos, music, footage (footage is usually gitignored)
posts/<date>-<topic>/
post.ts template, props, formats
out/ <topic>-square.png, <topic>-portrait.mp4, <topic>-sheet.png ... (<topic>: the folder name without its date, or the post's `name`)
```
## Before anything
1. `social-kit doctor`. It checks Chrome, ffmpeg, React, Remotion (reels only) and Python (optional). Fix what it marks MISS before going on, using the hint it prints.
2. Read `social/social.config.ts` and list the templates (`social-kit templates`), so you use the project's brand and templates rather than inventing new ones.
3. If the project has writing rules (a copywriting guide, a brand voice doc, a CLAUDE.md section), follow them for every word on the image. Do not add text the user did not ask for or approve: a tagline, a call to action, a hashtag. Suggest it instead.
## Make an image post
1. `social-kit new <topic> --template <name>` creates `social/posts/<today>-<topic>/post.ts` with the template's example props.
2. Fill in the props with the user's copy. Leave `formats` out to get the config's defaults, or list them (`["square", "landscape", "portrait"]`).
3. `social-kit render <post>`. It writes `out/<topic>-<format>.png` for each format and `out/<topic>-sheet.png`.
4. **Look at the sheet yourself before showing it** (read the image). Check every format, not only the first: text that wraps badly or overflows, logos too small or touching the edge, anything in the portrait format's top 240 px or bottom 300 px (Stories, Reels and TikTok cover those with their own buttons), contrast. Fix and render again (`--only portrait` renders one format).
5. Report the files and which one goes where (LinkedIn and most feeds: square; X, YouTube, website: landscape; Stories, Reels, TikTok, Shorts: portrait).
## Templates
A template is a React component in `social/templates/<name>.tsx`:
```tsx
import type {TemplateMeta, TemplateProps} from "@perxel/social-kit"
interface Props {headline: string}
export const meta: TemplateMeta<Props> = {
name: "quote",
formats: ["square", "landscape", "portrait"],
kind: "still", // "still" | "reel" | "both"
example: {headline: "Hello"}, // written into new posts
}
export default function Quote({width, height, format, props, brand, asset}: TemplateProps<Props>) {
return <div style={{width, height, background: brand.colors?.primary}}>{props.headline}</div>
}
```
- **Lay out per `format`**, not by scaling one layout: a table of sizes per format (padding, type size, logo size) is the usual pattern. The portrait format keeps important things clear of the top 240 and bottom 300 px.
- **Files:** `asset("social/assets/logos/x.svg")` (a path from the project root) gives a URL that works in images and reels. `brand.logo.light` / `brand.logo.dark` and `brand.fonts` come already resolved.
- **Images render on the server** (React to static HTML, then a Chrome screenshot): no hooks with effects, no client-side code runs. Inline styles or the stylesheets listed in the config's `css`.
- **Waiting and errors:** mark anything still loading with `data-pending` (the renderer waits until none is left); put `data-error="message"` on an element to fail the render with that message (for bad props).
- To change a kit starter, `social-kit eject <name>` copies it into `social/templates/`, where it replaces the starter.
- **Client templates (`bundle: true` in `meta`):** a template that needs code in the browser (a canvas drawn in an effect, a Lottie player, the project's Tailwind classes, `@/` imports) renders through the bundle instead: real client React, built with Remotion's webpack (so Remotion must be installed). The config's `bundle` sets it up: `css` (the project's global stylesheet, e.g. one that imports `app/globals.css`), `tailwind: true` (needs `@remotion/tailwind-v4`), `alias` (`{"@": ".."}`, and shims for framework-only imports such as `next/dynamic`) and `root` (the folder served at `/`, e.g. `../public`, so `/logo.svg` works). `data-pending` and `data-error` work the same. A framework's own setup (next/font variables, `antialiased` on `<html>`) has to be repeated in that stylesheet.
- **URL mode:** a post with `url: "http://localhost:3000/og?format={format}"` (instead of `template`) screenshots a page the project serves itself, at each format's size (`{format}`, `{width}`, `{height}` are filled in). Use it when the design needs the project's own build (its CSS framework, path aliases, components).
## Reels
A reel template has `kind: "reel"`, `fps` (30 by default) and `duration` (seconds, or a function of the props). It renders through Remotion, so the project needs `remotion`, `@remotion/bundler` and `@rTrust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- declared (1 observation(s))
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (2)
url: `http://127.0.0.1:${port}`,docs/demo.gif
Gates applied: no_behavioural_pass.
966c53ad8faafull audit observations/trust-audit/skill/perxel__perxel-social-kit.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-13 | 966c53ad8faa | SAFE | B | 89 | first audit |
Questions
What does the perxel-social-kit skill do?
One post, every size: social images and reels, and blog visuals, from React templates your project owns.
Is perxel-social-kit safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can perxel-social-kit access on my machine?
The audit observed that it reaches the network. Each of those is consistent with what it says it does. Secrets in the source: none found.
Which assistants does perxel-social-kit work with?
Its documentation mentions claude-code and cursor. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (966c53ad8faa), read on 2026-10-13. The repository is watched, and a new audit runs when it changes — this is the first audit.