Skip to content

Build Not yet confirmed elsewhere1 publisher 2 min read Published

SvelteKit OG 4.4 renders OG images on the main thread or in a web worker

SvelteKit OG 4.4 adds a client entry that renders OG images in the browser or a web worker, with no server request. A dev.to post says it targets live editor previews and adapter-static sites that have no server.

The Engineer · Build desk

How we use AI Send a correction

SvelteKit OG's client entry has setup limits Limits the post states for the client entry and the setups each reaches; the story's one number is a version, not a quantity to chart.

Worker rendering needs worker format es in Vite config or vite build fails. Components keep only inline styles. Satori raster formats other than png render as png; Takumi outputs jpeg and webp. Satori-only projects must install takumi-js. Only Vite is supported as bundler.

SvelteKit OG's client entry has setup limits
WhoHowKindClaim
Worker rendering setupsNeeds worker format "es" in Vite config; without it vite dev works but vite build failsconstraint14
Components with scoped stylesOnly inline styles are captured; scoped style blocks and css="injected" do not come throughconstraint13
Satori jpeg or webp usersSatori raster formats other than png render as png; Takumi outputs jpeg and webpconstraint10
Satori-only projectstakumi-js must still be installed, because Vite resolves the Takumi chunk at build timecost6
Projects on other bundlersClient entry loads wasm and fonts via Vite ?url imports; other bundlers are not supportedconstraint7

What happened

  • Before 4.4, every OG image the package produced came from a server route.
  • The client entry runs the same two engines as the server: Takumi by default, or Satori with ReSVG.
  • Worker rendering needs worker.format set to es in the Vite config, since the default iife format cannot code-split the per-engine chunks.
  • Only inline styles survive when a component is rendered; scoped style blocks and css="injected" do not come through.

Why it matters

  • cost The worker setting fails late. Without it vite dev works and vite build does not, so the first error appears at build time.
  • constraint A card component written with scoped style blocks loses those styles in the image and has to move to inline styles or the stylesheets and Tailwind options.
  • decision Teams that want webp or jpeg previews need Takumi, the default engine, because Satori raster output other than png comes back as png.

The entry point is one function. `createImage` takes an HTML string or a Svelte component and returns a standard Response, read with `.blob()`, `.arrayBuffer()` or `.text()` [9]. For a component, the package mounts it into a detached shadow root, captures the HTML and unmounts it, so page CSS cannot leak into the image [12].

The post's example ends at an object URL: it turns the blob into one with `URL.createObjectURL` and sets it as an `<img>` source [17]. In our view, that URL is local to the tab that made it, so a link-preview crawler requesting an og:image address cannot reach it. The post does not show how a browser-rendered image gets to an address a crawler can fetch. Until it does, the adapter-static claim covers rendering and leaves delivery to the team.

The client entry loads its WebAssembly and fonts through Vite `?url` imports, and the post says other bundlers are unsupported [7]. The call has to stay out of server rendering. Set `export const ssr = false;` in the route's `+page.ts`, or call the API only inside `onMount` or an event handler [8].

Install weight and visitor weight differ. `takumi-js` has to be installed even for Satori-only use, because Vite resolves the Takumi chunk at build time [6]. It adds a dependency for the engine you did not pick, though the install is a single command [6]. At runtime each engine is its own chunk behind a dynamic `import()`, so a Takumi user never fetches Satori's WebAssembly, and the reverse holds [11].

The worker path is where the post claims a performance benefit. Rendering in a module worker keeps the main thread free while the wasm runs [16]. The post's handler reads the result with `.arrayBuffer()` and posts it back with the buffer in the transfer list [15], so the page receives the buffer itself.

On compatibility the post is direct: "The server API doesn't change; this release is purely additive." [5] That is the post's own claim. If it holds, a team with working server routes has nothing to migrate. The post also links a playground that renders in the browser and shows the matching `createImage(...)` call, so output can be checked before installing anything [18].

What to watch

  • Whether the package documents a way to get a browser-rendered image to a URL a link-preview crawler can fetch, which adapter-static sites would need.
  • Reports of vite build failures from teams that leave the worker format at its default iife.
  • Side-by-side checks of playground output against the server route for the same HTML, since the post says both produce the same images.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence50
Adoption
Insufficient
Hype gap−5
Incentives
Insufficient
Confidence55
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    SvelteKit OG 4.4 adds an @ethercorps/sveltekit-og/client entry that renders the same images on the main thread or in a web worker, with no server request.

    Reported Supported Source: dev.to post 'SvelteKit OG 4.4: Generate OG Images in the Browser'View cited source
  2. [2]

    Until 4.4, every OG image came from a server route.

    Reported SupportedView cited source
  3. [3]

    The post names two uses: live previews, where an editor or CMS shows the OG card as someone types without calling an endpoint on every keystroke, and static sites, where an adapter-static site has no server but can still generate images at runtime.

    Reported SupportedView cited source

Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.

Add to ChatGPTAdd to Claude

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · October 14, 2026

    SvelteKit OG 4.4: Generate OG Images in the Browser

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Topics

  • Generated share and Open Graph imagesFollow
  • WebAssembly in the browserFollow
  • SvelteKitFollow
Loading related stories