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 🙏

© 2024 – Pkg Stats / Ryan Hefner

expo-native-lockfiles

v0.2.0

Published

Achieve more reproducible builds by committing your native project lockfiles to source control.

Downloads

11

Readme

expo-native-lockfiles

Achieve more reproducible builds by committing your native project lockfiles to source control.

What this does

This library is both a config plugin and a CLI tool for managing native mobile project lockfiles. By default, Expo's Continuous Native Generation ("CNG") pattern generates an iOS project with a Cocoapods lockfile, and an Android project with no Gradle lockfile, based on javascript dependencies locked with yarn.lock or similar. This module ensures more stable inputs to your native builds by allowing you to:

  • update & commit native lockfiles as you update and change JS dependencies that depend on native ones
  • ensure your CNG-managed native projects reference the committed lockfiles and don't generate them on the fly with every expo prebuild
  • setup a Gradle lockfile for your Android project

Not convinced? Read more about why this exists below.

Getting started

  • yarn add -D expo-native-lockfiles
  • add expo-native-lockfiles as a plugin to your app.json or app.config.js (see example)
  • setup an update approach of either:
    1. a CI check job that asserts that your native lockfiles didn't change (recommended)
    2. a postinstall step for your JS dependencies (quicker, slows down dependency installs)

CLI Command

expo-native-lockfiles CLI
Usage: yarn native-lock [subcommand]

Subcommands:
  check: Check if lockfiles after prebuild are the same as those in the root of the repo.
  write: Write the lockfiles generated after prebuild to the root of the repo.
  help: Print this help message.

Options:
  --android: Generate or check a lockfile for Android (opt-in).
  --non-interactive: Skip interactive prompts (assumes 'yes').
  --debug: Print debug information.

Lockfile Update Approaches

Choose one of the following approaches to keep your native lockfiles up to date and committed to your repository.

CI check

A CI-based check that runs whenever your yarn.lock changes might be the least intrusive way to ensure your native lockfiles stay in sync with any JS-based dependency changes.

Postinstall step

The easiest approach to setup, but least efficient is to add yarn native-lock write to your postinstall script in your package.json.

Why this exists

You may notice the occasional drift in native dependencies with Expo's Managed Workflow (also known as Continuous Native Generation, "CNG") given that only the javascript dependency tree has dependency versions locked. This leaves the door open for the following scenario:

  • javascript dependency relies on a native dependency with unfixed version
    • for example: iOS podspec has ~> 1.0 which means 1.1 would be an acceptable version
  • the JS dependency's native dependency issues an update within the range of acceptable versions
  • you run a build on EAS or expo prebuild and your project is generated, along with its native lockfile, based on the native dependency constraints dictated by your javascript dependency
    • in the above example, you may have previously has 1.0 for that native dependency in your ios/Podfile.lock but now it would be 1.1, meaning that while your JS dependency hasn't changed, it's underlying native dependency has

The above may be desirable if you're OK with the risk that the underlying dependency does not use semantic versioning correctly and maintains backwards compatibility. Even if the version bump is not a breaking change it may have undesirable or unexpected runtime characteristics. This risk increases if the maintainer of the JS dependency is not also the maintainer of the native dependency it uses.

It can also be good to have visibility into the state of native dependencies for security scanning or supply chain management (SAST scans). With the recommended approach of ignoring the native project folders under CNG, you have no visibility into what dependencies your yarn lockfile-defined dependencies are pulling in.

A note on gradle.lockfile

React Native dependencies on Android aren't really dependencies but instead are "sub projects" that are included into the main "app" project. This structure is termed a Composite Build. Gradle's locking mechanism does not support composite builds out of the box. More work on this to follow.

Roadmap to v1

Things to iron out:

  • [x] get full scenario CI test workflow passing (issue w/ plugin always writing?)
  • [x] make android opt-in for now (composite builds aren't covered by "app" lockfile so it's a partial picture)
  • [ ] make xcode version (and others?) clearer and configurable
  • [ ] allow for running for a specific platform
  • [ ] provide better API or guidance for upgrade path (Expo / React Native bumps)
  • [ ] figure out how to speed up the gradle lockfile write (--offline w/ cache?)
  • [ ] add a simple readme example for CI check config
  • [ ] merging gradle lockfiles of all composite build projects beyond just "app"