Open-source project
daveearley/screenshot.rocks avatar
daveearley/screenshot.rocks

Screenshot.rocks turns a screenshot into a device mockup in the browser

Create beautiful mobile & browser mockups from screenshots

809 stars73 forksTypeScriptMIT

At a glance

What is it?
Screenshot.rocks is a React application that takes a screenshot and wraps it in a phone or browser frame on the client, with browser extensions for one-click capture, an AWS Lambda for the screenshot API and a Konva canvas for the composition. It suits designers and developers who need presentable mockups without opening a design tool.
Who is it for?
Adopt Screenshot.rocks when you need a presentable mockup of a screen you already have, since the composition happens in the browser and the extensions remove the capture step, which is much faster than rebuilding the screen in a design tool. Do not adopt it if you need editable vector mockups or a design file, because the output is a rendered image produced by a canvas rather than a design artefact.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 30 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The whole job is compositing a frame around a picture

The premise is narrow and that is the appeal. Screenshot.rocks is an online tool which allows you to create beautiful mobile and browser mockups from screenshots, and the repository is the source code for the hosted service at screenshot.rocks. There is no design tool, no layer system and no export to a design format. You supply a picture of a screen and the application composes it into a device or browser frame, in the browser. The dependency list in `package.json` shows the shape of that work. `konva` and `react-konva` provide the canvas, `react-image-crop` handles the interactive crop, `dom-to-image` turns DOM into an image, `polished` does the colour maths, and `use-image` and `react-color` deal with loading and colour input. The whole thing is a React 16 application built with `react-scripts`.

Installation is four commands

The README gives the setup in full, and it is a standard React project checkout:

bash
git clone [email protected]:daveearley/screenshot.rocks.git
cd screenshot.rocks
yarn install
yarn start

The `start` script is worth reading before you run it, because it explains an otherwise puzzling flag. The package scripts set `NODE_OPTIONS=--openssl-legacy-provider` before running `react-scripts start --host 0.0.0.0`, and the same flag appears in the `build` script. That is a workaround for running an old `react-scripts` release, 3.4.1 in the manifest, against a modern Node, where the Webpack version bundled inside it expects the legacy OpenSSL provider. The `--host 0.0.0.0` part is there so the dev server is reachable from other machines on the network, which matters if you are testing on a phone. The `build` script additionally runs `node scripts/build-pages.js` after the React build, which appears to produce static pages alongside the app.

Extensions remove the capture step for Firefox, Chrome and Edge

The most interesting feature is not in the application. There are browser extensions for three browsers, listed in the README as one-click design mockups, for Firefox, for Chrome and for Edge. The reason they matter is that the hard part of the workflow is not the frame, it is getting the screenshot cleanly in the first place. A user browsing the application they are working on has to select a region, hide the parts they do not want, and deal with the browser chrome. An extension can do that capture natively and hand a clean image to the tool. For a developer working on a responsive layout, the loop of open the page, capture, frame, share becomes a few clicks rather than a screenshot utility and a file dialog. The extensions are separate downloads from the add-on stores, so adopting the tool does not force you to adopt the extension, and the repository has a `browser-extension/` directory for the code.

The screenshot API lives in a Lambda

There is a server side piece, and it is deliberately small. The repository has a `screenshot-lambda/` directory and an `api/` directory, and the environment file lists a `REACT_APP_SCREENSHOT_API` variable, which is the endpoint the front end calls when it needs a capture it cannot take itself. The Makefile has a target that packages and uploads it:

bash
deploy-lambda:
	@(cd ./screenshot-lambda && zip -r function.zip . && aws lambda update-function-code --function-name screenshot --zip-file fileb://function.zip)

So the Lambda is named `screenshot` and is updated in place with the AWS CLI, which is the whole deployment story for that piece. The other Makefile target packages the browser extension into `extension.zip` by zipping the contents of the `browser-extension` directory. The rest of the environment file is analytics configuration, with `REACT_APP_GA_ID`, `REACT_APP_GAA_ID`, `REACT_APP_GAA_CONV_ID` for Google Analytics and Google Analytics for Ads, and a `REACT_APP_DEBUG` flag. The `api/` directory is the other sign that this is not a purely client side tool.

Two deployment paths, one for the app and one for the extension

The application can be deployed in the two ways a React project usually is. There is a `vercel.json` for Vercel, and there is a Dockerfile that builds in one stage and serves in another:

dockerfile
FROM node:18.16.0 AS build

ADD ./ /app
WORKDIR /app
RUN npm install && npm run build

FROM node 

EXPOSE 5000
COPY --from=build /app/build /app
RUN npm install -g serve

CMD serve -s /app

The runtime stage is a bare `node` image with the `serve` package installed globally, serving the built `build` directory as a static site on port 5000. That is a thin, conventional setup, and the choice of `serve -s` means client side routing is handled by the fallback. The extension is deployed separately, and the Makefile's `package-browser-extension` target is the whole pipeline: it removes any existing archive, zips the extension directory and prints a confirmation. The `.env.example` shows that the analytics and API settings are compile-time environment variables with the `REACT_APP_` prefix, which is the Create React App convention and means they are baked into the bundle at build time rather than read at runtime.

Tests, linting and the age of the toolchain

The repository carries both unit and end to end testing, and the scripts say how. The `test` script runs `react-scripts test`, the Jest runner from Create React App, with the testing library packages for React, jest-dom and user-event among the dependencies, and a `tests/` directory at the root. The end to end path is separate and uses Playwright, with `test:e2e` running a production build before `playwright test`, and there is a `playwright.config.ts` and an `e2e/` directory. The age of the stack is the thing to keep in mind before you plan maintenance. React is pinned at 16.13.1, TypeScript at about 3.7, `react-scripts` at 3.4.1, and the type packages for React 16, while Playwright is much newer at 1.55.1. The `browserslist` field also shows the intended targets, with the production list set to more than 0.2 percent share, not dead and not op_mini all, and the development list pinned to the last version of Chrome, Firefox and Safari. ESLint extends `react-app`, and the repository includes a `CLAUDE.md` file for assistant tooling.

MIT licensed, and the contribution route

The licence is MIT, described in the README with a link to a summary of it, and the file at the root is named `LICENCE`. The contribution guidance is short. The README says contributions are more than welcome and asks that if you think a feature could be added, you create an issue first, which is a sensible convention for a project that has to keep a browser extension, a Lambda and a React app in step. Bugs are handled the same way, by creating an issue. The repository itself is organised around those separate pieces, with `site/`, `src/`, `api/`, `browser-extension/`, `screenshot-lambda/`, `public/`, `assets/`, `scripts/` and `e2e/` at the top level, alongside `vercel.json`, the `Dockerfile` and the `Makefile`. There are no GitHub releases, and the last push to the repository was on 2026-09-24, so the hosted service is the reference implementation rather than a published package.

Editorial conclusion

Adopt Screenshot.rocks when you need a presentable mockup of a screen you already have, since the composition happens in the browser and the extensions remove the capture step, which is much faster than rebuilding the screen in a design tool. Do not adopt it if you need editable vector mockups or a design file, because the output is a rendered image produced by a canvas rather than a design artefact. Verify first which browser extensions you need, since Firefox, Chrome and Edge each have their own build, and check the Node version you run, because the scripts rely on `react-scripts` 3.4.1 and set `--openssl-legacy-provider` to work on modern Node.

Frequently asked questions

How do I run Screenshot.rocks locally?

Clone the repository with `git clone [email protected]:daveearley/screenshot.rocks.git`, change into the directory, run `yarn install` and then `yarn start`. The start script sets `NODE_OPTIONS=--openssl-legacy-provider` so the older `react-scripts` release works on a modern Node.

Does Screenshot.rocks have a browser extension?

Yes, one for Firefox, one for Chrome and one for Edge, described as one-click design mockups. The extension source is in the `browser-extension/` directory and the Makefile has a target that zips it into `extension.zip`.

What does the screenshot API in Screenshot.rocks do?

The front end calls a server side screenshot API, whose address is set through the `REACT_APP_SCREENSHOT_API` environment variable. The implementation lives in the `screenshot-lambda/` directory and is deployed with an AWS CLI command in the Makefile's `deploy-lambda` target.

How can Screenshot.rocks be deployed?

There is a `vercel.json` for Vercel and a Dockerfile that builds the app with Node 18.16.0 and serves the built output with the `serve` package on port 5000. Environment variables use the `REACT_APP_` prefix and are baked in at build time.

Official sources

  1. daveearley/screenshot.rocks on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/daveearley-screenshot-rocks.svg)](https://hysenlabs.com/projects/daveearley-screenshot-rocks)

Was this useful?