Skip to content

Kax675/rectram

Repository files navigation

🖼️ rectram

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

License: Apache 2.0 Build Status Bun Satori Sharp

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.tsx
export const getProps = async ({ query }) => ({
  title: query.get("title") ?? "Hello World",
  subtitle: query.get("subtitle") ?? "Generated with rectram",
});

export default function Page({ title, subtitle }) {
  return (
    <div style={{
      display: "flex",
      width: "100%",
      height: "100%",
      alignItems: "center",
      justifyContent: "center",
      background: "#111827",
      color: "white",
      fontFamily: "Inter",
      padding: 64
    }}>
      <div style={{ display: "flex", flexDirection: "column", gap: 16, maxWidth: 900 }}>
        <div style={{ fontSize: 72, fontWeight: 700, lineHeight: 1.1 }}>{title}</div>
        <div style={{ 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

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published