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

unblock-jitpack-expo

v0.1.0

Published

Rescue an Android / Expo / React Native Gradle build when jitpack.io (or any Maven repo) is unreachable — vendors the artifact into android/local-maven and wires it via Gradle exclusiveContent.

Readme

unblock-jitpack-expo

Rescue an Android / Expo / React Native Gradle build when jitpack.io (or any other Maven repo) is unreachable — vendor the failing artifact into your repo and route Gradle around the blocked upstream via exclusiveContent.

If you've hit this — usually on some Indian ISPs (Jio / Airtel / ACT), on a corporate proxy, or on airgapped CI — you know the pain:

Could not resolve com.github.Dimezis:BlurView:version-2.0.6.
  > Could not GET 'https://www.jitpack.io/com/github/Dimezis/BlurView/...'.
    > Connect to www.jitpack.io:443 [104.26.x.x, ...] failed: Connection timed out

The dependency is fine. The path to it is not. This CLI fixes it once and for all: it copies the artifact from your Gradle cache into android/local-maven/, patches android/build.gradle with an exclusiveContent block that scopes ONLY that coord to the local repo, and leaves everything else on google() / mavenCentral() / jitpack untouched.


Fix in under a second

Grab the failing coord straight from your Gradle error (the Could not resolve <group>:<artifact>:<version> line) and run:

npx unblock-jitpack-expo@latest add <your-group>:<your-artifact>:<your-version> --yes

Concrete example (this one happens to be BlurView, but any Maven coordinate works — .aar Android libs, .jar Java libs, any version string):

npx unblock-jitpack-expo@latest add com.github.Dimezis:BlurView:version-2.0.6 --yes

Or run it with no coord and paste the whole error line when prompted — the CLI extracts the coord for you.

Under the hood: copy the artifact from your local Gradle cache into android/local-maven/, patch android/build.gradle with a scoped exclusiveContent block. Done in ~300 ms.

What it looks like

› Project: my-expo-app
  android/ : android
  build.gradle : android\build.gradle
────────────────────────────────────────────────────────────
[1/1] Vendoring com.github.Dimezis:BlurView:version-2.0.6
✔ Copied 3 file(s) into android\local-maven\com\github\Dimezis\BlurView\version-2.0.6/
› Patching android\build.gradle ...
✔   inserted managed exclusiveContent block into repositories { }
  wired: com.github.Dimezis:BlurView
✔ Wrote android\local-maven\README.md
────────────────────────────────────────────────────────────
✔ Done. Verify with:
  cd android && ./gradlew :app:dependencies --configuration debugRuntimeClasspath | rg BlurView
  npx expo run:android

Install & run — pick your package manager

You don't need to install anything globally. Run it directly with the runner that ships with your package manager. Always pin @latest so you pick up new heuristics and bug fixes.

# npm
npx unblock-jitpack-expo@latest

# pnpm
pnpm dlx unblock-jitpack-expo@latest

# yarn (>= 2 / berry)
yarn dlx unblock-jitpack-expo@latest

# bun
bunx unblock-jitpack-expo@latest

Or install it globally if you'll use it a lot:

npm i -g unblock-jitpack-expo
pnpm add -g unblock-jitpack-expo
bun add -g unblock-jitpack-expo

The CLI will also tell you when a new version is available (once a day at most, cached; never blocks the run). Follow the printed hint — a npx unblock-jitpack-expo@latest ... invocation will grab it.


What it does

Run from your Expo / React Native / bare-Android project root and:

  1. Detects your project layout (package.json, android/, android/build.gradle or .kts) and refuses to run outside a valid app directory.

  2. Takes the failing Maven coord — as a positional argument, from a --log <file> build log, or from a pasted line in interactive mode.

  3. Finds the artifact (.aar / .jar + .pom + optional .module) in your local Gradle cache (~/.gradle/caches/modules-2/files-2.1/...) and copies it into android/local-maven/<group-as-path>/<artifact>/<version>/.

  4. Patches android/build.gradle (or .kts) with a managed exclusiveContent block that includes ONLY your vendored coord(s):

    allprojects {
      repositories {
        // >>> unblock-jitpack-expo: BEGIN (managed - do not edit by hand) <<<
        exclusiveContent {
          forRepository {
            maven {
              name = "UnblockJitpackLocalMaven"
              url = uri("${rootProject.projectDir}/local-maven")
              metadataSources { mavenPom(); gradleMetadata() }
            }
          }
          filter {
            // one includeModule() per coord you added; example shown:
            includeModule('com.github.Dimezis', 'BlurView')
          }
        }
        // <<< unblock-jitpack-expo: END >>>
        google()
        mavenCentral()
        maven { url 'https://www.jitpack.io' }  // left in place for other coords
      }
    }
  5. Writes android/local-maven/README.md and adds an un-ignore rule to .gitignore / .easignore if either would sweep away vendored .aar files.

  6. Prints a verification command you can paste back into the terminal.

The block is idempotent — re-running with more coords merges into the same block; it never duplicates.


Common usage

Non-interactive with the coord you already saw in the error (fastest, CI-safe):

npx unblock-jitpack-expo@latest add com.github.Dimezis:BlurView:version-2.0.6 --yes

Interactive — run with no args, paste the coord (or the whole error line) when prompted:

npx unblock-jitpack-expo@latest

Multiple coords at once:

npx unblock-jitpack-expo@latest add \
  com.github.Dimezis:BlurView:version-2.0.6 \
  com.github.SomeOrg:some-lib:1.2.3 --yes

Extract coords from an existing Gradle log file:

./gradlew :app:assembleDebug 2> build.log || true
npx unblock-jitpack-expo@latest add --log build.log --yes

Also vendor runtime transitive deps found in the .pom:

npx unblock-jitpack-expo@latest add com.github.Dimezis:BlurView:version-2.0.6 --recurse --yes

Check reachability of a Maven host from this machine:

npx unblock-jitpack-expo@latest check-host www.jitpack.io

Verify an existing vendored setup:

npx unblock-jitpack-expo@latest doctor

Point at a project outside cwd:

npx unblock-jitpack-expo@latest --cwd ~/apps/my-expo-app add com.github.Dimezis:BlurView:version-2.0.6 --yes

Full flag reference:

Options:
  -v, --version           Print CLI version and exit
      --yes               Non-interactive: assume yes for all prompts
      --verbose           Verbose diagnostic logging
      --no-banner         Suppress the startup banner
      --cwd <dir>         Project root to operate on (defaults to auto-detected)

Commands:
  (default)               Interactive: prompt for a coord and apply the fix.

  add <coord...>          Vendor coord(s) and wire them into build.gradle.
    --log <file>          Also pull coords from a Gradle build log file
    --recurse             Also vendor runtime deps found in the .pom

  doctor                  Verify the vendored setup is coherent

  check-host [host]       TCP-test a Maven host (default: www.jitpack.io)
    -p, --port <port>     TCP port (default: 443)

What if the coord isn't in my Gradle cache yet?

The artifact must have been downloaded at least once on a network that can reach the upstream repo. Priority order:

  1. VPN / phone tether — enable it, run cd android && ./gradlew :app:assembleDebug --refresh-dependencies once (even if the build later fails), then re-run this CLI.
  2. Copy from a teammate — copy ~/.gradle/caches/modules-2/files-2.1/<group>/<artifact>/<version>/ into the same path locally, then re-run.
  3. Manual mirror — download .aar and .pom from mvnrepository.com or a Sonatype/Nexus mirror, drop them into android/local-maven/<group-as-path>/<artifact>/<version>/, then re-run add with the same coord to write the build.gradle block.

The CLI never touches the network for artifact bytes on its own; you keep control over that step.


Requirements

  • Node.js ≥ 18.17 (uses stable ESM and native fs APIs)
  • A project with:
    • package.json at the project root
    • android/ directory (from npx expo prebuild or a bare RN project)
    • android/build.gradle (Groovy) or android/build.gradle.kts (Kotlin DSL)

Works from any package manager runner: npx, pnpm dlx, yarn dlx, bunx. No lockfile changes to your project.


Compatibility notes

  • Expo prebuild: expo prebuild --clean wipes android/. If you run that regularly, either keep vendored artifacts under source control (they're small; .aar files are typically < 500 KB) or wrap the vendoring in an Expo config plugin. android/local-maven/README.md is written by the CLI so the intent is discoverable to future you.
  • EAS Build (remote): works as long as android/local-maven/** is committed to git and not excluded by .easignore. The CLI adds the un-ignore rule for you if it detects an exclusion.
  • Kotlin DSL: android/build.gradle.kts is supported. The CLI emits KTS syntax when it detects a .kts root build script.
  • Multiple coords / repeat runs: safe. The managed block is merged, not duplicated. Bumping a version is <version>/-folder rename + re-running add with the new coord (the block is keyed on group:artifact, so includeModule doesn't need to change).

Why exclusiveContent and not flatDir or removing the upstream repo?

  • flatDir skips .pom metadata, so transitive deps disappear and you get cryptic NoClassDefFoundError at runtime.
  • Removing the upstream repo from allprojects.repositories breaks resolution for every other coord that legitimately lives on jitpack.
  • exclusiveContent is explicit, greppable, and Gradle-native: it says "for these specific coords, look ONLY here", and everything else routes through your existing repo declarations untouched.

Contributing

Issues and PRs welcome. The CLI is intentionally dependency-light so it stays snappy for npx first-use latency.

git clone https://github.com/nikhildhawan/unblock-jitpack-expo
cd unblock-jitpack-expo
npm install
npm run build
node dist/cli.js --help

License

MIT. See LICENSE.