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

@expo/agent-cli

v1.0.22

Published

Agent-native CLI on top of the Expo CLI family

Readme

@expo/agent-cli

Agent-native CLI on top of the Expo CLI family. Coding agents (and humans) use it to run Expo workflows and get machine-readable answers. It runs expo, eas-cli, expo-doctor, and friends as subprocesses. It does not import their internals.

Design documents: llp/0001-agentic-cli-on-expo-cli.rfc.md and its child LLPs in this package.

Start here

| Step | Command | Gets you | | ---------------------------- | ----------------------------------------- | ---------------------------------------------- | | 1. Check the project | npx @expo/agent-cli status | what this project is, and what to run next | | 2. Start the app | npx @expo/agent-cli dev --ios --detach | the dev server starts, the terminal comes back | | | npx @expo/agent-cli navigate / | the app opens a route, on a device | | 3. Edit and reload | npx @expo/agent-cli runtime:reload | after your edit, the app runs the code on disk | | | npx @expo/agent-cli runtime:errors | what it threw, over a time window | | | npx @expo/agent-cli runtime:tree | what is on screen, and its testIDs | | 4. Verify before you're done | npx @expo/agent-cli smoke --ios | the app on the code on disk, and one exit code | | | npx @expo/agent-cli typecheck | the type errors neither of those can see | | 5. Release | npx @expo/agent-cli deploy | the web app to EAS Hosting | | One-time setup | npx @expo/agent-cli new my-app | create a project | | | npx @expo/agent-cli install expo-sqlite | add a package at the version this SDK wants | | | npx @expo/agent-cli agents:setup | confirm agent setup for a project or user home |

npx @expo/agent-cli help workflow is this loop in one screen, plus exit codes, --json, and what to do when a command fails.

npx @expo/agent-cli -h lists every command. Each command's --help has the same shape: purpose, options, examples, what to run next, and the --json keys.

Commands

| Command | What it does | | -------------------------------------------------------------- | --------------------------------------------------------------------------- | | new | Create a project without prompts | | install / add | Run expo install, then sync that package's skills | | status | What this project is, whether a rebuild is needed, what to run next | | dev | Plan how to get the app on a device, then do it. --eas does it all on EAS | | start | expo start and nothing else, then sync skills | | dev:logs / dev:stop | Read or stop a detached dev server | | navigate | Open a route on a simulator, a device, or EAS Simulator (--eas) | | runtime:reload | Put the running app back on the code on disk | | runtime:errors / runtime:eval | Read runtime errors, or evaluate JS in the running app | | runtime:tree / runtime:tap / runtime:type | Drive the app by testID | | runtime:stop | Stop the app on the device | | smoke | Reload onto the code on disk, open a route, check for errors | | typecheck | The project's own tsc --noEmit | | doctor | expo-doctor, normalized | | deploy | Ship the web app to EAS Hosting, or the native app with --native | | inspect:build-log | Find the line in a native build log that says why it failed | | inspect:config-plugins | What the config plugins produced. Experimental | | agents:setup | Set up Expo agents in a project or user home | | feedback | Send feedback to the Expo team, with agent and project context | | skills:sync / skills:list / skills:show / skills:clean | Discover and link skills shipped by installed modules | | docs:sync / docs:search | The Expo docs for the project's SDK as local Markdown files to grep |

Grouped commands use group:action, the way eas-cli does. The space form is the same command: skills list is skills:list. Bare skills syncs, bare doctor checks, bare dev runs the plan.

Commands this CLI does not wrap go to the project's expo CLI: run, run:ios, run:android, prebuild, config, export, export:web, export:embed, serve, customize, lint, login, logout, register, whoami.

Send feedback

Use npx --yes @expo/agent-cli feedback in place of npx --yes submit-expo-feedback:

npx --yes @expo/agent-cli feedback --message "Please explain how to recover when the dev server disconnects."
npx --yes @expo/agent-cli feedback --category skills --subject expo-router --message "Please add an example of nested routes with shared layouts."
npx --yes @expo/agent-cli feedback --resume abc123 --message "The issue also happens after restarting the development server."

Messages must contain 40–5,000 characters. --message/-m, --category/-c, --subject/-s, and --resume retain the standalone CLI's behavior. Positional messages are still accepted with a deprecation warning. Without a message, the command prompts in an interactive terminal; agents and CI should pass --message. --json prints { "sent": true, "feedbackId": "…" } after a successful submission.

Categories are skills, expo-cli, eas-cli, agent-cli, mcp, docs, evals, simulator, and unknown (the default). For agent-cli, use the full command as the subject, such as npx @expo/agent-cli status. Other subjects identify the exact skill, documentation URL, MCP tool, CLI command, package, simulator workflow, or topic involved.

Feedback uses the same Expo endpoint and request format as submit-expo-feedback, including agent, sandbox, environment, and Expo project metadata. It uses EXPO_TOKEN or the saved Expo session when available; authenticated feedback is associated with that account. DO_NOT_TRACK=1 or EXPO_NO_TELEMETRY=1 skips submission and metadata collection (--json reports { "sent": false, "feedbackId": null }).

Set up a coding agent

Run npx @expo/agent-cli agents:setup to select agents, review the commands, and confirm installation into your user home. It works both inside an Expo app and before creating one. Pass --project to install plugins/skills in the current Expo project instead; this flag requires an Expo app. Package skill synchronization and instruction-file setup still run in that app, even when the plugin installation targets your home.

Use the arrow keys to navigate, Space to toggle agents, and Enter to continue. Detected or previously configured agents start selected. Escape or Ctrl-C cancels setup before installation; the final confirmation defaults to No.

  • Claude Code uses expo@claude-plugins-official with an explicit user/project scope. The official marketplace must already be registered; for a fresh Claude configuration, run claude plugin marketplace add anthropics/claude-plugins-official first.
  • Codex user setup registers expo/skills at main and installs expo@expo-plugins. Codex's plugin CLI has no project scope, so --project installs Expo skills for Codex instead.
  • Other agents use bunx skills add expo/skills --skill '*' (or npx when Bun is unavailable), with the selected agent and scope passed explicitly.
  • Grok Build uses --agent grok and .grok/skills for package skill links. Setup detects .grok in the project or user home (respecting GROK_HOME), and the grok executable. Grok reads AGENTS.md directly.

For automation, accept the plan explicitly:

npx @expo/agent-cli agents:setup --yes --agent codex --json
npx @expo/agent-cli agents:setup --yes --project --agent claude-code --json

--json alone does not accept setup. Without a terminal, omit --yes to receive a confirmation-required error without installing anything. Declining the interactive confirmation leaves files unchanged.

Use --no-plugins to skip official plugin/skills installation, --no-agent-skills to skip package skill synchronization, and --no-agents-md to skip all instruction-file writes. Existing installations are inspected and retained; setup does not run broad updates or replace skills from another source. Use each plugin marketplace or the skills CLI to manage updates. Start a new agent session after installation; MCP tools may require sign-in separately.

The JSON report includes the selected scope, cancelled, per-agent plugins, and errors, alongside the project results, including agentsMd and claudeMd file actions. Outside a project, projectRoot, skills, agentsMd, and claudeMd are null. If an installer fails, independent project setup still runs; the final report preserves completed steps and exits with code 20. Invalid arguments or missing noninteractive confirmation exit with code 1; declining confirmation exits with code 0 and cancelled: true.

Shared project instructions

Setup creates or updates the Expo managed block in the project-root AGENTS.md. It also rewrites Expo command examples to agent-cli for wrapped commands (install, start, and add) and every registered Expo passthrough command, such as prebuild, export, run:ios, and lint. The rewrite keeps supported npx/bunx runner options and command arguments. Bare commands at the start of a line or quoted example use npx; expo-doctor and expo-doctor@latest become agent-cli doctor. Unknown commands and other template and user instructions are preserved. The block directs agents to use agent-cli for equivalent Expo install/start/lint, TypeScript, and expo-doctor operations, including commands suggested by loaded skills; it retains Expo's SDK-compatible package installation and the template's bunx convention for projects with bun.lock.

new writes these same instructions and rewrites the template's Expo command examples after creating a project, including with --no-install. It does not install agent plugins or ask setup questions. Its JSON report includes agentsMd and errors; if instruction generation fails after scaffolding succeeds, created remains true and the command exits with code 20. Run agents:setup in the new project to retry instructions and configure agent skills.

For selected Claude Code agents, setup creates CLAUDE.md with @AGENTS.md, or appends that import to an existing regular file. A plain mention such as “See AGENTS.md” is not a file import. Existing active imports and CLAUDE.md symlinks to AGENTS.md are retained. The reverse layout, AGENTS.md symlinked directly to a regular project-root CLAUDE.md, also shares one managed block without adding a self-import. Other instruction-file symlinks are not written through. See Claude's shared instruction documentation.

The managed block points agents to expo-overview, when available in their skill list, as the entry point for choosing an Expo or EAS skill. It refers to the skill by name without copying its routing map or embedding installation paths. A Package / Skill / Read table follows for verified, linked package skills. Links are project-relative and point to SKILL.md; missing links, user-owned conflicts, and losing duplicate names are omitted. Multiple skills from one package get separate rows. Plugins and standalone skills installed from expo/skills remain owned by their installers and are outside this package-skill index.

After setup creates the index, skills:sync, automatic skill sync during install/start/dev, and skills:clean refresh only its marked section. Other instructions and project facts stay unchanged. Dry runs never refresh it, and these commands do not create instruction files or add an index to a file that setup has not opted in. Rerunning setup upgrades an older managed block to include the index.

Package skill synchronization

Package skills follow skills/<name>/SKILL.md inside installed dependencies. Discovery walks the dependency graph through Expo autolinking. Sync creates relative directory symlinks (junctions on Windows) in the selected agents' directories: .claude/skills, .agents/skills, or .grok/skills. It updates the generated .gitignore entries and any existing package-skill index. These commands call the shared linking implementation directly; they do not spawn a skills:sync subprocess.

Automatic sync uses the saved agent selection in .expo/agent-skill-links.json when present; otherwise it detects agents from marker directories in the project or user home. Installing a package in a freshly created app therefore links its skills for detected agents without requiring setup first. Detection is recomputed each run and is not saved. Successful project agents:setup with package skills enabled, or skills:sync --agent codex, saves an explicit selection that takes precedence over detection. Repeat --agent for other agents; dry runs do not save a selection. With no saved or detected agents, automatic sync does nothing.

| Entry point | When package skills sync | | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | install <packages> / add <packages> | After a successful install, link skills from the named packages; do not prune unrelated links. | | Bare install / install --fix without package names | After success, full sync, including pruning stale managed links. | | start / foreground dev | Full sync scheduled three seconds after spawning a dev-server step, including run:ios/run:android steps selected by dev. Cancelled if the server exits before the delay. | | dev --detach | The new child runs the same dev sync; reusing an existing server does not trigger another sync. | | smoke | Only indirectly, when bootstrapping a new detached dev server. Reusing a server or --no-start does not trigger sync. Smoke does not wait for skill sync to finish. | | agents:setup | Explicit full sync for the selected agents when a project is available and package skills are enabled. | | skills / skills:sync | Explicit full sync using flags, saved selection, or detection; stale links are pruned even when no skills remain. |

install --check, failed installs, and dev --plan do not sync. --no-agent-skills disables the hook on install/start/dev. Direct passthrough commands such as run:ios, run:android, and prebuild, plain expo commands, and package-manager installs do not run this hook. new writes project instructions but does not configure or link package skills. status, skills:list, and skills:show inspect skills without linking them; skills:clean removes managed links.

Install also prints the named packages' skill contents when a driving agent is detected, independently of whether a selection was saved. --no-skill-context, --no-agent-skills, and JSON mode suppress that text; JSON reports package names under skillPackages, not skill contents or proof that links were created. No package skills means nothing new to link. Automatic sync failures are best-effort and do not fail a successful install or dev server; explicit sync reports errors. Linking makes skill files available on disk; whether an already-running agent notices them depends on that agent.

Config

Flags beat package.json. package.json beats detection. Unknown keys are errors.

{
  "expo": {
    "agent-cli": {
      "target": "dev-build",
      "buildBackend": "eas",
      "android": { "buildBackend": "local" }
    }
  }
}

target is expo-go or dev-build. buildBackend says where a build runs: local or eas. deviceBackend says where the app runs: local, or eas for an EAS Simulator session. An ios or android key overrides either backend for that platform.

deviceBackend: "eas" makes dev take the --eas route, and smoke too when it starts its own dev server. It also builds on EAS, because a session can only install a build EAS made, so buildBackend: "local" with it is an error. navigate, runtime:reload, runtime:stop and dev:stop do not read it: they use what runs, and reach a session through --eas. The config is committed, so everyone who runs dev in the repo starts a billed session. dev --local keeps the build and the app on this machine.

Notes

  • A machine that cannot build locally (no Xcode, no Android SDK, a Windows host asked for iOS) is never routed to EAS on its own: dev and smoke stop and name --eas, because an EAS build and an EAS Simulator session use EAS credits. Pass --eas, or set buildBackend or deviceBackend to "eas" in the config, to take that route.
  • smoke --ios --eas gates the app on this project's EAS Simulator session: it reuses the session in progress, or starts one with Expo Go or the finished EAS build of this fingerprint and ends it afterwards (start-session phase). It never builds; a development build with nothing finished on EAS is a failure naming dev --ios --eas. dev:stop --eas ends the session too.
  • dev --ios --eas runs everything on EAS: the dev server is tunnelled, a build (when one is needed) is the development-simulator profile on EAS Build — added to eas.json when missing, skipped when EAS already has a finished build of this fingerprint — and the app is opened on this project's EAS Simulator session, which is started with Expo Go or that build when none is up. A session bills until npx --yes eas-cli simulator:stop. --eas on smoke, navigate, runtime:reload and runtime:stop names that session as the device.
  • Expo Go on Android has no debugger. Use a development build to drive the app there.
  • runtime:tree, runtime:tap, and runtime:type call the app's props. They do not touch the screen. They need a development bundle.
  • smoke reloads an app that is already running before it reads it, because that app is holding the bundle from before your edit. A reload it cannot prove is exit 22, never a pass. Pass --no-reload to read the app where it is.
  • smoke makes sure the simulator has the Expo Go your SDK ships, for a project that runs in Expo Go and is not set to dev-build. Missing, older or newer all get replaced with the right release, the way expo start does. Under --no-start nothing is installed, and a wrong version is reported instead of a pass.
  • smoke checks that the app that answered is one your project can actually run. Expo Go holding a project whose native code its runtime does not have, or an Expo Go from a different SDK release line, is exit 22 with the build command named — never a pass. An Expo Go an update behind on the same line is reported and does not fail the run.
  • smoke does not run on web. A browser is not in the debugger target list.
  • A cloud simulator needs a tunnelled dev server. Localhost is refused.

The rest of the limits live in each command's --help.

Telemetry

The CLI sends command-usage events to Expo's shared telemetry service, identified as expo/agent-cli. Events include the canonical command name, CLI and system versions, an anonymous installation ID, a hashed cached user ID when available, and agent/sandbox context from agent-cli-detector and sandbox-cli-detector. Command arguments, project contents, credentials, output, and the local LOG_EVENTS stream are not uploaded. Help and version requests are excluded.

Delivery runs in a detached worker with a three-second deadline; commands never wait for a network response. Set EXPO_NO_TELEMETRY=1 or EXPO_OFFLINE=1 to disable it.

Status

Experimental. Commands and output formats may change.