尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Rust Chromium fleet engine: pooling, admission, recycle, crash recovery
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Run hundreds of headless Chrome jobs on one machine. Fluxwright pools browsers, queues jobs when every slot is busy, restarts browsers before they bloat, and retries jobs when a browser crashes, behind a Playwright-style API for Node, Python and Rust.
It is not a Playwright rewrite. Playwright drives a browser; Fluxwright runs a fleet of them.
Docs: https://fluxwright.vercel.app · Roadmap: ROADMAP.md
npm install fluxwright
import { chromium } from "fluxwright";
const browser = await chromium.launch({ maxBrowsers: 4 });
const page = await browser.newPage(); // a fresh context on a pooled Chrome
await page.goto("https://example.com");
console.log(await page.getByRole("heading").textContent()); // "Example Domain"
console.log(await page.evaluate(() => location.hostname));
await page.close(); // the context is destroyed and the slot is free again
await browser.close();
Fluxwright uses the Chrome on your machine. For headless jobs, install chrome-headless-shell: pages open 5-10x faster than on Chrome's new headless mode in our runs.
npx @puppeteer/browsers install chrome-headless-shell@stable
pip install fluxwright
import asyncio
from fluxwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(max_browsers=4)
page = await browser.new_page()
await page.goto("https://example.com")
print(await page.get_by_role("heading").text_content()) # "Example Domain"
await browser.close()
asyncio.run(main())
Blocking code uses fluxwright.sync_api and sync_playwright() the same way. The names are Playwright's, so a Playwright script for these features runs after changing its import.
| Area | API |
|---|---|
| Navigate | goto(url, { waitUntil }) with load (default), domcontentloaded, networkidle or commit, event-driven like Playwright |
| Find | getByRole(role, { name }), getByText, getByLabel, getByPlaceholder, getByTestId, locator(css | "text=…" | "role=…"), frameLocator(iframe) for same- and cross-origin iframes. Narrow with nth(i), first(), last(), filter({ hasText }) and chained getBy… calls |
| Act | click() and fill() wait until the element is visible, enabled, stable and not covered; waitFor(), waitForSelector() |
| Read | title(), content(), textContent(), evaluate(fn, arg) or evaluate("expression"), locator.evaluate((el, arg) => …), locator.boundingBox() |
| Capture | screenshot({ fullPage, path }), locator.screenshot({ path }) (also inside scrolling containers and iframes), setViewportSize({ width, height }) |
| Errors | consoleMessages() and pageErrors() from the page, its popups and iframes, so a job can fail on JavaScript errors; page.on('console' | 'pageerror', handler) as they happen |
| Requests | page.route(url, handler) to fulfill, change or abort requests (route.fulfill({ json }), route.continue({ headers }), route.abort(), route.fallback()), with globs, RegExps or functions |
| Downloads | page.waitForDownload() then download.saveAs(path); each job's files stay in its own folder until the page closes |
| Emulate | newPage({ userAgent, locale, timezoneId, geolocation, permissions, viewport, deviceScaleFactor, colorScheme }), Playwright's option names |
| Sessions | page.storageState({ path }) saves cookies and localStorage; starts from them, so you log in once. Playwright's file format |
The full Node API is in bindings/node/README.md and the Python API, with the same features under Playwright's Python names (get_by_role, wait_until, storage_state, ...), in bindings/python/README.md.
expect, fixtures, a trace viewer and a recorder. Fluxwright is an engine, not a test framework.Use Fluxwright when you run many browser jobs, such as scraping, crawling, PDF and screenshot rendering, or automation at volume, and want the fleet handled for you.
Measured on GitHub's ubuntu-latest runner (three runs, 2026-10-27): every tool on the same chrome-headless-shell 156 binary, loading a small local page with the same number of jobs in flight. With 1 browser and 10 pages, Fluxwright ran 34–40 jobs/s, Playwright 27–34 and Puppeteer 27–36; with 1,000 jobs on 4 browsers, 36–44, 30–38 and 34–46. No job failed. A shared cloud machine varies by up to a third from run to run, so rerun it (Actions → benchmarks) and measure your own workload with cargo run --release -p fluxwright-benchmarks (results go to benchmarks/results/).
[dependencies]
fluxwright = { git = "https://github.com/harshit-d3v/fluxwright" }
use fluxwright::{BrowserEngine, JobOptions, Priority};
#[tokio::main]
async fn main() -> fluxwright::Result<()> {
let engine = BrowserEngine::builder()
.max_browsers(50)
.max_contexts_per_browser(10)
.memory_ceiling_mb(8192)
.build()
.await?;
let page = engine.acquire().await?;
page.goto("https://example.com").await?;
println!("{}", page.title().await?);
drop(page); // context destroyed, slot returned
// run() queues, leases, retries after a crash, and always releases the page.
let title = engine
.run(JobOptions::default().priority(Priority::High).retries(2), |page| async move {
page.goto("https://example.com").await?;
page.title().await
})
.await?;
println!("{title}");
Ok(())
}
Requires Rust 1.95+ and Chrome or Chromium (found on the standard install paths, or set FLUXWRIGHT_CHROMIUM, CHROME or CHROMIUM). --no-sandbox is off unless you set FLUXWRIGHT_NO_SANDBOX=1 (logs a warning).
| Crate | Role |
|---|---|
fluxwright-cdp | One connection per browser (DevTools pipe on Linux/macOS, WebSocket on Windows), flat sessions |
fluxwright-core | Pool, scheduler, memory ceiling, recycling, metrics |
fluxwright | Public API |
fluxwright-cli | fluxwright start / stats / browsers / doctor / benchmark |
fluxwright-mcp | MCP server: open, goto, click, fill, evaluate, screenshot, close |
cargo install --git https://github.com/harshit-d3v/fluxwright fluxwright-mcp
Then add { "mcpServers": { "fluxwright": { "command": "fluxwright-mcp" } } } to your client's configuration (Windows: install-mcp.bat).
cargo run -p fluxwright-cli -- start
cargo run -p fluxwright-cli -- stats
cargo run -p fluxwright-cli -- browsers
cargo run -p fluxwright-cli -- doctor
The control channel is a Unix socket, or \\.\pipe\fluxwright on Windows. Nothing listens on TCP.
cargo run --release -p fluxwright-benchmarks
# two-hour soak (memory over time): cargo run --release -p fluxwright-benchmarks -- --soak
The harness talks to benchmark-server (localhost only). Playwright and Puppeteer adapters run if their Node packages are installed.
cd www && npm install && npm run dev (http://localhost:3456). Vercel deploys www/ from main.cd bindings/node && npm install && npm run build && npm test.cd bindings/python && pip install maturin pytest && maturin develop && pytest (in a virtualenv).cargo test --workspace -- --test-threads=1.docs/COMPETITIVE_ANALYSIS.md, docs/CDP_DECISION.md, docs/DECISIONS.md.Licensed under the Apache License, Version 2.0. Versions up to 0.2.0 were released under the MIT license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project shall be licensed under the Apache License, Version 2.0, without any additional terms or conditions.
newPage({ storageState })| Network | a proxy per page, with a username and password; blocking by resource type or URL (Rust JobOptions) |