Every config-driven UI says “no eval.” This one runs the test in front of you.
A strict Content-Security-Policy is the cheapest security control you have, and it is the one that config-driven UI quietly breaks: bindings compiled from strings need unsafe-eval, so the policy comes off. Below is the actual Blueprint validator running under a policy that does not grant it — validating real contracts, reporting zero violations, and then deliberately calling new Function() so you can watch the browser refuse.
Why this matters: Builder.io #3180 — “Failed code evaluation: Code generation from strings disallowed for this context.”
It doesn’t break in dev. It breaks on deploy.
Not our characterisation — the vendor’s own issue tracker. Bindings that work in the editor and on localhost stop working the moment they land somewhere that disallows dynamic code.
[Builder.io]: Failed code evaluation: Code generation from strings disallowed for this context var _virtual_index = state.username; return _virtual_index
Reported on GitHub #3180 and again on their forum #5302.
The environment isn’t exotic. Cloudflare Pages, Vercel Edge, Deno Deploy and any page with a strict CSP all refuse code generated from strings — for the same reason you want that refusal.
The workaround is to weaken the policy. Adding 'unsafe-eval' restores the bindings and removes the control that made script injection hard in the first place.
On a payment page that is not a preference. PCI DSS 4.0 §6.4.3 requires every script to be inventoried and justified — and code produced at runtime is, by construction, not what you inventoried.
Not a screenshot. The runtime, in this page, right now.
The frame below is a self-contained document with its own Content-Security-Policy, isolated from this site. It bundles the real runtime — blueprint-core and zod — validates contracts, and counts CSP violations. Expected: zero. Then it attempts new Function() on purpose, and the browser blocks it. That last step is the important one: it proves the policy is enforced rather than decorative.
Content-Security-Policy: default-src 'self'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; base-uri 'none'
Inline is allowed so the bundled demo can run at all. Eval is not — and that is the axis the whole argument turns on. Nothing here is granted 'unsafe-eval'.
Three receipts, because one is an assertion.
The browser enforces it
The demo above is not our verdict, it is the browser’s. A deliberate new Function() is refused by the same engine that would refuse an injected payload.
A tripwire test guards it
no-eval.test.ts swaps globalThis.Function and globalThis.eval for throwing stubs while a real contract is validated, and asserts neither is ever invoked. It fails loudly if anyone regresses it.
The dependency closure is published
SBOM.md lists the runtime’s entire production closure. It is short enough to read in an afternoon, which is the point — you cannot audit what you cannot finish reading.
A source grep would have missed it. Twice.
The guarantee is not “we never typed the word eval.” zod v4 JIT-compiles validators with new Function, and probes for eval availability with new Function(""), unless it is configured jitless — which our schema does. A grep would not catch the regression if that config were dropped, and it would not catch an alias either, because a library can simply write const F = Function.
// Swap the dynamic-code primitives for tripwires.
globalThis.Function = function (): never {
touched = 'new Function';
throw new Error('new Function was called');
};
validate(doc); // a real nested contract
expect(touched).toBe(''); // never invokedWhich is why the guarantee is enforced at runtime, not by reading the source. If someone regresses the config, adds an eval-using path, or bumps zod to a version that ignores jitless, CI stops.
The honest part
This proves the Blueprint runtime executes no dynamic code. It does not prove your application doesn’t — your own code, your other dependencies, your analytics tag and your consent banner are all still yours to account for. What it removes is one specific and common reason teams are told to loosen a policy they had every reason to keep. Whether your CSP is strict everywhere else remains your call, and your assessor’s.