inkframe

Render beautiful visual images from markdown content — CLI and SDK.
Powered by inkframe.dev.
Includes a free shared API key so you can try it instantly — no signup required.
The shared key may be rate-limited or rotated over time; bring your own key for production use.
Requirements
- Node.js 18+
- An inkframe API key (a free shared key is included by default; for production use, open an issue to request a dedicated key)
Install
pnpm add -g inkframe
pnpm add inkframe
Workflow
0. Preview in the browser (free, no API key)
Open the Inkframe playground with your content pre-loaded — no API key needed.
inkframe open --content "# Hello World\n\nThis is styled."
inkframe open --content @post.md --design @design.json
This opens your browser with the playground pre-populated so you can preview and tweak before rendering.
1. Render with a template
The quickest way to get started — pick a template and render your content with it.
inkframe templates list
inkframe render --template tmpl_PWfUUDlVw --output out.png
inkframe render --content @post.md --template tmpl_PWfUUDlVw --output out.png
inkframe render --content "# My Post\n\nHello world." --template tmpl_PWfUUDlVw --output out.png
2. Customize a design
Extract a template's design as a starting point, tweak it, then render with your custom version.
inkframe templates get tmpl_PWfUUDlVw --design-only --output design.json
inkframe render --content @post.md --design @design.json --output out.png
inkframe render --content "# My Post\n\nHello world." --design '{"backgroundKey":"ocean","colorPaletteKey":"pure-white"}' --output out.png
3. Automate with the SDK
Use the TypeScript SDK to render images programmatically in your scripts or pipelines.
import { InkframeClient } from "inkframe";
const client = new InkframeClient({ apiKey: process.env.INKFRAME_API_KEY });
const result = await client.render({
content: "# Hello World\n\nThis is a visual post.",
design: { backgroundKey: "ocean", dimensionSpecKey: "instagram-4:5" },
});
console.log(result.resultUrl);
CLI
inkframe render --content "# Hello World"
export INKFRAME_API_KEY=your_api_key
inkframe render --content "# Hello World"
inkframe render --content @post.md --output out.png
inkframe render --template tmpl_PWfUUDlVw --output out.png
inkframe render --content @post.md --template tmpl_PWfUUDlVw --output out.png
inkframe render --content @post.md --design @design.json --output out.png
inkframe render --content "# Hello World" --design '{"backgroundKey":"ocean"}' --output out.png
inkframe templates list
inkframe templates get tmpl_PWfUUDlVw
inkframe templates get tmpl_PWfUUDlVw --design-only
inkframe templates get tmpl_PWfUUDlVw --output template.json
inkframe templates get tmpl_PWfUUDlVw --design-only --output design.json
inkframe open --content "# Hello World"
inkframe open --content @post.md --design @design.json
TypeScript SDK
import { InkframeClient } from "inkframe";
const client = new InkframeClient({ apiKey: process.env.INKFRAME_API_KEY });
try {
const result = await client.render({
content: "# Hello World\n\nThis is a visual post.",
design: {
backgroundKey: "ocean",
colorPaletteKey: "pure-white",
dimensionSpecKey: "instagram-4:5",
},
});
console.log(result.resultUrl);
} catch (error) {
console.error("Render failed:", error.message);
}
const templates = await client.listTemplates({ exclude: ["thumbnailUrl"] });
Multi-Page Content
Content can contain \pagebreak to separate pages (slides). The API renders one image per request — if your content has \pagebreak separators, only the first page is rendered. The inkframe.dev studio UI supports rendering all pages at once.
To render multi-page content via the CLI or SDK, split the content yourself and render each page in parallel:
inkframe render --content @page1.md --design @design.json --output slide1.png &
inkframe render --content @page2.md --design @design.json --output slide2.png &
inkframe render --content @page3.md --design @design.json --output slide3.png &
wait
const pages = fullContent.split("\\pagebreak");
const results = await Promise.all(
pages.map((page) => client.render({ content: page.trim(), design }))
);
Development
pnpm install
pnpm build
pnpm dev
pnpm typecheck
Test the open command locally (point to local webapp):
pnpm build
node dist/cli.js open --content "# Hello World" --base-url http://localhost:3001
Test the CLI locally against the live API:
pnpm build
INKFRAME_API_KEY=your_api_key node dist/cli.js render --content "# Hello World"
Test against a local server:
INKFRAME_API_KEY=your_api_key node dist/cli.js render --content "# Hello World" --base-url http://localhost:3000
Simulate a global install:
pnpm link --global
export INKFRAME_API_KEY=your_api_key
inkframe render --content "# Hello World"
License
MIT