Minimal reproduction demonstrating the wasm-unsafe-eval Content Security Policy requirement for PowerSync Web SDK using the actual @journeyapps/wa-sqlite package.
PowerSync Web SDK depends on @journeyapps/wa-sqlite, which requires WebAssembly compilation at runtime. This test uses the exact same wa-sqlite package that PowerSync uses to demonstrate that CSP blocks WASM loading without the wasm-unsafe-eval directive.
Install dependencies:
npm installThis installs @journeyapps/wa-sqlite - the same package PowerSync uses.
node server.js block-wasmOpen http://localhost:3005/ in Safari
Expected Result: ❌ Red error - WASM module initialization fails with CSP-related error
CSP Header:
script-src 'self' 'unsafe-inline'
This reproduces the production issue where Safari blocks WASM compilation, breaking PowerSync.
node server.js allow-wasmOpen http://localhost:3005/ in Safari
Expected Result: ✅ Green success - "wa-sqlite WASM module loaded and initialized successfully!"
CSP Header:
script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'
This is the correct production configuration for PowerSync.
node server.js no-cspExpected Result: ✅ Green success (no CSP enforcement)
Note: Works but provides no CSP protection.
The test page:
- Imports
@journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs - Calls the module factory to initialize the WASM - this is where CSP enforcement happens
- Verifies the WASM module loaded successfully
- Reports success or failure
Step 2 is critical - calling moduleFactory.default() loads and compiles the WebAssembly module, which requires wasm-unsafe-eval. Without it in CSP, this call fails with a CSP violation and the test shows an error.
The test intentionally keeps things minimal - it only tests WASM initialization (the CSP-enforced operation) rather than performing full SQLite operations.
This is the EXACT dependency PowerSync uses:
- Uses
@journeyapps/wa-sqlite(PowerSync's peer dependency) - Tests the real WASM module PowerSync loads
- Demonstrates the same CSP behavior customers encounter
- Safari strictly enforces CSP
- Without
wasm-unsafe-eval, PowerSync breaks in production
This is not a simulation - it's testing the actual package.
index.html- WebAssembly CSP test pageserver.js- HTTP server with configurable CSP headerspackage.json- Package metadata (no runtime dependencies needed)README.md- This file
The test calls moduleFactory.default() from @journeyapps/wa-sqlite which:
- Loads the wa-sqlite WASM binary
- Compiles and instantiates the WebAssembly module
- Requires CSP
wasm-unsafe-evalpermission for step 2
This is the EXACT SAME operation PowerSync performs during initialization. If this succeeds, PowerSync will work. If this fails due to CSP, PowerSync will also fail.
Safari enforces CSP most strictly:
- Without
wasm-unsafe-eval: Immediately blocksWebAssembly.compile() - With
wasm-unsafe-eval: Allows WASM compilation normally
Chrome and Firefox also enforce this, but Safari's strict enforcement makes it the most common place developers discover the issue.
Is wasm-unsafe-eval safe?
✅ YES - It's more secure than unsafe-eval:
wasm-unsafe-eval- Only permits WASM compilation (secure)unsafe-eval- Permits WASM AND JavaScripteval()(dangerous for XSS)
wasm-unsafe-eval is the industry-standard directive for WASM applications. It does NOT enable JavaScript eval() or introduce XSS risks.
Safari has the strictest CSP enforcement and will clearly show blocking behavior:
- Open Safari
- Open Web Inspector (Develop → Show Web Inspector)
- Go to http://localhost:3005/
- Check Console tab
With block-wasm:
❌ ERROR: wa-sqlite WASM module initialization failed
Most likely cause: Content Security Policy is blocking WebAssembly compilation
With allow-wasm:
✅ SUCCESS! wa-sqlite WASM module loaded and initialized
PowerSync Web SDK will work
Also enforce CSP correctly. Test in Safari for best results since it's where customers report issues.
Test fails even with allow-wasm?
- Check server console - is the CSP header being set?
- Hard refresh browser (Cmd+Shift+R) to clear cache
- Check Safari console for CSP violation messages
- Try
no-cspmode - if that works, it's definitely CSP-related
Server won't start?
# Check if port 3005 is in use
lsof -i :3005
# Kill existing process if needed
kill -9 <PID>- Support Ticket: 2026-01-28_email-0001_csp-wasm-unsafe-eval
- Documentation PR: powersync-ja/powersync-docs#344
- SQLite WASM CSP: https://sqlite.org/wasm/doc/trunk/csp.md
- WebAssembly CSP Spec: https://github.com/WebAssembly/content-security-policy/blob/main/proposals/CSP.md
- MDN CSP Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
This test proves that:
- ✅
wasm-unsafe-evalis required for PowerSync Web SDK - ✅ Uses the actual
@journeyapps/wa-sqlitepackage PowerSync depends on - ✅ Safari blocks wa-sqlite WASM without this directive
- ✅
wasm-unsafe-evalis secure (doesn't enable JS eval) - ✅ There are no alternatives to this CSP directive
For production PowerSync deployments, add 'wasm-unsafe-eval' to your script-src CSP directive.