npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-shot

v0.1.0

Published

App Store screenshot generator. Write designs in React, export production-ready PNGs for every locale and device.

Downloads

80

Readme

react-shot

react-shot is a Bun-first screenshot SDK for App Store and Play Store creative. You write screenshot sets in React, preview them locally, and export production-ready PNG slices with Puppeteer and Sharp.

The current SDK is built around one idea:

Text is the argument. UI is the proof.

Instead of shipping generic “5 screens with different colors”, react-shot now gives you copy-first building blocks and creative families for agency-style screenshot sets.

Requirements

  • Runtime: Bun
  • Install in projects: bun add react-shot
  • One-off commands: bunx react-shot ...

Install

bun add react-shot

Quick Start

mkdir my-screenshots
cd my-screenshots
bunx react-shot init
bun install

# Add raw simulator screenshots
cp ~/simulator-screenshots/*.png public/assets/screenshots/ios/

# Rewrite the generated headlines first
$EDITOR compositions/hero/index.tsx

# Preview the set
bun run dev

# Export all locales and devices
bun run export -- hero --all --store

CLI

react-shot init
react-shot dev
react-shot export <id>
react-shot export <id> --locale tr
react-shot export <id> --device ipad
react-shot export <id> --all
react-shot export <id> --store
react-shot build
react-shot --version

Story Model

The default screenshot system is a 5-slot sequence:

  1. Hook
  2. Shift
  3. Proof
  4. Delivery
  5. Payoff

The first three slots should answer:

  • Why should I care?
  • What changes after I install?
  • Why should I believe you?

If the copy reads like feature labels, rewrite it before touching the layout.

Creative Families

react-shot now ships stronger starter directions instead of a large pool of color-swapped demos:

  • editorial-travel
  • creator-bold
  • transit-utility
  • playful-commerce
  • premium-neutral

Each family is meant to behave like one campaign with a consistent:

  • headline rhythm
  • device placement
  • background system
  • proof treatment
  • merchandising language

Config

import { defineConfig } from "react-shot/config";

export default defineConfig({
  compositionsDir: "./compositions",
  publicDir: "./public",
  creativeFamily: "premium-neutral",
  brandColor: "#1F2937",
  targetDisplay: "iphone-67",
  port: 5174,
  export: {
    outputDir: "./appstore",
    deviceFolders: {
      ios: "APP_IPHONE_67",
      ipad: "APP_IPAD_PRO_6GEN_129",
    },
  },
});

Additional top-level fields:

  • creativeFamily
  • brandColor
  • targetDisplay

Unknown top-level config keys now warn to catch typos early.

Writing Compositions

The preferred workflow is:

  1. Write the 5 headlines.
  2. Map each headline to the strongest screen.
  3. Choose one creative family.
  4. Build the set with reusable blocks.

Example:

import {
  Canvas,
  Slice,
  SolidBg,
  HeroHeadlineBlock,
  DeviceStage,
  ScreenshotBreakout,
  ProofStrip,
} from "react-shot";
import { appstoreIOS } from "react-shot/presets";

export default function Hero() {
  return (
    <Canvas preset={appstoreIOS}>
      <Slice index={0} bg={<SolidBg color="#F3F4F6" />} align="center" justify="start" py={90}>
        <div style={{ flex: 1, width: "100%", display: "flex", justifyContent: "center", alignItems: "center" }}>
          <HeroHeadlineBlock
            kicker="The hook"
            headline={<>Stop wasting time<br />on busy work</>}
            subtitle="Lead with the pain, not the feature list."
            proofItems={["4.9 rating", "Loved by teams"]}
            accentColor="#2563EB"
            headlineColor="#111827"
            subtitleColor="rgba(17,24,39,0.64)"
          />
        </div>

        <DeviceStage
          variant="iphone-16-pro"
          frameColor="white"
          screenshot="/assets/screenshots/ios/1.png"
          width={1000}
          bleedBottom={120}
        >
          <ScreenshotBreakout
            x={120}
            y={980}
            width={980}
            bgColor="#FFFFFF"
            textColor="#111827"
            title="One message per screen wins"
          >
            <ProofStrip items={["Pain first", "Outcome next", "Proof third"]} />
          </ScreenshotBreakout>
        </DeviceStage>
      </Slice>
    </Canvas>
  );
}

Register compositions in compositions/index.ts with family and narrative metadata:

import { lazy } from "react";
import type { CompositionEntry } from "react-shot/types";
import { appstoreIOS, appstoreIPad } from "react-shot/presets";

export const compositions: CompositionEntry[] = [
  {
    id: "hero",
    name: "Copy-First Hero",
    component: lazy(() => import("./hero")),
    preset: appstoreIOS,
    ipadPreset: appstoreIPad,
    locales: ["en", "tr"],
    family: "premium-neutral",
    narrative: {
      name: "Copy-First Hero",
      family: "premium-neutral",
      brandColor: "#F3F4F6",
      slots: [
        { role: "hook", headline: { verb: "STOP", outcome: "WASTING TIME", support: "Lead with the pain" } },
        { role: "shift", headline: { verb: "GET", outcome: "INSTANT CLARITY", support: "Show the shift" } },
        { role: "proof", headline: { verb: "TRUST", outcome: "A REAL RESULT", support: "Back up the claim" } },
        { role: "feature", headline: { verb: "USE", outcome: "THE CORE WORKFLOW", support: "Reveal the mechanic" } },
        { role: "cta", headline: { verb: "START", outcome: "TODAY", support: "Close with the payoff" } },
      ],
    },
  },
];

New Building Blocks

High-level components for screenshot campaigns:

  • HeroHeadlineBlock
  • ProofStrip
  • StoryBadge
  • DeviceStage
  • ScreenshotBreakout
  • FloatingMerch

These sit on top of the lower-level canvas, slice, text, device, and decorative primitives.

Presets

appstoreIOS
appstoreIOS4
appstoreIOS6
appstoreIOS65
appstoreIOS69
appstoreIPad
playstore
socialInstagram
socialTwitter

App Store portrait presets now include crop-safe metadata for text and merchandising.

Types

import type {
  CompositionEntry,
  CompositionProps,
  ScreenshotNarrative,
  StorySlot,
  StorySlotRole,
  BenefitHeadline,
  CreativeFamily,
  CropSafeArea,
  DeviceVariant,
} from "react-shot/types";

Export Output

react-shot export <id> --store writes output organized by locale and device:

appstore/
  en/
    APP_IPHONE_67/01.png
    APP_IPHONE_67/02.png
  tr/
    APP_IPAD_PRO_6GEN_129/01.png

How It Works

  1. Compositions are React components rendered at exact store dimensions.
  2. react-shot dev starts a Vite server with gallery and preview routes.
  3. react-shot export launches Puppeteer, renders the full canvas, and slices it into final PNGs with Sharp.

License

MIT