flarer 0.1.0

Rust client and CLI for Cloudflare's Browser Rendering REST API (content, screenshot, PDF, snapshot, markdown, scrape, JSON extraction, links, crawl).
Documentation

flarer

Crates.io Docs.rs CI License

Rust library + CLI for Cloudflare's Browser Rendering REST API.

flarer exposes every Browser Rendering tool — content, screenshot, pdf, snapshot, markdown, scrape, json (LLM extraction), links, crawl — through a small, typed client and an interactive command-line front-end.


Install

As a CLI

cargo install flarer

As a library

[dependencies]
flarer = "0.1"

For library-only use (no clap / inquire / dotenv / tracing-subscriber):

flarer = { version = "0.1", default-features = false }

Configuration

flarer needs a Cloudflare account ID and an API token with the Browser Rendering permission.

export CF_ACCOUNT_ID=...
export CF_API_TOKEN=...
# Optional: where binary artifacts (PNG, PDF) are written.
export FLARER_OUTPUT_DIR=./outputs

The CLI also reads .env automatically.


CLI usage

# Interactive (prompts for URL, tool, options)
flarer
flarer -i

# One-shot
flarer --url https://example.com --tool markdown
flarer --url https://example.com --tool screenshot --output-dir ./shots
flarer --url https://example.com --tool json \
       --prompt "Extract title and links" \
       --schema ./schema.json

Increase log verbosity:

FLARER_LOG=flarer=debug flarer --url https://example.com --tool content

Library usage

use flarer::{Account, Flarer, Tool};

#[tokio::main]
async fn main() -> flarer::Result<()> {
    let account = Account::from_env()?;
    let flarer  = Flarer::builder().account(account).build()?;
    flarer.verify().await?;

    let out = flarer.run(Tool::Markdown, "https://example.com").await?;
    println!("{}", out.display_string());
    Ok(())
}

LLM JSON extraction

use flarer::{Account, Flarer, JsonOptions, ResponseFormat};
use serde_json::json;

#[tokio::main]
async fn main() -> flarer::Result<()> {
    let flarer = Flarer::builder().account(Account::from_env()?).build()?;

    let schema = json!({
        "type": "object",
        "properties": {
            "title": { "type": "string" },
            "links": { "type": "array", "items": { "type": "string" } }
        },
        "required": ["title"]
    });

    let opts = JsonOptions::new()
        .with_prompt("Extract the page title and all hyperlinks.")
        .with_response_format(ResponseFormat::json_schema(schema));

    let value = flarer.json("https://example.com", opts).await?;
    println!("{}", serde_json::to_string_pretty(&value)?);
    Ok(())
}

Custom HTTP client / mock server

use std::time::Duration;
use flarer::{Account, Flarer};
use reqwest::Url;

# fn build() -> flarer::Result<()> {
let flarer = Flarer::builder()
    .account(Account::new("acct", "token"))
    .base_url(Url::parse("https://my-mock.local/v4/").unwrap())
    .timeout(Duration::from_secs(60))
    .user_agent("my-app/0.1")
    .output_dir("/tmp/flarer")
    .build()?;
# Ok(()) }

Examples

cargo run --example markdown -- https://example.com
cargo run --example screenshot -- https://example.com ./outputs
cargo run --example extract_json -- https://example.com

Features

Feature Default Pulls in
cli yes clap, inquire, dotenv, tracing-subscriber

Minimum Supported Rust Version

1.85 (edition 2024).


License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.