Migrating to Lightcone
Move from local browser automation (Selenium, Puppeteer, Playwright) to Lightcone cloud browsers.
If you’re already using Selenium, Puppeteer, or Playwright for browser automation, Lightcone replaces the browser infrastructure with managed cloud sessions. This guide maps the concepts and APIs you already know to their Lightcone equivalents.
Why migrate
Section titled “Why migrate”| Local automation | Lightcone | |
|---|---|---|
| Infrastructure | You manage browser binaries, drivers, containers | Managed cloud browsers — nothing to install or maintain |
| Scaling | Limited by your machine’s resources | Spin up hundreds of sessions on demand |
| Bot detection | You configure fingerprinting, proxies, user agents | Built-in stealth with optional advanced proxy |
| AI agents | You build the agent loop yourself | Agent Tasks run autonomously from a single instruction |
| Persistent state | You manage cookie files or browser profiles | persistent: true saves and restores automatically |
| Cost | Free (but you pay for infrastructure) | Pay-per-session, no infrastructure to manage |
Concept mapping
Section titled “Concept mapping”| Local concept | Lightcone equivalent |
|---|---|
| Browser instance / page | Computer session (kind: "browser") |
page.goto(url) | computer.navigate(url) |
page.click(selector) | computer.click(x, y) (screenshot-based coordinates) |
page.type(selector, text) | computer.type(text) (types into focused element) |
page.keyboard.press('Enter') | computer.hotkey("Enter") |
page.screenshot() | computer.screenshot() → URL of the captured image |
page.content() | computer.html() → page HTML content |
page.evaluate(js) | computer.debug(command) for shell, or use Playwright CDP for JS eval |
page.waitForSelector() | computer.wait(seconds) + screenshot to verify |
browser.close() | computer.terminate() or context manager exit |
| Cookie files / profiles | Persistent sessions (persistent: true) |
| Proxy config | use_advanced_proxy: true or change_proxy() |
From Selenium
Section titled “From Selenium”Before (Selenium):
from selenium import webdriverfrom selenium.webdriver.common.by import By
driver = webdriver.Chrome()driver.get("https://example.com")driver.find_element(By.CSS_SELECTOR, "#search").send_keys("hello")driver.find_element(By.CSS_SELECTOR, "#submit").click()screenshot = driver.get_screenshot_as_png()driver.quit()After (Lightcone):
from tzafon import Lightcone
client = Lightcone()
with client.computer.create(kind="browser") as computer: computer.navigate("https://example.com") computer.wait(2)
# Instead of CSS selectors, use screenshot-based coordinates # Take a screenshot to find field positions result = computer.screenshot() print(computer.get_screenshot_url(result))
# Click the search field and type computer.click(400, 300) # Coordinates from screenshot computer.type("hello")
# Click submit computer.click(500, 400) computer.wait(2)
result = computer.screenshot() print(computer.get_screenshot_url(result))Key differences:
- No driver setup — no ChromeDriver, no version matching, no Docker
- Coordinate-based interaction — take a screenshot, find the element position, click at those coordinates
- Automatic cleanup — context manager handles session termination
- Cloud execution — the browser runs in Lightcone’s cloud, not on your machine
From Puppeteer
Section titled “From Puppeteer”Before (Puppeteer):
import puppeteer from "puppeteer";
const browser = await puppeteer.launch();const page = await browser.newPage();await page.goto("https://example.com");await page.type("#search", "hello");await page.click("#submit");await page.screenshot({ path: "result.png" });await browser.close();After (Lightcone):
import Lightcone from "@tzafon/lightcone";
const client = new Lightcone();const computer = await client.computers.create({ kind: "browser" });const id = computer.id!;
try { await client.computers.navigate(id, { url: "https://example.com" }); await new Promise((r) => setTimeout(r, 2000));
// Screenshot to find coordinates const screenshot = await client.computers.screenshot(id); console.log("Layout:", screenshot.result?.screenshot_url);
// Click and type using coordinates await client.computers.click(id, { x: 400, y: 300 }); await client.computers.type(id, { text: "hello" }); await client.computers.click(id, { x: 500, y: 400 });
const result = await client.computers.screenshot(id); console.log("Result:", result.result?.screenshot_url);} finally { await client.computers.delete(id);}From Playwright
Section titled “From Playwright”Lightcone has a Playwright integration that lets you keep using Playwright’s selector-based API while running on Lightcone cloud browsers. This is the easiest migration path:
Before (Playwright local):
from playwright.sync_api import sync_playwright
with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto("https://example.com") page.fill("#search", "hello") page.click("#submit") page.screenshot(path="result.png") browser.close()After (Playwright + Lightcone):
from playwright.sync_api import sync_playwrightfrom tzafon import Lightcone
client = Lightcone()session = client.computers.create(kind="browser")
with sync_playwright() as p: # Connect to the Lightcone session via CDP browser = p.chromium.connect_over_cdp(f"wss://api.tzafon.ai/v1/cdp/{session.id}") page = browser.contexts[0].pages[0]
page.goto("https://example.com") page.fill("#search", "hello") page.click("#submit") page.screenshot(path="result.png")
browser.close()
client.computers.delete(session.id)This approach lets you keep your CSS selectors and Playwright test patterns while gaining cloud infrastructure, stealth, and scaling.
Use AI instead of selectors
Section titled “Use AI instead of selectors”Lightcone’s biggest advantage over local automation is AI-powered interaction. Instead of maintaining brittle selectors, let a vision model find elements:
The old way (selector-based):
# Breaks when the site changes its HTMLpage.click("#submit-btn")page.fill("input[name='email']", "user@example.com")The Lightcone way (AI agent):
# Works regardless of HTML structurefor event in client.agent.tasks.start_stream( instruction=( "Go to example.com, " "enter user@example.com in the email field, " "and click the submit button." ), kind="browser", max_steps=10,): print(event)The Lightcone way (CUA loop for custom logic):
# You control each step, but AI finds the elementsresponse = client.responses.create( model="tzafon.northstar-cua-fast", input=[{ "role": "user", "content": [ {"type": "input_text", "text": "Click the email field and type user@example.com"}, {"type": "input_image", "image_url": screenshot_url}, ], }], tools=[{"type": "computer_use", "display_width": 1280, "display_height": 720, "environment": "browser"}],)# The model returns coordinates to click — execute them on the sessionMigration checklist
Section titled “Migration checklist”- Install the SDK:
pip install tzafonornpm install @tzafon/lightcone - Get an API key from the dashboard
- Replace browser launch with
client.computer.create(kind="browser") - Replace selector-based clicks with coordinate-based clicks (or use the Playwright integration)
- Replace
waitForSelectorwithcomputer.wait()+ screenshot verification - Replace local cookie/profile management with
persistent: true - Replace proxy configuration with
use_advanced_proxy: true - Consider replacing coordinate-based scripts with Agent Tasks for resilience
See also
Section titled “See also”- Quickstart — get started in under 5 minutes
- Computers — full session API reference
- Playwright integration — use Playwright selectors on Lightcone browsers
- Agent Tasks — AI-powered automation without coordinates
- Best practices — patterns for reliable automation