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

slapify

v0.0.20

Published

AI-powered browser automation — autonomous task agent, performance auditing, and E2E test flows in plain English

Readme

slapify 🖐️

AI-powered browser automation that slaps — run autonomous agents, audit performance, and write E2E tests in plain English.

By slaps.dev


What can it do?

| Mode | What it does | | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | task | Autonomous AI agent — give it any goal, it figures out how to achieve it. Browses, logs in, schedules itself, audits performance, remembers state across runs. | | run | Execute .flow test files — plain-English E2E tests with screenshots and HTML reports |


Installation

npm install -g slapify

# or run without installing
npx slapify init

Quick Start

# 1. Set up your project (interactive — picks LLM, browser, creates sample files)
npx slapify init

# 2. Set your API key
export ANTHROPIC_API_KEY=your-key

# 3a. Run an autonomous task
npx slapify task "Summarise the top posts on reddit.com/r/programming today" --report

# 3b. Run a test flow
npx slapify run tests/example.flow --report

Autonomous Agent (slapify task)

Give it a goal in plain English. The agent decides what to do, browses pages, handles login, retries on errors, and keeps running until the goal is complete — even if that takes hours or days.

CLI

# One-off research
npx slapify task "What is the current gold price?"
npx slapify task "Go to reddit.com/r/programming and summarise the top 5 posts"
npx slapify task "Check https://myapp.com and tell me if anything looks broken"

# Performance audits
npx slapify task "Audit the performance of slaps.dev" --report
npx slapify task "Audit the home, pricing, and about pages on vercel.com" --report

# Long-running / scheduled
npx slapify task "Check my LinkedIn messages every 30 minutes and summarise new ones"
npx slapify task "Monitor https://example.com/status every 5 minutes and alert if down"
npx slapify task "Check BTC price every hour for 24 hours and give me an end-of-day summary"

# Auth-required tasks (agent handles login automatically)
npx slapify task "Log into myapp.com and export my account data"
npx slapify task "Reply to any unread Slack DMs with a friendly holding message"

# Flags
npx slapify task "..." --report           # generate HTML report on exit
npx slapify task "..." --headed            # show the browser window
npx slapify task "..." --debug             # verbose logs
npx slapify task "..." --save-flow         # save steps as a reusable .flow file
npx slapify task "..." --max-iterations N  # cap agent loop iterations (default 400)
npx slapify task "..." --schema <json> --output <file>  # structured JSON output (see below)

Structured output (JSON schema) — Have the agent write data that matches a schema to a file. Use --schema (inline JSON or path to a .json file) and --output (file path). The agent uses a write_output tool to append or update the file whenever it has new data — ideal for recurring tasks that keep updating a report.

# One-shot: write structured data once
npx slapify task "Get top 5 HN posts and their URLs" \
  --schema '{"type":"object","properties":{"posts":{"type":"array"}}}' \
  --output hn.json

# Recurring: schema in a file, agent appends to output each run
npx slapify task "Every day at 9am, collect top tech headlines and add to report" \
  --schema schema.json \
  --output daily-news.json \
  --max-iterations 2000

What the agent can do

| Capability | Details | | ------------------------- | ------------------------------------------------------------------------------ | | Browse & interact | Navigate, click, type, scroll, fill forms, handle popups | | Bypass bot protection | Falls back to HTTP-level requests when the browser is blocked | | Login automatically | Detects login forms, uses saved credential profiles, asks you to save new ones | | Persistent memory | Stores key facts between runs (thread URLs, last-seen items, etc.) | | Schedule itself | Creates its own cron jobs for recurring subtasks | | Ask for input | Pauses and prompts you when it needs information (e.g. OTP, confirmation) | | Performance audit | Scores, web vitals, network analysis, framework detection, re-render testing | | Structured output | Writes JSON conforming to a schema to a file (append/update per run) | | HTML report | Full session report with tool timeline, summaries, and perf data |

Programmatic (JS/TS)

import { runTask } from "slapify";

// Simple one-shot task
const result = await runTask({
  goal: "Go to news.ycombinator.com and return the top 10 headlines",
});

console.log(result.finalSummary);
import { runTask, TaskEvent } from "slapify";

// With real-time events
const result = await runTask({
  goal: "Audit the performance of https://myapp.com/pricing and /about",

  onEvent: (event: TaskEvent) => {
    if (event.type === "message") console.log("Agent:", event.text);
    if (event.type === "status_update") console.log("→", event.message);
    if (event.type === "tool_start") console.log(`  [${event.toolName}]`);
    if (event.type === "done") console.log("✅", event.summary);
  },

  // Called when the agent needs a human answer (e.g. 2FA code, confirmation)
  onHumanInput: async (question, hint) => {
    return await promptUser(question); // plug in your own UI
  },
});
import { runTask } from "slapify";

// Resume a previous session (credentials, memory, and context are preserved)
const result = await runTask({
  goal: "Continue monitoring LinkedIn messages",
  sessionId: "task-2026-02-19T20-19-44-dtbfu",
});
import { runTask } from "slapify";

// Long-running scheduled task — agent sets its own cron internally
await runTask({
  goal:
    "Every hour, check the BTC price and store it. " +
    "After 24 hours, summarise the day's movements.",
  maxIterations: 500,
  onEvent: (e) => {
    if (e.type === "scheduled") console.log(`Scheduled: ${e.cron}`);
    if (e.type === "sleeping") console.log(`Sleeping until: ${e.until}`);
    if (e.type === "done") console.log(e.summary);
  },
});
import { runTask } from "slapify";

// Structured output — agent writes JSON matching the schema to a file
const result = await runTask({
  goal: "Get the current gold price and record it",
  schema: {
    type: "object",
    properties: { price: { type: "number" }, currency: { type: "string" } },
  },
  outputFile: "gold.json",
});
// gold.json is written; result.structuredOutput has the same data
console.log(result.structuredOutput);

Performance Auditing

The agent has a built-in perf_audit tool. Just ask it to check performance — it navigates, injects observers, collects everything, and includes it all in the HTML report.

What's measured

| Category | Metrics | | --------------------- | ---------------------------------------------------------------- | | Real-user metrics | FCP, LCP, CLS, TTFB | | Lab scores | Performance, Accessibility, SEO, Best Practices (0–100) | | Framework | React / Next.js detection, re-render issues, interaction tests | | Network | Total size, JS bundle size, CSS, images | | API calls | Method, URL, status, duration — slow (>500ms) and failed flagged | | Long tasks | JavaScript blocking the main thread (>50ms) | | Memory | JS heap usage |

Multi-page comparison

Audit multiple pages in one command. The HTML report shows a tab bar — one tab per URL, click to switch. Each tab has the full breakdown for that page.

# Three-tab report: /, /pricing, /about
slapify task "Audit the home, pricing, and about pages on vercel.com" --report

Programmatic

import { runPerfAudit } from "slapify/perf";
import { BrowserAgent } from "slapify";

const browser = new BrowserAgent();
await browser.launch();

const result = await runPerfAudit("https://myapp.com/pricing", browser, {
  lighthouse: true, // lab scores — Performance/A11y/SEO/Best Practices (default: true)
  reactScan: true, // framework detection + re-render analysis (default: true)
  navigate: true, // navigate to the URL before auditing (default: true)
});

console.log(result.vitals); // { fcp, lcp, cls, ttfb }
console.log(result.scores); // { performance, accessibility, seo, bestPractices }
console.log(result.react); // { detected, version, issues, interactionTests }
console.log(result.network); // { totalRequests, totalBytes, apiCalls, longTasks, ... }

await browser.close();

Test Flows (slapify run)

Write tests as .flow files in plain English. The AI interprets each line and executes browser actions, with screenshots and auto-retry on failure.

Smart by default

You don't need to spell out every edge case. The runner handles these automatically on every step:

| What happens automatically | How | | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | Cookie banners, popups, chat widgets | Detected and dismissed before they block the next step | | CAPTCHAs | Detected by page content signals (reCAPTCHA, hCaptcha, Cloudflare Turnstile) and solved automatically | | Credential lookup | Steps like Log in or Sign in (no profile named) auto-pick the best matching profile for the current domain, falling back to default | | Auto-retry | Failed steps are retried once before being marked failed |

Writing .flow files

# tests/checkout.flow

Go to https://myshop.com
[Optional] Close cookie banner
Click "Add to Cart" on the first product
Go to checkout
Log in                              # picks the right credential profile automatically
Fill shipping address
Click "Place Order"
Verify "Order confirmed" appears

Syntax reference:

| Syntax | Example | | ---------------- | ------------------------------------------------ | | Comment | # This is a comment | | Required step | Click the login button | | Optional step | [Optional] Close popup | | Conditional | If "Accept cookies" appears, click Accept | | Named credential | Login with admin credentials | | Auto credential | Log in — picks best profile for current domain | | Assertion | Verify "Welcome" message appears |

CLI

# Run a single flow
slapify run tests/login.flow

# Run all flows in a directory
slapify run tests/

# With visible browser
slapify run tests/ --headed

# Generate HTML report with screenshots
slapify run tests/ --report

# Include performance audit in the report
slapify run tests/ --report --performance

# Run in parallel (4 workers by default)
slapify run tests/ --parallel

# Run in parallel with 8 workers
slapify run tests/ --parallel --workers 8

# Auto-fix a failing flow
slapify fix tests/broken.flow

# Other utilities
slapify list             # list all flow files
slapify validate         # validate flow syntax
slapify create my-test   # create a blank flow

Generating flows

Instead of writing flows by hand, use generate to have the agent discover the real path by actually running it in the browser — handles login, captcha, and dynamic content automatically, and only records steps that worked.

# Agent runs the goal, saves verified steps to tests/
slapify generate "test the login flow on github.com"

# Save to a specific directory
slapify generate "test checkout on myshop.com" --dir tests/checkout

# With visible browser
slapify generate "sign up flow on myapp.com" --headed

This is equivalent to slapify task "..." --save-flow --dir tests/ — the saved .flow file is proven to work, not just AI-guessed from a page snapshot.

Programmatic (JS/TS)

import { Slapify } from "slapify";

const slapify = new Slapify({ configDir: ".slapify" });

// Run inline steps
const result = await slapify.run(
  [
    "Go to https://example.com",
    'Click "More information"',
    'Verify URL contains "iana.org"',
  ],
  "example-test"
);

console.log(result.status); // 'passed' | 'failed'
console.log(result.passedSteps); // number
console.log(result.duration); // ms
// Run from file
const result = await slapify.runFile("./tests/checkout.flow");

// Run multiple — sequential
const results = await slapify.runMultiple([
  "tests/login.flow",
  "tests/checkout.flow",
]);

// Run multiple — parallel
const results = await slapify.runMultiple(["tests/"], {
  parallel: true,
  workers: 4,
});
// Step-level callbacks
const result = await slapify.run(steps, "my-test", {
  onTestStart: (name, totalSteps) =>
    console.log(`Starting ${name} (${totalSteps} steps)`),
  onStep: (stepResult) => {
    const icon = stepResult.status === "passed" ? "✓" : "✗";
    console.log(`  ${icon} ${stepResult.step.text}`);
  },
  onTestComplete: (result) => console.log(`Done: ${result.status}`),
});
// Save reports
const reportPath = slapify.saveReport(result); // single test
const suiteReport = slapify.saveSuiteReport(results); // full suite
const html = slapify.generateReport(result); // HTML as string

Jest / Vitest integration

import { Slapify } from "slapify";

const slapify = new Slapify({ configDir: ".slapify" });

test("user can log in", async () => {
  const result = await slapify.run(
    [
      "Go to https://myapp.com/login",
      "Fill email with [email protected]",
      "Fill password with secret123",
      "Click Login",
      'Verify "Dashboard" appears',
    ],
    "login-test"
  );
  expect(result.status).toBe("passed");
}, 60_000);

test("checkout flow", async () => {
  const result = await slapify.runFile("tests/checkout.flow");
  expect(result.failedSteps).toBe(0);
}, 120_000);

Credential Management

Slapify handles credentials for any site — login forms, OAuth, or injecting an existing session.

.slapify/credentials.yaml

profiles:
  default:
    type: login-form
    username: ${TEST_USERNAME}
    password: ${TEST_PASSWORD}

  admin:
    type: login-form
    username: [email protected]
    password: ${ADMIN_PASSWORD}
    totp_secret: JBSWY3DPEHPK3PXP # TOTP 2FA

  # Skip login entirely — inject an existing session
  my-session:
    type: inject
    cookies:
      - name: auth_token
        value: ${AUTH_TOKEN}
        domain: .example.com
    localStorage:
      user_id: "12345"
      theme: dark

In task mode, credentials are fully automatic:

  • The agent detects login forms and picks the right profile
  • If no profile matches, it asks you to enter credentials and offers to save them
  • Saved sessions are reused on future runs — no re-login needed

Configuration

.slapify/config.yaml

llm:
  provider: anthropic
  model: claude-haiku-4-5-20251001 # fast & cheap — recommended
  api_key: ${ANTHROPIC_API_KEY}

browser:
  headless: true
  timeout: 30000
  viewport:
    width: 1280
    height: 720

report:
  format: html
  screenshots: true
  output_dir: ./test-reports

LLM Providers

Supports 6 providers via Vercel AI SDK.

Budget-friendly (recommended)

# Anthropic — Claude Haiku 4.5 (fast, ~$1/5M tokens)
llm:
  provider: anthropic
  model: claude-haiku-4-5-20251001
  api_key: ${ANTHROPIC_API_KEY}

# OpenAI — GPT-4o Mini
llm:
  provider: openai
  model: gpt-4o-mini
  api_key: ${OPENAI_API_KEY}

# Google — Gemini 2.0 Flash (generous free tier)
llm:
  provider: google
  model: gemini-2.0-flash
  api_key: ${GOOGLE_API_KEY}

# Groq — free tier available
llm:
  provider: groq
  model: llama-3.3-70b-versatile
  api_key: ${GROQ_API_KEY}

More capable

# Anthropic — Claude Sonnet
llm:
  provider: anthropic
  model: claude-sonnet-4-20250514

# OpenAI — GPT-4o
llm:
  provider: openai
  model: gpt-4o

Local (no API key)

# Ollama — runs on your machine, completely free
llm:
  provider: ollama
  model: llama3 # or mistral, codellama, phi3
  base_url: http://localhost:11434/v1

Project Structure

your-project/
├── .slapify/
│   ├── config.yaml          # LLM + browser + report settings
│   ├── credentials.yaml     # Saved login profiles
│   └── tasks/               # Persisted agent sessions (auto-created)
│       └── task-2026-....jsonl
├── tests/
│   ├── auth/
│   │   ├── login.flow
│   │   └── signup.flow
│   └── checkout.flow
└── test-reports/            # HTML reports
    └── login-1234567890/
        ├── report.html
        └── screenshots/

Requirements

  • Node.js 18+
  • agent-browser (installed as a peer dependency)

License

MIT — Made with 🖐️ by slaps.dev