Skip to content

Repository files navigation

🖼️ rectram

Dead simple dynamic image generation server for Bun using Satori + Sharp

License: Apache 2.0Build StatusBunSatoriSharp

rectram is a lightweight file-based image server framework that allows you to generate dynamic images (OG images, social cards, custom graphics) from JSX components using Satori and Sharp. Inspired by @vercel/og, it supports:

  • File-based routing (pages/.../page.tsx)
  • Dynamic props with getProps
  • Satori-powered SVG generation
  • Sharp-powered PNG rendering (fast af 🔥)
  • Full Bun-native support

⚡ Features

  • Dynamic Image Pages: Just create a page.tsx under pages/ and it becomes a route.
  • Async Props: Fetch data or generate props dynamically with getProps.
  • High Performance: Sharp handles PNG conversion fast, perfect for real-time OG image generation.
  • Bun Native: No Node.js hacks needed — runs fully in Bun.

📁 Project Structure

project/
├─ pages/
│ ├─ index/page.tsx # default route
├─ assets/
│ ├─ Inter-Regular.ttf
│ ├─ Inter-Italic.ttf
│ ├─ Inter-Bold.ttf
│ └─ Inter-BoldItalic.ttf
├─ src/
│ ├─ index.ts # Bun server entrypoint
│ ├─ router.ts # file-based router
│ ├─ renderer.ts # Satori + Sharp helpers
│ └─ types.ts # Type definitions
├─ bunfig.toml
└─ package.json / bun.lockb

🚀 Usage

1. Create your own repo from this template

  • If you want your own version, use this repo as a template on GitHub:
    • Go to the repo → Use this template → Create a new repo under your account.

2. Clone your personal repo

git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git
cd YOUR_REPO
bun install

3. Create a page

// pages/index/page.tsxexportconstgetProps=async({ query })=>({title: query.get("title")??"Hello World",subtitle: query.get("subtitle")??"Generated with rectram",});exportdefaultfunctionPage({ title, subtitle }){return(<divstyle={{display: "flex",width: "100%",height: "100%",alignItems: "center",justifyContent: "center",background: "#111827",color: "white",fontFamily: "Inter",padding: 64}}><divstyle={{display: "flex",flexDirection: "column",gap: 16,maxWidth: 900}}><divstyle={{fontSize: 72,fontWeight: 700,lineHeight: 1.1}}>{title}</div><divstyle={{fontSize: 36,opacity: 0.9}}>{subtitle}</div></div></div>);}

4. Start the server

bun dev

5. Open in browser

http://localhost:3000/?title=Hello&subtitle=rectram

🛠️ Development

  • Add new routes by creating page.tsx files under pages/.
  • Fetch dynamic data using getProps.
  • Use plain inline styles for your components.
  • Fonts must be placed under assets/ and imported in renderer.ts.

💡 Notes

  • Returns PNG by default; SVG is optional via contentType.
  • Fully typed with TypeScript.
  • Made with love and ChatGPT 😋

⚖️ License

Apache License 2.0 — do whatever the fuck you want w/ it.

About

Dead simple dynamic image generation server

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages