Charlotte has 111 stars. That's not a lot. But it's enough that a breaking change will annoy real people.
I shipped one anyway.
The naming problem
When I started building at the time.
I fixed it in evaluate.ts. Then found the same pattern in wait-for.ts and fixed it in 0.5.0.
0.6.0 found it a third time in pollUntilCondition, a utility function used by the wait system. Same bug. Same new Function('return ' + expr). Same migration to CDP Runtime.evaluate.
That's three separate files with the same broken pattern, discovered across three releases. Copy-paste bugs are persistent. If you find a pattern-level bug in your codebase, grep for every instance before you close the issue. I should have done that the first time.
7 strangers improved my code
When I started Charlotte in February, it was a solo project. 100% of commits from one person. An external evaluation in early March rated sustainability 2 out of 5 and flagged "97% single-developer commits" as the primary risk.
Six weeks later, seven people I've never met have merged code into Charlotte:
Teoman Yavuzkurt contributed three PRs: fixing the default viewport (800x600 was unrealistically small), solving a stale compositor frame bug in screenshots on SPA transitions, and fixing macOS symlink resolution in tests. Three different areas of the codebase. That's someone who read the code deeply enough to find problems across modules.
clawtom submitted two PRs: an O(1) lookup optimization for the snapshot store (replacing a linear scan with a Map index) and proper error logging for CDP failures in layout extraction. Both unsolicited. Both performance or reliability improvements that I hadn't prioritized.
Sandy McArthur, Jr. joined as a new contributor this cycle. Nuno Curado did the original security hardening back in February. kai-agent-free picked up the "read version from package.json" issue I had tagged as "good first issue." Nestor Fernando De Leon Llanos added the issue templates and community links.
I didn't recruit any of them. They found the project, read the code, and decided it was worth contributing to. The issue templates, the "good first issue" labels, the CONTRIBUTING guide, the test suite that gives contributors confidence their changes don't break things. All of that infrastructure exists to make contributing feel safe and worthwhile. It seems to be working.
The sustainability rating would look different today.
What's next
Charlotte is at 43 tools, 519 tests, and a 1.07:1 test-to-source line ratio. The structural tree view from 0.5.0 gives agents a full page map in under 2,000 characters. Iframe extraction handles embedded content. File output keeps large responses out of the context window. And now batch form fills collapse multi-step interactions into single calls.
The focus for the next cycle is the connect-to-browser feature: attaching Charlotte to an already-running Chrome instance instead of launching its own. This unlocks screen recording of agent sessions, live debugging, and the kind of demo videos that are worth more than any blog post.
Try it
npx @ticktockbent/charlotte@latest
Works with any MCP client: Claude Desktop, Claude Code, Cursor, Windsurf, Cline, VS Code, Amp.
Open source, MIT licensed. If you're running browser-heavy agent workflows, I'd like to hear how it holds up.
SOCIAL SHARE CARD GENERATOR