a13n
AI 에이전트를 만들고 클라우드에서 실행합니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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) |