ariya/phantomjs
Scriptable Headless Browser
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓23+ active contributors
- ✓Distributed ownership (top contributor 44% of recent commits)
- ✓BSD-3-Clause licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 3y ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/ariya/phantomjs)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/ariya/phantomjs on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: ariya/phantomjs
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ariya/phantomjs shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 23+ active contributors
- Distributed ownership (top contributor 44% of recent commits)
- BSD-3-Clause licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 3y ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live ariya/phantomjs
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/ariya/phantomjs.
What it runs against: a local clone of ariya/phantomjs — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in ariya/phantomjs | Confirms the artifact applies here, not a fork |
| 2 | License is still BSD-3-Clause | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 1289 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ariya/phantomjs. If you don't
# have one yet, run these first:
#
# git clone https://github.com/ariya/phantomjs.git
# cd phantomjs
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of ariya/phantomjs and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ariya/phantomjs(\\.git)?\\b" \\
&& ok "origin remote is ariya/phantomjs" \\
|| miss "origin remote is not ariya/phantomjs (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(BSD-3-Clause)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"BSD-3-Clause\"" package.json 2>/dev/null) \\
&& ok "license is BSD-3-Clause" \\
|| miss "license drift — was BSD-3-Clause at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1289 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1259d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ariya/phantomjs"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
PhantomJS is a headless WebKit browser scriptable with JavaScript, enabling automation and testing of web pages without a GUI. It provides native DOM, CSS, JavaScript, Canvas, and SVG support through a scriptable interface, allowing developers to programmatically capture screenshots, run tests, monitor network traffic, and automate page interactions via standard JavaScript APIs. Monolithic C++ application: core PhantomJS engine in src/ integrating WebKit, with JavaScript bindings exposed to user scripts in examples/. Top-level CMakeLists.txt drives cross-platform builds (Windows, Linux, macOS) via .github/workflows/. Examples/ directory contains ~40 standalone .js scripts demonstrating API usage (rasterize.js, netsniff.js, post.js, etc.). Build configured by CMake and legacy configure script.
👥Who it's for
QA engineers and automation specialists who need fast headless browser testing without Chrome/Firefox overhead; CI/CD pipeline maintainers building screenshot services or running web test suites; server-side developers building web graphics tools (chart rasterizers, PDF generators). Also used by data scrapers and performance analysts who need HAR-format network logs.
🌱Maturity & risk
Mature but officially abandoned since 2017 (as noted in the README: 'development is suspended until further notice'). The codebase is stable production-ready code built on WebKit, but no active maintenance, no recent commits visible, and a large backlog of open issues. Do not adopt for new projects; suitable only for maintaining legacy systems.
Critical risk: single maintainer (@ariyahidayat) with suspended development means security vulnerabilities and WebKit issues will not be patched. Heavy C++/C codebase (307k C++ lines) with complex dependencies on outdated WebKit makes contributions risky. No active CI shown for recent commits, and the project explicitly lacks community support going forward.
Active areas of work
Nothing—development is formally suspended. The repository is in maintenance-only/archive mode. Existing issues and pull requests are not being reviewed or merged. The last significant activity was version 2.1.1 release; no active roadmap or milestones.
🚀Get running
Clone and build: git clone https://github.com/ariya/phantomjs.git && cd phantomjs && mkdir build && cd build && cmake .. && make. Then run examples: ./phantomjs ../examples/hello.js. Build requires CMake 2.8.12+, a C++ compiler (GCC/Clang/MSVC per .github/workflows/), and Qt 4/5 headers for WebKit integration.
Daily commands:
No NPM/Yarn; uses CMake. Build: cd build && cmake .. && make (Linux/macOS) or cmake .. -G "Visual Studio 16 2019" (Windows). Run script: ./phantomjs script.js arg1 arg2. See examples/ for runnable demos: ./phantomjs ../examples/rasterize.js http://example.com output.png.
🗺️Map of the codebase
- src/qt/webcontext.cpp: Core JavaScript-to-C++ bridge exposing the phantom, page, and child_process APIs to user scripts
- CMakeLists.txt: Master build configuration defining how WebKit, Qt, and PhantomJS C++ are compiled across platforms
- examples/rasterize.js: Most-used example demonstrating screenshot/PDF capture workflow; de facto reference API documentation
- src/qt/main.cpp: Entry point handling script loading, argument parsing, and Qt application initialization
- .github/workflows/amd64_linux_gcc.yml: CI pipeline showing exact build commands and dependencies needed for Linux builds
- src/qt/webpage.cpp: Page object implementation controlling navigation, rendering, and network callbacks
- examples/netsniff.js: Demonstrates network monitoring API (onResourceRequested, HAR export) for performance analysis
🛠️How to make changes
JavaScript API extensions: edit src/qt/compat/phantomjs-* files and src/qt/webcontext.cpp for new JS methods. New example scripts: add to examples/*.js following patterns in examples/hello.js or examples/rasterize.js. Build system: edit CMakeLists.txt. Platform-specific code: use preprocessor guards in C++ files. Always rebuild with make after changes.
🪤Traps & gotchas
- PhantomJS requires Qt 4.8+ or Qt 5.x headers at build time; headless Linux builds need
mesa-devor similar for OpenGL. 2. Scripts run single-threaded in the Qt event loop; blocking calls will hang the entire process. 3. No async/await support; all async operations use callbacks. 4. WebKit is outdated (Chromium moved to Blink in 2013); modern JavaScript (ES6+), WASM, and current CSS features may not work. 5. SSL certificate validation can silently fail if OpenSSL version mismatches. 6. Exit codes are non-standard; scripts should callphantom.exit(code)explicitly.
💡Concepts to learn
- WebKit rendering engine — PhantomJS embeds WebKit directly; understanding its architecture (layout tree, rendering pipeline, DOM mutation handling) explains why certain CSS or JavaScript features work or fail
- Qt bindings & signal/slot mechanism — PhantomJS uses Qt for cross-platform abstraction and event handling; the C++/JavaScript bridge uses Qt signals to dispatch callbacks, so understanding this pattern is critical for extending the API
- Headless rendering & off-screen rasterization — PhantomJS renders pages without a display server (no X11 on Linux); this requires buffer-based rasterization and FBO (framebuffer object) usage in OpenGL, enabling server-side screenshot generation
- JavaScript engine bindings (QtScript/V8) — PhantomJS exposes C++ objects to JavaScript via bindings layer; understanding how properties/methods marshal between C++ and JS is essential for API design and debugging
- HTTP Archive (HAR) format — examples/netsniff.js generates HAR files for network analysis; HAR is the standard format for exporting web performance data, used by Chrome DevTools and load testing tools
- Sandboxing & process isolation in child_process — PhantomJS supports spawning child processes via child_process API; understanding process boundaries and IPC is critical for security and resource isolation in automation scripts
- CMake cross-platform builds — PhantomJS uses CMake to generate platform-specific builds (MSVC, GCC, Clang, Xcode); CMake is essential for understanding how dependencies (Qt, WebKit, OpenSSL) are configured across Windows/Linux/macOS
🔗Related repos
puppeteer/puppeteer— Modern Chromium-based headless browser automation; direct successor to PhantomJS for new projects with superior performance and standards supportselenium/selenium— Cross-browser automation framework; supports PhantomJS driver but also Chrome, Firefox; industry standard for QA test suitesnightwatchjs/nightwatch— End-to-end testing framework built on Selenium/WebDriver; common choice for replacing PhantomJS in test pipelinesariya/esprima— Created by PhantomJS lead (ariyahidayat); JavaScript parser used internally for script validation; sibling project in same ecosystemariya/escodegen— Code generation from AST by same author; demonstrates patterns similar to PhantomJS C++/JS bridge layer
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for src/childprocess.cpp and src/callback.cpp modules
The repo has multiple workflow files for different platforms (amd64_linux_gcc, amd64_windows_gcc, etc.) but no visible test suite directory. The childprocess and callback modules are critical for PhantomJS functionality but lack documented unit tests. Adding tests would improve code reliability across the CI/CD pipelines and reduce regressions.
- [ ] Create tests/unit/test_childprocess.cpp with tests for child process creation, communication, and teardown
- [ ] Create tests/unit/test_callback.cpp with tests for callback invocation and error handling
- [ ] Update CMakeLists.txt to include test targets and ensure they run in all GitHub Actions workflows
- [ ] Add test results reporting to .github/workflows/amd64_linux_gcc.yml, amd64_windows_gcc.yml, and other platform workflows
Add macOS GitHub Actions workflow and improve cookiejar.cpp handling for cross-platform cookie storage
The repo has workflows for Linux (gcc/clang) and Windows (gcc/clang) but notably lacks a macOS workflow. Additionally, src/cookiejar.cpp likely has platform-specific code for cookie persistence that needs testing on macOS. This is a high-value addition given macOS is a common development platform.
- [ ] Create .github/workflows/amd64_macos_clang.yml following the pattern of existing workflows
- [ ] Add macOS-specific build steps (Xcode/clang setup, Qt framework paths if applicable)
- [ ] Review and document platform-specific code in src/cookiejar.cpp with conditional compilation flags
- [ ] Add macOS test results to repository CI badges in README.md
Create API documentation for examples/ folder and src/config.cpp configuration options
The examples/ folder contains 30+ example scripts (rasterize.js, server.js, netsniff.js, etc.) but lacks a guide explaining what each does and which config.cpp settings control their behavior. A structured documentation file would dramatically improve contributor and user onboarding, especially given the project is in maintenance mode.
- [ ] Create docs/EXAMPLES.md with a table listing each example file with its purpose and sample usage
- [ ] Create docs/CONFIGURATION.md documenting all src/config.cpp and src/consts.h configuration flags with examples
- [ ] Add cross-references in README.md to these new documentation files
- [ ] Include troubleshooting section for common configuration issues (proxy, SSL, memory limits)
🌿Good first issues
- Add timeout handling to examples/loadspeed.js and examples/post.js to prevent hanging on unresponsive servers: Current examples lack error boundaries for network timeouts; would improve robustness of runnable demos
- Document the phantom.args, phantom.version, and phantom.isHeadless API in examples/printenv.js with explanatory comments: examples/printenv.js is sparse; adding inline documentation and extra API calls would serve as reference for newcomers
- Create a troubleshooting guide in docs/ for common build failures on Windows (MSVC compiler, Qt paths, SSL libraries): .github/workflows/amd64_windows_gcc.yml and amd64_windows_clang.yml show Windows builds work, but no user guide exists for local development
⭐Top contributors
Click to expand
Top contributors
- @ariya — 44 commits
- @vitallium — 23 commits
- @zackw — 8 commits
- @mepard — 6 commits
- @Rawaa-Al-Kabbani — 1 commits
📝Recent commits
Click to expand
Recent commits
0a0b0fa— CI: 32-bit GCC/MSYS2 build for Windows (#15405) (ariya)01d3397— Fix the outdated post url (Rawaa-Al-Kabbani)fad2f73— CI: Building on Windows (with MSYS2) using GCC and Clang (#15405) (ariya)6efc102— Use clang-format 6.0 to check for code style (#15403, #15404) (ariya)9f64f22— GitHub Actions: split the workflows (#15403) (ariya)08d49a7— GitHub Actions: split the workflows (#15403) (ariya)3172296— Switch CI to Github Actions (#15403) (ariya)da0ab54— docs: Fix simple typo, wihout -> without (timgates42)cb1b04b— Replace NULL (or 0) with Q_NULLPTR (vitallium)a283cb4— Remove QSsl deprecation warnings (vitallium)
🔒Security observations
- Critical · Project Development Suspended —
README.md, Project Status. PhantomJS development is officially suspended (issue #15344). No security patches or updates are being provided. Using this project in production exposes the application to unpatched vulnerabilities in WebKit, JavaScript engine, and all dependent libraries. Fix: Migrate to actively maintained alternatives such as Puppeteer, Playwright, or Selenium WebDriver. If continued use is necessary, implement comprehensive security controls and regular security audits. - High · Headless Browser Remote Code Execution Risk —
src/main.cpp, src/callback.cpp, examples/. PhantomJS is a scriptable headless WebKit browser that executes arbitrary JavaScript. If untrusted input is passed to the JavaScript context (via page.evaluate(), page.evaluateAsync(), or similar methods), it can lead to Remote Code Execution. The examples directory shows usage patterns that could be vulnerable if not properly sandboxed. Fix: Implement strict input validation and sanitization before passing any user-controlled data to JavaScript evaluation contexts. Use content security policies and run PhantomJS in isolated environments with minimal privileges. - High · Child Process Execution Without Proper Validation —
src/childprocess.cpp, src/childprocess.h, src/modules/child_process.js, examples/child_process-examples.js. The codebase includes child_process.cpp and examples/child_process-examples.js, indicating the ability to execute child processes. If user input is not properly sanitized before being passed to process execution functions, command injection attacks are possible. Fix: Use parameterized execution (argv array) rather than shell string concatenation. Validate and whitelist allowed commands. Never pass unsanitized user input directly to process execution functions. - High · File System Access Without Proper Controls —
src/filesystem.cpp, src/filesystem.h, examples/echoToFile.js, examples/scandir.js. The filesystem.cpp module provides direct file system access capabilities. Combined with script execution, this could allow unauthorized file read/write operations if JavaScript context is compromised. Examples like echoToFile.js and scandir.js demonstrate file operations. Fix: Implement strict access controls and sandboxing. Restrict file operations to specific directories. Validate all file paths to prevent directory traversal attacks. Run PhantomJS with minimal file system permissions. - High · Network Request Monitoring and Potential SSRF —
examples/netsniff.js, examples/openurlwithproxy.js, examples/post.js, examples/postjson.js. PhantomJS can make arbitrary network requests (examples: netsniff.js, openurlwithproxy.js). If user-controlled URLs are passed without validation, Server-Side Request Forgery (SSRF) attacks are possible, allowing access to internal services, cloud metadata endpoints, or private networks. Fix: Implement URL validation and whitelist allowed domains. Block access to private IP ranges (127.0.0.1, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Use network-level firewalls to restrict egress traffic. - Medium · Cookie Jar Security —
src/cookiejar.cpp, src/cookiejar.h. The cookiejar.cpp module manages HTTP cookies. Improper cookie handling could expose session tokens or authentication credentials, especially if cookies are not properly isolated between page contexts or if the cookie jar is not properly protected. Fix: Ensure cookies are properly scoped and isolated. Implement secure cookie flags (HttpOnly, Secure, SameSite). Validate cookie storage mechanisms. Consider implementing ephemeral cookie handling for security-sensitive operations. - Medium · Outdated WebKit Engine —
Core WebKit dependency. PhantomJS uses WebKit which is no longer actively maintained for this project. Known vulnerabilities in WebKit, JavaScript engine, and rendering engine will not be patched. The browser engine likely contains numerous CVEs. Fix: This is a fundamental issue with the suspended project. Migration to alternatives using updated browser engines (Chromium-based: Puppeteer, Playwright) is strongly recommended. - Medium · Missing Security Headers Configuration —
undefined. No evidence of security header implementation (CSP, X-Frame Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.