Skip to content

feat(schema)!: replace zod with valibot - #8

Merged
AbianS merged 1 commit into
mainfrom
feat/schema-valibot
Sep 25, 2026
Merged

AbianS merged 1 commit into
mainfrom
feat/schema-valibot

Conversation

@AbianS

@AbianS AbianS commented Sep 25, 2026

Copy link
Copy Markdown
Member

Closes #4

Why

parseDemo() runs in the host app on every demo load, so the schema library's size and parse cost are paid by every site that embeds a demo.

Evaluation

The same schema was written in each library. All four were checked against 24 cases (20 invalid inputs and 4 valid ones, including a real steps.json) and give the same results, except that ArkType accepts Infinity. Measured on the real steps.json (6 steps):

Host bundle (Vite, brotli) Module load First parse Warm parse
Zod 4 (before) 23.4 KB 4.5 ms 1.7 ms 1.8 µs
zod/mini 6.8 KB 2.0 ms 0.5 ms 6.0 µs
Valibot 1.5 2.6 KB 0.6 ms 0.3 ms 4.2 µs
ArkType 2.2 42.8 KB 58 ms 0.8 ms 35 µs

Load and first parse are medians of 30 fresh processes. Warm parse doesn't matter here: the demo is parsed once per page.

  • The built package now costs the host 2.8 KB instead of 23.4 KB. player-core itself is 29 KB, so the total download for an embed drops by about 40%.
  • Zod 4 runs a new Function("") probe for its JIT, which fires a securitypolicyviolation report on sites with a strict CSP. Valibot uses no eval.

Changes

  • packages/schema/src/index.ts: schemas rewritten with Valibot, with the same rules. v.finite() keeps rejecting Infinity, as Zod did.
  • New DemoParseError, thrown by parseDemo() instead of the library's error. It's an Error with issues: { path, message }[] (e.g. path: "steps.1.hotspot.x"), so the validator can change again without breaking the public API.
  • New Vitest suite for the schema package (parse-demo.test.ts, 27 tests). The validation rules were pinned against Zod first, then the suite stayed green through the switch unchanged. tsconfig.build.json keeps tests out of dist/, as in exporter.
  • zod@4.6.5 → valibot@1.5.0. Configs, comments, READMEs and CLAUDE.md files updated.

Breaking changes

  • parseDemo() throws DemoParseError instead of ZodError.
  • The exported *Schema values are Valibot schemas instead of Zod schemas. Nothing in the repo uses them.
  • The exported TypeScript types (Demo, Step, …) and parseDemo()'s signature are unchanged.

No changeset in this PR: it will be added later together with the other pending changes.

Checks

biome ci, build, check-types, size and the tests of every package pass.

@AbianS
AbianS merged commit f5b1caa into main Sep 25, 2026
1 check passed
@AbianS
AbianS deleted the feat/schema-valibot branch September 25, 2026 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace Zod with a lighter, faster schema library

1 participant