A local-first browser profile manager for Playwright web automation. It creates isolated, persistent Chromium sessions for authorized QA, repeatable browser testing, localization checks, and development workflows.
Each profile owns a separate user-data directory. Cookies, local storage, cache, service workers, and authenticated test state stay with that profile instead of leaking into another environment. The project uses Playwright's supported persistent-context API. It does not spoof browser fingerprints or bypass site security controls.
- The problem
- What the project does
- Quick start
- CLI reference
- Architecture
- Browser profile lifecycle
- Profile data model
- Common testing workflows
- Design decisions
- Project structure
- Documentation
- Roadmap
- Responsible use
Short Playwright tests often create a clean browser context, perform assertions, and discard all state. That model is ideal for isolated test cases, but it is inconvenient for workflows that need a stable development identity:
- a QA login that must survive process restarts;
- separate staging and production sessions;
- localization checks with a fixed locale, timezone, and viewport;
- bug reproduction that depends on cookies or local storage;
- parallel projects that must never share browser data;
- a manual browser handoff before automation continues.
Using one normal browser profile for all of these jobs makes state difficult to reason about. Copying profile directories manually is also error-prone. This project treats the browser profile as an explicit local resource with metadata, a lifecycle, and a predictable storage boundary.
- Creates named browser profiles with isolated user-data directories.
- Launches persistent Playwright Chromium contexts.
- Stores locale, timezone, viewport, creation time, and last launch time.
- Lists profiles as a terminal table or machine-readable JSON.
- Validates HTTP and HTTPS navigation targets.
- Refuses unsafe profile names and paths outside the configured root.
- Requires an explicit
--yesflag before deleting browser data. - Diagnoses Node.js, storage, Playwright, and Chromium installation problems.
- Keeps profile data local and sends no telemetry.
This is a small reference CLI, not a hosted browser farm. It does not provide proxy rotation, fingerprint modification, credential collection, CAPTCHA handling, stealth plugins, ad interaction, or engagement manipulation. Teams can build authorized test adapters around the profile boundary without changing the storage model.
Requirements: Node.js 20 or newer.
npm install
npx playwright install chromium
node src/cli.js doctor
node src/cli.js create checkout-qa \
--locale en-US \
--timezone America/New_York \
--viewport 1440x900
node src/cli.js launch checkout-qa --url https://example.comClose the browser window to end an interactive launch. For a time-limited headless run:
node src/cli.js launch checkout-qa \
--url https://example.com \
--headless \
--duration 5000Run npm link once if you prefer the shorter global browser-profile command.
| Command | Purpose |
|---|---|
create <name> |
Create a new isolated browser profile. |
list |
List profiles and their last launch time. |
list --json |
Return complete profile metadata as JSON. |
info <name> |
Inspect one profile. |
launch <name> |
Open a persistent Playwright browser context. |
doctor |
Check Node.js, storage, Playwright, and Chromium. |
doctor --json |
Return environment diagnostics as JSON. |
remove <name> --yes |
Delete one profile and its local browser data. |
| Option | Default | Meaning |
|---|---|---|
--locale |
en-US |
Browser locale passed to Playwright. |
--timezone |
UTC |
IANA timezone ID used by the context. |
--viewport |
1280x720 |
Viewport from 320x320 through 3840x2160. |
| Option | Default | Meaning |
|---|---|---|
--url |
Browser start page | Initial HTTP or HTTPS page. |
--headless |
Off | Launch without a visible browser window. |
--duration |
Until browser closes | Close automatically after N milliseconds. |
Set BROWSER_PROFILE_HOME to move storage outside the default ~/.browser-profile-manager directory.
The command line owns intent, ProfileStore owns durable metadata and paths, and Playwright owns the browser process. Keeping those responsibilities separate makes the storage code testable without launching Chromium.
flowchart LR
CLI[CLI command] --> Validation[Input validation]
Validation --> Store[ProfileStore]
Store --> Metadata[profile.json]
Store --> Data[isolated user-data directory]
CLI --> Playwright[Playwright persistent context]
Playwright --> Data
Playwright --> Page[Authorized test target]
The project deliberately has no background daemon. Every command reads the current filesystem state and performs one bounded operation. See docs/architecture.md for component boundaries and failure handling.
stateDiagram-v2
[*] --> Created: create
Created --> Available: metadata written
Available --> Running: launch
Running --> Available: browser closes
Available --> Removed: remove --yes
Removed --> [*]
Profile creation is explicit and duplicate names are rejected. A launch updates lastLaunchedAt only after Playwright opens the persistent context. Removal first verifies that the named profile exists, then deletes only its validated directory.
For operational guidance, see docs/browser-profile-lifecycle.md.
Each profile stores non-secret metadata beside its browser data:
{
"id": "c615a42b-1921-4ac7-9018-71ec6cb03d0e",
"name": "checkout-qa",
"createdAt": "2026-08-31T08:00:00.000Z",
"lastLaunchedAt": null,
"locale": "en-US",
"timezoneId": "America/New_York",
"viewport": { "width": 1440, "height": 900 },
"userDataDir": "/home/user/.browser-profile-manager/profiles/checkout-qa/user-data"
}The user-data directory can contain sensitive authenticated session state. It is excluded from Git and should not be synced, attached to issues, or treated as a portable credential archive. Read docs/profile-storage-security.md before using persistent sessions in a team.
Create one profile per application environment:
node src/cli.js create storefront-local
node src/cli.js create storefront-staging
node src/cli.js create storefront-productionThis prevents a staging cookie or feature flag from silently affecting production verification.
node src/cli.js create checkout-en-us --locale en-US --timezone America/New_York
node src/cli.js create checkout-en-gb --locale en-GB --timezone Europe/London
node src/cli.js create checkout-ja-jp --locale ja-JP --timezone Asia/TokyoThe example at examples/profile-matrix.mjs builds a small authorized QA matrix and prints the generated profile metadata.
node src/cli.js list --json
node src/cli.js doctor --jsonJSON output can feed local scripts and CI diagnostics without parsing terminal tables.
More patterns are documented in docs/testing-workflows.md.
| Decision | Reason |
|---|---|
| Persistent context instead of manual cookie injection | Browser-managed storage remains internally consistent. |
| One user-data directory per profile | The filesystem boundary is easy to inspect and protect. |
| Metadata outside Chromium internals | The CLI never needs to parse undocumented browser databases. |
| Strict profile names | A short allowlist prevents ambiguous paths and traversal. |
| Local-first storage | Authenticated browser state does not need a cloud service. |
| No automatic profile copying | Copying live browser state can corrupt data or duplicate credentials. |
| Explicit deletion flag | Removing a profile destroys cookies and local session state. |
| Dependency injection in diagnostics | Environment checks remain testable without downloading a browser. |
.
|-- .github/ Issue and pull request templates
|-- docs/ Architecture, lifecycle, security, and guides
|-- examples/ Small authorized automation examples
|-- src/
| |-- cli.js Command parsing and Playwright launch flow
| |-- doctor.js Environment diagnostics
| |-- profile-store.js Profile metadata and filesystem boundaries
| `-- validation.js Name, URL, and viewport validation
|-- test/ Node.js unit tests
|-- CHANGELOG.md
|-- CONTRIBUTING.md
|-- SECURITY.md
`-- package.json
- Architecture: component boundaries and data flow.
- Browser profile lifecycle: creation, launch, recovery, and removal.
- Playwright persistent contexts: when persistent state is appropriate.
- Profile storage and security: cookies, secrets, backups, and team use.
- Testing workflows: environment isolation and localization matrices.
- Troubleshooting: installation, locked profiles, URLs, and storage errors.
The roadmap is intentionally limited to features that preserve the local isolation model:
- profile labels and notes;
- optional metadata-only export and import;
- launch event history without browsing data;
- configurable browser channels;
- stronger checks for profiles already in use;
- a documented adapter interface for authorized test harnesses.
Items are proposals, not current functionality. Open an issue before starting a large implementation.
npm test
npm run checkThe unit tests use temporary directories and do not launch Chromium. See CONTRIBUTING.md for the contribution workflow and CHANGELOG.md for released changes.
Use this project only for websites, applications, and accounts you own or are authorized to test. It is not designed for ad clicking, engagement manipulation, account farming, security-control bypass, or evasion of platform enforcement. Respect site terms, rate limits, privacy requirements, and applicable law.
Released under the MIT License. This independent, local-first utility is maintained with support from TrafficBotPro, a desktop web automation platform.