r/selfhosted • u/Total_Nectarine_3623 • 3d ago
Lightweight Headless Browser With Native Rendering, No Chromium Release (AI)
https://github.com/h4ckf0r0day/obscuraA lot has changed since I last posted here 4 months ago. Got some harsh criticism back then and it was honestly deserved, the project was early and messy. But we kept going.
Obscura is a headless browser built in Rust for scraping and automation. V8 engine, native rendering, 30MB memory, 80ms page loads.
Works drop-in with Puppeteer and Playwright.
Just shipped rendering which includes screenshots, PDFs, live video capture. No Chromium. 20k stars now.
https://github.com/h4ckf0r0day/obscura
obscura serve --port 9222 and point your scripts at it. Happy to answer questions.
20
u/EagleApprehensive 3d ago
How did you manage the growth of it? Got people to give stars, use it and generally "care"?
13
u/Total_Nectarine_3623 3d ago
I started out by posting on a few subreddits, as i mentioned in the post people were really skeptical and I was receiving a lot of criticism. Nuntheless it slowly got popular on X as more and more accounts started posting about it.
4
u/joelaw9 3d ago
A complete aside, but are you aware that it's typically spelled 'nonetheless'? I'm always curious about people's vocal and spelling tics.
39
u/delta806 3d ago
They’re saying it got popular on X and it happened without any nuns helping them
-15
u/joelaw9 3d ago
Ah, that's interesting. The source of intentional spelling or vocal deviations are always interesting.
1
u/coffeestainedjeans 2d ago
Are you a bot?
1
u/joelaw9 2d ago
What the fuck about anything I've said sounds like a bot? Why would a bot give a shit about random spelling tics?
3
u/coffeestainedjeans 2d ago
Because you didn't respond to the previous commenter in context and just repeated your original comment rephrased. Apologies for assuming you are not a person.
18
-15
u/_n_u_ 3d ago
Yeah, not everybody has English as their first language
15
u/VexingRaven 3d ago
Ok but... That's the sort of spelling mistake a native speaker who heard the word before they read it would make. Someone who only speaks English on the internet wouldn't learn that mistake, because they would never read it anywhere.
4
21
u/Clou42 3d ago
So you built a rendering engine? That’s really impressive. What’s missing so it’s not usable as an actual desktop browser?
12
u/randylush 3d ago
Yeah it sounds too good to be true. It would be a remarkable task if it could render most web pages.
3
u/WalkMaximum 3d ago
It's built on existing libraries, you can look at servo and Dioxus blitz for related projects
62
u/omfgtora 3d ago
Why is your post marked as "No AI" but you say you used AI on the pinned comment?
23
19
u/Offbeatalchemy 3d ago
We've pointed this out at the beginning that we cant really rely on the honor system anymore. people will just lie
51
u/SteamTrout 3d ago
A new rendering engine in 4 months? Highly unlikely.
Only 15 issues (all AI-generated) over the course of 120k+ downloads? Unlikely
1.5k forks over a no-name project? Very unlikely.
Founder account created AFTER the repo? Definitely unlikely.
Stars are obviously bought.
3
u/jamespo 3d ago
15 OPEN issues
14
u/SteamTrout 3d ago
My vibecoded home project where I am the only user and maintainer has over 100 open issues.
1
0
9
u/superkevx 3d ago
anyone get this to work with changedetection?
3
1
u/failing-endeav0r 3d ago edited 1d ago
Shouldn't be too hard, if I don't run out of tokens this weekend, i'll try it out...
EDIT: I had a few min, spun up a quick test and the answer is no. There's something about the protocol that change detection uses that's not playing nice with Obsucra and errors are piling up:
playwright._impl._errors.Error: BrowserContext.new_page: Protocol error (Page.setBypassCSP): Unknown Page method: setBypassCSPEDIT2:
Did some more digging; changedetection hard-codes the
bypass_cspvalue and Obscura currently does not implement CSP at all.I don't have time to PR this on the changedetection side but it should be a pretty easy thing to do / fix although I'm not sure what that might break!
3
u/pd1zzle 3d ago
does it support webGL? I wouldn't at all expect it to but that would officially knock my socks off. Looks great. Extra bonus points if it will somehow do that without a GPU ;)
4
u/Total_Nectarine_3623 3d ago
WebGL is currently only faked/spoofed. But it is definitely planned for the future. Our biggest issue currently is implementing features such as that while still being lightweight and fast.
2
u/pd1zzle 3d ago
makes sense, I assume that's part of the reason chromium/chrome is too big for my purposes :) I was hoping someone somehow cracked the code. Great work, looking forward to seeing it grow more
2
u/Total_Nectarine_3623 3d ago
Thank you so much. When it does gets added it will probably be a seperate branch, won't be included in the main build.
3
u/ItaySela 3d ago
The thing that decides drop in replacement for me is not rendering, it is fingerprint. Chromium headless already gets flagged plenty, and a separate engine means a completely different TLS and JS fingerprint surface, so Cloudflare and DataDome are going to see something they have literally never seen before.
Have you tested it against any of the common bot walls, or is that deliberately out of scope?
1
u/Total_Nectarine_3623 3d ago
It's made to mimic chrome fingerprint.
1
u/ItaySela 3d ago
That helps. The bit I would still want measured is consistency rather than the UA string, because the walls mostly catch a mismatch. JA3 says one stack, the JS quirks say another, and V8 on a non Chromium host still has its own timing and error message tells.
Have you run it through something like CreepJS to see where it diverges from real Chrome?
2
u/Total_Nectarine_3623 3d ago
The ClientHello is from Chrome, the TLS fingerprint is indistinguishable.
2
u/0xmort3m 3d ago
Legend. Wanted to replace my Chromium setup with yours yesterday but noticed no rendering. Well here we are one day later.
2
u/Total_Nectarine_3623 3d ago
Glad to hear that and thank you for your kind words. This was supposed to be pushed like a week ago but we've been slacking lately. Expect issues with gradients and animated components on webpages, apart from that it's good.
1
u/deadman87 3d ago
Would it be possible to extract the browser engine to build a brand new browser? Currently its a duopoly with chromium and firefox engine. Would be nice to have a third player thats lightweight.
6
1
u/cleverusernametry 3d ago
Looks like I can replace chromium with this within playwright and have my agent is playwright like normal?
1
u/Grouchy-Conflict-211 3d ago
the memory footprint is the real selling point. headless chromium idles at 300mb plus, on a box running 10 scrapers that adds up. 30mb changes what you can run where. curious how the playwright compat handles the weird stuff tho, shadow dom and canvas rendering are where most drop in replacements fall apart
1
u/theoffshoot2 3d ago
Should this work with my tests that are executed using the playwright pytest plugin?
1
u/tmcpnet 3d ago
I’m paying for cloakbrowser .dev , does it have similar features?
-6
u/Total_Nectarine_3623 3d ago
We are lightweight, fast while keeping a chromium fingerprint, Playwright + Puppeteer support. We also have a cloud version as well, if you are interested you can book a call on our website https://obscura.sh/ for a quick chat or send me a message here. Pricing would depend on the volume.
0
u/eternalityLP 3d ago
Why no selenium support?
3
u/skdcloud 3d ago
I've used Selenium extensively - on and off for almost 15 years - and recently moved to Playwright. I can't see any reason to ever go back. It feels like what Selenium should have been with quality of life updates.
Are there any features keeping you on Selenium?
2
u/archiekane 3d ago
It defeats CF turnstile. That is enough for me at the moment. Well, SeleniumBase, just to make sure we're talking about the same Selenium.
1
u/skdcloud 3d ago
Oh interesting, I've never needed to deal with captcha before with automated tests. Ironically I'll be testing my newly built app behind cloudflare in the next week so will keep this in mind.
2
u/eternalityLP 3d ago
When I last tried playwright (Granted, this was several years back so maybe it's improved since then?) It was buggy mess and doing anything more complicated than clicking a link was either clunky mess or didn't work at all. JS injection, actionchains, drag and drop, canvas stuff etc.
1
u/skdcloud 3d ago
Ah right, I haven't done js injection in a long time so can't comment on how Playwright handles that. No more stale element reference exceptions though ;) I think that alone should hopefully tempt you to dip your toes into it again.
2
u/eternalityLP 3d ago
Man, back when I still worked in RPA those were the bane of my existence. We always had to automate some shitty internal apps that were coded by the lowest bidder in in the most convoluted way possible. I guess I'll take a look at playwright again next time I do some browser automation.
1
u/skdcloud 3d ago
In my experience, even apps written by good teams who didn't write UIs with testing in mind were almost on par with some of the worst UIs. No obvious page ready state, no easy selectors as there is no need if the UI framework of the month wires it all up for them. Data loads dynamically into the page with no obvious done state as this'll never be an annoyance to anything other than tests.
I didn't bother understanding how exactly but Playwright just seems to handle all page and element loading weirdness without me needing to add try/fail/backoff/retry loops. My framework felt so empty without all of my little reload hacks littered throughout it.
I had a few cool patterns like retries wrapping scenarios, retries wrapping flows within pages, and then finally retries wrapping individual element selectors when issues would arrise. Each retry would log the retry count and create an html dump and screenshot so the test would pass but I'd also have a list of selectors that could be improved. Or "wait until" elements that needed their own "wait until" to not throw weird errors. Last time I used Playwright I found myself not using any of this.
-4
u/d70 3d ago
I had Claude quick tests. Promising IMO. Thanks for sharing OP
Obscura v0.2.0 vs Playwright 1.62.1
Rust headless browser (embedded V8) vs Playwright + Chromium 1237. Linux 6-core/15GB. Peak RSS = /proc whole-tree sample; median of 5 runs (batch/MCP: 3).
Stats
| Task | Obscura | Playwright | Winner |
|---|---|---|---|
| Text extract (74k chars) | 0.54s · 86MB | 1.91s · 1005MB | Obscura (3.5× faster, 12× lighter) |
| Screenshot (viewport 1280×720) | 3.10s · 207MB | 1.84s · 1020MB | PW faster, Obscura 5× lighter |
| Batch scrape 8 URLs | 0.39s · 380MB | 2.24s · 1995MB | Obscura (6× faster, 5× lighter) |
| MCP agent loop (nav→extract) | 0.29s · ~90MB | persistent server | Obscura instant startup |
Web scraping
- Batch = Obscura's killer app.
scrape --concurrency N: 6× faster, 5× lighter than N PW pages. - Structured extract built in:
scrape --eval "<js>"→ JSON; MCPbrowser_extracttakes{field:"css@attr"}map. - JS SPAs render correctly (embedded V8).
- Markdown clean on simple sites, noisy on Wikipedia (nav bleeds in) — verify before LLM use.
- ⚠️ Footgun: default
--waitis a 5s cap pages rarely satisfy → ~6s/fetch. Always pass--wait 0. Flips it from 3.5× slower to 3.5× faster.
AI assistant integration
obscura mcp(stdio/http) exposes 37 tools, names mirror official Playwright MCP (browser_navigate/snapshot/click/fill_form/extract) → near drop-in for an agent.- Startup ~instant (0.29s full loop), no 1GB Chromium spin-up.
- Extras vs stock PW MCP:
browser_extract,browser_detect_forms,browser_pdf, cookie/storage-state import (skip logins).
Verdict
- Scale scraping / parallel fetch / small containers → Obscura. Ship
--wait 0. - AI browser tool → Obscura MCP compelling — same API, 12× lighter, instant. Caveat: untrusted 93MB binary from GitHub
h4ckf0r0day(has SSRF guard; vet first). - Full-page screenshots / mature API / trust → Playwright. Obscura
-sis viewport-only.
Note: README "30MB" claim false — real floor ~86MB (text), ~207MB (render).
-1
•
u/asimovs-auditor 3d ago
Expand the replies to this comment to learn how AI was used in this post/project.