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

appium-session-recorder

v0.0.4

Published

Interactive Appium session recorder with modern UI

Readme

Appium Session Recorder

A modern Appium recorder and automation CLI with real-time UI visualization, session navigation commands, and selector ranking. Built with Bun, Solid.js, and Kobalte.

Workflow Demo

✨ Features

  • 🎬 Session Recording: Intercepts and logs Appium commands (currently focused on POST /session/:sessionId/*)
  • 📸 Screenshot Capture: Automatically captures screenshots after actions
  • 🤖 JSON-First Command Mode: Scriptable subcommands for agent workflows (session, screen, selectors, drive)
  • 🧭 CLI App Navigation: Drive taps, typing, back navigation, and swipe gestures via Appium
  • 🏆 Best Selector Ranking: Heuristic ranking with strategy scoring + match counts + reason codes
  • 🔍 Element Inspector: Interactive element inspection with multiple locator strategies
  • 🎯 Query Tester: Test locators in real-time on captured screenshots
  • 📊 Real-time Updates: Live dashboard with Server-Sent Events
  • 🎨 Modern UI: Beautiful dark theme with vibrant accents using Solid.js + Kobalte
  • Fast: Built with Bun for optimal performance
  • 🛠️ Interactive CLI: Beautiful prompts for easy configuration

🚀 Quick Start

Prerequisites

Start Appium Server

Start the Appium server (CORS is only needed if you plan to call Appium directly from a browser):

appium --port 4723 --allow-cors

The recorder proxy itself does not require --allow-cors for normal usage.

Installation

npm i -g appium-session-recorder

Run the CLI

appium-recorder

The CLI will interactively prompt you for:

  • Proxy port (default: 4724)
  • Proxy host (default: 127.0.0.1)
  • Appium server URL (default: http://127.0.0.1:4723)

Alternatively, use command-line arguments:

appium-recorder --port 8080 --appium-url http://192.168.1.100:4723

Or run command mode (JSON output by default):

appium-recorder session create --appium-url http://127.0.0.1:4723 --caps-file ./caps.json --pretty

Configure Appium Inspector

Point Appium Inspector to the recorder proxy:

| Setting | Value | |---------|-------| | Remote Host | 127.0.0.1 | | Remote Port | 4724 (or your configured port) | | Remote Path | / |

Access the UI

Open your browser to:

http://localhost:4724/_recorder

📖 Usage

Security (Local-Only Tool)

This project is intended for local testing and development. It runs an unauthenticated proxy/UI that can forward commands to Appium. For normal usage, keep it bound to localhost and do not expose it to untrusted networks.

Current known gaps (will be addressed in future updates):

  • Missing validation for sessionId
  • Missing validation for appiumUrl
  • Rate limiting for API endpoints
  • Authentication/authorization (likely optional, since local-by-default is intentional)

Practical guidance:

  • Run the recorder on 127.0.0.1 only (default) and avoid port-forwarding/sharing the port.
  • Be cautious with appium --allow-cors; treat the recorder + Appium as a local dev surface while running.
  • Page source is untrusted input; XML is rendered as text (not HTML) to mitigate XSS.

Command Mode (JSON)

appium-recorder <group> <command> [flags]

Available command groups:

  • proxy start
  • session create|delete
  • screen snapshot|elements
  • selectors best
  • drive tap|type|back|swipe

Global command flags:

  • --pretty pretty-print JSON
  • --output <path> persist JSON output to a file
  • Legacy mode (appium-recorder [legacy-options]) does not accept --pretty or --output

Agent Skill

This repo includes a reusable Codex skill at:

  • skills/appium-cli-selector-navigator/SKILL.md

The skill is designed for CLI-only navigation + selector discovery loops.

Skill Runbook (What To Run)

Use this when you want to drive the app and find selectors with $appium-cli-selector-navigator.

  1. Start Appium:
appium --port 4723 --allow-cors
  1. (Optional) Install skill globally for Codex:
mkdir -p ~/.claude/skills
cp -R ./skills/appium-cli-selector-navigator ~/.claude/skills/appium-cli-selector-navigator

Restart Claude after installing the global skill.

  1. Create a capabilities file (example iOS Safari):
cat > /tmp/caps.json <<'JSON'
{
  "platformName": "iOS",
  "appium:deviceName": "iPhone 17",
  "appium:platformVersion": "26.2",
  "appium:automationName": "XCUITest",
  "appium:bundleId": "com.apple.mobilesafari",
  "appium:newCommandTimeout": 3600,
  "appium:connectHardwareKeyboard": true,
  "appium:includeSafariInWebviews": true
}
JSON
  1. Create session and capture SESSION_ID:
appium-recorder session create \
  --appium-url http://127.0.0.1:4723 \
  --caps-file /tmp/caps.json \
  --output /tmp/session.json \
  --pretty \
&& SESSION_ID="$(jq -r '.result.sessionId' /tmp/session.json)" \
&& echo "$SESSION_ID"
  1. Fetch current elements and save JSON:
appium-recorder screen elements \
  --appium-url http://127.0.0.1:4723 \
  --session-id "$SESSION_ID" \
  --only-actionable \
  --limit 80 \
  --output /tmp/elements.json \
  --pretty \
&& jq -r '.result.elements[] | [.elementRef, .type, .name, .label, .resourceId] | @tsv' /tmp/elements.json
  1. Pick element and get best selectors:
appium-recorder selectors best \
  --appium-url http://127.0.0.1:4723 \
  --session-id "$SESSION_ID" \
  --element-ref "<ELEMENT_REF>" \
  --pretty
  1. Drive actions (examples):
# Tap an element
appium-recorder drive tap \
  --appium-url http://127.0.0.1:4723 \
  --session-id "$SESSION_ID" \
  --using "accessibility id" --value "Accept all" --pretty

# Type into a field
appium-recorder drive type \
  --appium-url http://127.0.0.1:4723 \
  --session-id "$SESSION_ID" \
  --using "accessibility id" --value "Address" \
  --text "example.com\n" --clear-first --pretty

# Navigate back
appium-recorder drive back \
  --appium-url http://127.0.0.1:4723 \
  --session-id "$SESSION_ID" --pretty

# Swipe gesture
appium-recorder drive swipe \
  --appium-url http://127.0.0.1:4723 \
  --session-id "$SESSION_ID" \
  --from 900,1800 --to 900,400 --duration-ms 350 --pretty
  1. Cleanup session:
appium-recorder session delete \
  --appium-url http://127.0.0.1:4723 \
  --session-id "$SESSION_ID" --pretty

Legacy CLI Options (Backwards Compatible)

appium-recorder [options]

OPTIONS:
  -p, --port <number>        Proxy server port (default: 4724)
  -u, --appium-url <url>     Appium server URL (default: http://127.0.0.1:4723)
  --host <host>              Proxy server host (default: 127.0.0.1)
  -h, --help                 Show help message
  -v, --version              Show version

Configuration priority (highest to lowest):

  1. Command-line arguments
  2. Interactive prompts
  3. Environment variables
  4. Default values

Environment Variables

APPIUM_URL=http://192.168.1.100:4723
PROXY_PORT=8080
PROXY_HOST=127.0.0.1

appium-recorder

🎨 UI Features

Dashboard

  • Total Requests: Count of all intercepted requests
  • Actions: Requests with screenshots (clicks, inputs, etc.)
  • Real-time Updates: Automatically refreshes as you interact

Timeline

  • View all interactions in chronological order
  • Color-coded by HTTP method (mostly POST)
  • Action markers for requests with screenshots
  • Click screenshots to open inspector

Element Inspector

  • Query Tester: Test different locator strategies
    • accessibility id
    • xpath
    • class name
    • iOS predicate string
    • iOS class chain
  • Element Details: View element properties (name, label, value, bounds)
  • Locators: Auto-generated locators ready to copy
  • Click to copy: One-click locator copying

🔧 Development

Setup

git clone https://github.com/JustasMonkev/appium-session-recorder.git
cd appium-session-recorder
bun install

Run from Source

bun run cli

This is equivalent to appium-recorder but runs directly from source. All examples in this README that use appium-recorder can be replaced with bun run cli during development.

Build the UI

cd src/ui
bun run build

Run in Development Mode

# Terminal 1: Build UI in watch mode
cd src/ui
bun run dev

# Terminal 2: Run CLI
bun run cli

Run Tests

bun run test           # Run all tests
bun run test:watch     # Watch mode
bun run test:coverage  # With coverage

Build for Production

bun run build

This builds both the UI and the CLI executable.

📦 What's Recorded

The recorder captures:

  • Element clicks
  • Text input (value)
  • Element clear
  • Find element/elements
  • Touch actions
  • Navigation (back, forward, refresh)

For each action:

  • ✅ Request details (method, path, body)
  • ✅ Screenshot (base64)
  • ✅ Page source (XML)
  • ✅ Timestamp

🎯 Use Cases

  • Test Debugging: Review session history to debug failing tests
  • Element Discovery: Find reliable locators for automation
  • Training: Show team members how to interact with the app
  • Test Recording: Generate test scripts from recorded interactions

🤝 Architecture

┌─────────────────────┐      ┌─────────────────────┐      ┌─────────────────────┐
│  Appium Inspector   │ ──── │  Session Recorder   │ ──── │   Appium Server     │
│  (localhost:4724)   │      │   (Bun + Express)   │      │  (localhost:4723)   │
└─────────────────────┘      └─────────────────────┘      └─────────────────────┘
                                        │
                                        ▼
                              ┌─────────────────────┐
                              │   Web UI (Solid.js) │
                              │  Real-time Updates  │
                              └─────────────────────┘