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

@modern-logic/snap

v0.1.2

Published

FAST visual regression testing for React Native

Readme

Typescript

snap

A simple cli that facilitates rapid snapshot testing

https://github.com/ModernLogic/snap

move runsnaps.sh into the script.

In Xcode

Copy logic in AppDelegate around snapPort

const char * snapPortC = getenv("snapPort");
if (snapPortC) {
    initialProperties[@"snapPort"] = [NSString stringWithUTF8String: snapPortC];
}

In React Native App

Create .snaprc.json file in the root directory changing the bundleIdentifier value

{
    "ios": {

        "bundleIdentifier": "com.example.example",
        "simulator": "iPhone 13",
        "appName": "Example.app"
    },
    "revokePermissions" ["location"] // Optional list of permissions to revoke on sim to avoid device modals poping up in snaps
}

Add in the .gitignore file

.snap/snapshots/diff
.snap/snapshots/latest

Modify src/ui/App.tsx file to add the snapPort value

<StorybookUIRoot storybookPage={p.storybookPage} snapPort={p.snapPort} />

The new library already includes TStorybookProps, TStory and TSubStory, so you will need to use them in src/storybook/stories/index.tsx and src/storybook/index.tsx files.

In addition, open src/storybook/index.tsx, look for StorybookAddRedux function and add before to the return statement.

if (storybookPage?.match(/^turbo/)) {
    return (
        <Provider store={store}>
        <TurboStorybook storybookPage={storybookPage} snapPort={snapPort} Stories={Stories} />
        </Provider>
    )
}

Modify .gitattributes to ensure new files added in .snap are added via lfs

.snap/snapshots/reference/ios/* filter=lfs diff=lfs merge=lfs -text

Modify metro.config.js either like this

  resolver.blockList = [
    ...(Array.isArray(resolver.blockList) ? resolver.blockList : resolver.blockList ? [resolver.blockList] : []),
    /^[.]snap[/]/,
  ];

or like this:

module.exports = {
  resolver: {
    ...defaultResolver,
    ...,
    blockList: [/^[.]snap[/]/],
  }
}

Android

Create an xml file in android/app/src/main/res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>

and reference it in the ApplicationManifest.xml:

<application
    android:networkSecurityConfig="@xml/network_security_config"
>

also in that file add an intent to the main activity:

  <intent-filter>
    <action android:name="io.modernlogic.snap.test" />
    <category android:name="io.modernlogic.snap" />
    <data android:mimeType="text/plain" />
  </intent-filter>

To the MainActivity kotlin file, add a dynamic property to the class:

  val isMoLoSnap: Boolean
    get() {
      val intentAction = intent.action
      return "io.modernlogic.snap" == intentAction
    }

if a custom animation for splash screen is installed, make it conditional, e.g. in onCreate:

    if (!isMoLoSnap) {
      SplashScreenModule.show(this)
    }

Implement createReactActivityDelegate like so:

override fun createReactActivityDelegate(): ReactActivityDelegate {
    return ReactActivityDelegateWrapper(
      this,
      BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
      object : DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) {
        override fun getLaunchOptions(): Bundle {
          val initialProps = Bundle()
          if (isMoLoSnap) {
            intent.getStringExtra("snapPort")?.let { initialProps.putString("snapPort", it) }
            intent.getStringExtra("storybookPage")?.let { initialProps.putString("storybookPage", it) }
          }
          return initialProps
        }
      }
    )
  }

Generating snaps

Run

npm run snap test -u

This should write results in to .snap/ directory

Running tests

To test

npm run snap test

This should run against existing match files

Copy CI script, especially the test area

      - name: run tests
        run: |
          npm run snap citest
        env:
          NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: store test results as artifact
        if: failure()
        uses: actions/upload-artifact@v3
        with:
          name: xcuitest-results
          path: |
            .snap/snapshots/diff/
            .snap/snapshots/latest/
          if-no-files-found: ignore

Debugging

For debugging from xcode, if necessary

To test: add these to the Scheme Environment Variables

snapPort=8881
storybookPage=turbo

Tips

  • If you have more than one simulator in Xcode with the same name as the simulator specified in your .snaprc.json, snap will only connect to the simulator with the most recent iOS version. For example, if you have two "iPhone 13", one iOS 16.1 and one iOS 15.5, snap will only connect to iOS 16.1. Delete any simulators with a newer iOS version to fix this issue.

Developing

Here's Andy's quick and dirty guide to developing snap.

  • Code up some new changes in this repo
  • run npm run tar to generate a temporary .tgz file called package.tgz in this directory
  • From the iOS app directory:
    • Copy the package.tgz into your project, e.g. cp ../@modernlogic/snap/package.tgz ./vendor/@modernlogic/snap_0.0.9.tgz
    • remove, and then reinstall the package: npm remove @modernlogic/snap and then npm add ./vendor/@modernlogic/snap_0.0.9.tgz
  • now you can run npm snap test or other commands and see if it works better with your new changes.
  • Be sure to delete package.tgz -- it doesn't need to be added to source control.

An alternate

You can also just do

npm run dev:try ../../<project_dir_name>

To do the same sequence of steps.

Releasing

In order to release a new version:

  1. Make sure all your changes are committed and pushed
  2. Clean the dist folder via rm -rf dist
  3. Prepare via npm run prepare this invokes builder bob.
  4. Run npm run release. This will:
    • Bump the version number based on your commits (using conventional commits)
    • Create a git tag
    • Push the changes to GitHub
    • Create a GitHub release
    • Publish to npm

The release process uses conventional commits to determine the version bump:

  • feat: commits trigger a minor version bump
  • fix: commits trigger a patch version bump
  • BREAKING CHANGE: in commit messages trigger a major version bump

Make sure your commit messages follow the conventional commit format for proper version management.