Everything a WebView gives you, none of the baggage
Headless & off-tree
No React component, no screen, no UI tree. Parse, mutate, and evaluate HTML entirely off-screen.
Truly isolated runtime
Every JSDOM.create() spins up its own QuickJS runtime, not a shared Hermes instance. No leaking globals between sandboxes.
Native HTML parsing
Backed by Lexbor, the fastest WHATWG-compliant HTML parser in C99, with zero dependencies.
jsdom-shaped DOM API
querySelector, textContent, dataset, and more mirror jsdom's DOM shape, though usage differs: everything runs through the async evaluate(), not jsdom's synchronous object access.
Synchronous JSI bridge
Powered by Nitro Modules, with direct JSI calls, no bridge, no JSON serialization overhead.
Full memory control
Call dispose() to deterministically free the Lexbor document and QuickJS runtime, no waiting on GC.
One synchronous call, two native engines
evaluate() is the only door into the sandbox: everything else happens natively, off the JS bridge.
- WHATWG-compliant HTML parsing
- In-memory DOM tree
- querySelector / querySelectorAll
- serialize() → HTML string
- Isolated JS runtime per instance
- DOM bindings → delegates to Lexbor
- setTimeout / setInterval, own event loop
- Executes arbitrary user scripts
Why not just use a hidden WebView?
| Feature | WebView (hidden) | react-native-nitro-jsdom |
|---|---|---|
| Requires a React component | ✓ | ✕ |
| Runs headless / off-tree | ✕ | ✓ |
| Isolated instances | Complex | Native |
| Arbitrary JS execution | ✓ | ✓ |
| Full DOM API | ✓ | Progressive |
| Memory control | Limited | Full (dispose()) |
| Performance overhead | High | Low |
Ready to sandbox your first DOM?
Install the library and run your first evaluate() in minutes.