Image Publishing Platform
One image-generation platform, applied in three steps: a server-side rendering engine, a shipped consumer feature built on it, and a self-service concept to make it a paved road for any team.
1 · Sharing Accelerator → the image-template platform
The idea. In 2025 BuzzFeed ran the Sharing Accelerator, a cross-functional program with one KPI: lift shares per thousand pageviews by 70 to 125 percent. My track was quiz results. The spike asked one question: could a quiz result become a personalized, generated image a reader would actually post, with the same share options on every quiz type? The first build was the checklist result card below, and what it took to ship became the foundation of the image-template platform on this page.
The goal. A result worth sharing, one share step from the result screen, and an artifact that pulls a friend back into the quiz, all safe at scale, since the inputs are dynamic and the output is a public image.




How it was built. One share touches four codebases, changed in step.
- The shared UI package. Updated the core sharing elements in the company React component library: the ShareButton and its platform variants, the share icon, and an engagement trigger that reports share and comment clicks. Fixed once, every product gets it.
- A new image engine, and its first template. Replaced the legacy Python image service with
template_image_api: server-side React rendered by headless Chromium to a PNG, hashed on its content so a result renders once and is reused. The quiz-result template shipped with it, six backgrounds and a score variant for trivia and checklist quizzes. - The quiz module. Wired the shared package in, redesigned the result card per quiz type to match the template, and passed the dynamic parameters through the share URL: quiz and result ids, score, background. The result id comes from quiz data, never from user text.
- Page metadata. On an incoming share link the page server generates or fetches the cached image and sets the
og:image, Twitter, and Pinterest tags at each platform's size (1200×630, 1080×1080, 1080×1920), with a canonical share URL per result.

What came of it. Quiz-result sharing shipped across every quiz type with French and LATAM localization, and the engine became the platform: Tag Yourself, the quiz-party invite, timed trivia, and the BF Island artifacts all landed as templates on it. The sections below pick up from there.
2 · Tag Yourself
The idea. Personality quizzes already had a share moment. Tag Yourself made it a game: guess your result before the reveal, or guess a friend's, and let the result page show expectation against reality on one generated card. Same platform as section 1, a new template, and a share that now carries a question instead of an answer.
The goal. A reveal worth posting, a share that pulls the tagged friend back to play, and cards that stay honest, since every one is generated from ids validated against the quiz data rather than anything a user typed.







How it was built.
- The template. A tag-yourself template on the image engine with two components, the share image and the result card. Layout is decided purely by which ids arrive: a single result, a friend's tag with a mystery card, expectation against reality, and, from the v3 redesign, a celebratory card when the guess was right. Versions are aliased so every old link keeps rendering.
- The quiz module. The Tag Yourself step stores the guess, the result page builds a share URL from the two ids and the mode, and Share to Comments fetches the result card straight from the engine and posts it into the thread.
- Page metadata. The page server maps the incoming ids to the template call and sets the preview image. The bug I chased: the pick id was missing from the canonical share URL, so Facebook cached one preview for every share of a result and each friend's card collapsed into the first one crawled. Adding it gave each pick a unique URL.
- The redesign. The v3 pass took our designer's Figma into a new type treatment and four layouts, shipped in step across the quiz module, the engine, and the page metadata.
What came of it. A public feature that turned a result into a two-person game, with the friend loop doing the marketing. The redesign was put to an A/B test and won decisively: share engagement up 176% on desktop and 82% on mobile web, and the return-visit rate through shared links rose from 59% to 69%.
3 · Turnkey Sharing 🤖
The idea. As more internal consumers started using the custom share-artifact system, it became apparent that a turnkey solution would support greater adoption of a proven strategy. Every new experience was still wired by hand across three codebases: a new template class in the image engine, a matching decode path in the page server, and share parameters in the quiz module. The reusable chassis already existed on every surface. What was bespoke was the glue.
The goal. Make sharing a drop-in add-on: a new game supplies a stable result id and a small display config and gets the Share button, the personalized card, and the unfurl with no multi-repo project. Keep the security model intact, since identity stays id-based and nothing a user types can select an image. Allow bounded customization, with custom skins as the escalation path.







How it was built. An exploration branch across the same three surfaces, run as a phase-gated agent loop with a green test suite at every commit.
- Templates as data. A generic renderer that turns a definition (accepted params, allowed values, upstream fetch, hash fields, render component) into a working template. The quiz-result template was migrated first and produced byte-identical image hashes, so the pipeline never changed.
- One share contract. A versioned, immutable contract per experience: ids for identity, bounded display params, a deterministic content hash. A read-only catalog lets any consumer, or an agent, list templates and their input schemas.
- Generic decode and encode. The page server got one decoder driven by the contract registry, with the legacy quiz-result and Tag Yourself paths kept as fallbacks. The quiz module got a share adapter, so a new experience is a result id plus a few lines.
- Skins with slots. A builder template family with three archetypes, a score card, an identity card, and an outcome card, each with bounded slots for background, palette, and counts. Text options interpolate validated values and fail closed, so a card can never ship half-rendered.
What came of it. The concept validated end to end: a result id flowing through adapter, contract, catalog, and renderer with the render pipeline untouched. Productionization was scoped with go decisions on the contract store, all three surfaces, and every core share action, and a follow-on put live game state, streak and daily rank, on a share card for a daily puzzle. The proposal was socialized with product leadership and routed to the Games roadmap. It was in progress when I left.
4 · The Nudge 🤖
The idea. After talking with other senior engineers, the problem of adoption came up: even when a solution is turnkey, people still have to hunt for it. We also had a growing number of non-technical people vibe coding their own games at BuzzFeed, and none of them were going to read a template catalog.
The goal. Put the offer where the work already happens. Inside the AI-assisted building tools, add an advisory step: as an editor nears completion, an agent looks for a shareable result, recommends turnkey sharing with a preview, and on accept wires the whole flow. The same detect, recommend, wire loop was meant to extend to leaderboards and other systems that already run in production.

How it was built.
- Detect. Eligibility guardrails carried over from Tag Yourself: a stable result id, a result image with the right crops, a title within length, and no CMS opt-out. Anything short of that returns machine-readable reasons and stays silent, so an editor never sees a broken card.
- Recommend and plan. One message, “This project has a shareable result. Add turnkey sharing?”, with a preview and three choices. On accept the planner drafts everything an engineer needs: the contract, the share adapter, and the share URL and metadata.
- A read-only MCP. The agent validates and previews against the image engine through list, describe, validate, and preview tools. No create, register, or upload. The only write is publishing the contract through an internal-auth route after human review.
- The security gate. Public upload was the open risk, so it was audited rather than built: signed short-lived tokens, file allowlists, and byte caps were designed and sequenced ahead of any nudge work.
What came of it. A working prototype ran the loop end to end, detect through draft through human publish, and was kept and aligned to the contract system when the wider effort was scoped. Leadership held the nudge itself behind the security gate, which was the right call. The pattern was documented for the next systems in line, a return bridge that tells a sharer when a friend plays and daily streaks with group boards. Both were in progress when I left.
Results
- Tag Yourself A/B: +176% desktop and +82% mobile-web share engagement.
- Return-visit rate via shared links 59% → 69%.
- The image-publishing program carried BuzzFeed past its H2 2017 Instagram engagement target, finishing at over 170% of goal.
Skills
AI / Agentic
- programmatic media generation at scale
- template-driven automated social output
Frontend
- React
- styled-components (server-rendered)
- design systems
- responsive template design (OG / social / story sizes)
- A/B experimentation
Backend / Infra
- Node.js
- Express
- Puppeteer / headless Chromium
- content-hash image caching
- S3 / CDN
- Jest + supertest
- staged legacy migration
Leadership
- architect & lead
- platform / paved-road thinking
- cross-repo feature rollout