vite/src
Vite plugin for zod-to-form — transforms ?z2f imports into generated form components and replaces <ZodForm> JSX call sites with static output at build time.
Two modes:
- Query mode (
?z2fimports): import a schema file with a?z2fquery parameter to receive a fully-generated React form component as a virtual module. Zero build step — the plugin compiles on demand. - Generate mode (
options.generate): scan JSX source files for<ZodForm>call sites and replace statically-resolvable ones with generated form components at build time. Opt-in viagenerate: {}.
Config resolution order:
options.configPathif explicitly provided- Auto-discovery of
z2f.config.{ts,mts,js,mjs}in the Vite root DEFAULT_CONFIGmerged withoptions.configOverride
Remarks
Two modes: ?z2f query imports (transform per-import, HMR works) vs generate mode
(static JSX rewriting, no HMR integration). Use ?z2f for new forms, generate for
migrating existing <ZodForm> call sites.
Use When
- You want zero-config form generation directly from
import './schema?z2f'— the plugin intercepts the import and returns a virtual form module - You have a Vite-based app and want to skip the CLI generate step — no separate codegen script needed
- You need per-variant forms (mobile/desktop) from the same schema — append
?z2f=variantNameto get a separate compiled output - You want HMR-aware form recompilation during development — schema file changes invalidate only the affected virtual modules
Avoid When
- You are NOT using Vite — use
@zod-to-form/clifor webpack, esbuild, or Rollup builds - Your schema files have cyclic type references — the
?z2frewriter recurses on Zod's type graph and will hang on cycles - You need SSR-safe form HTML without a client-side React bundle — static codegen produces lighter server-renderable output
- You are on Zod v3 — the plugin only supports Zod v4 schemas
Never
- NEVER use
?z2fon schemas with cyclic type references — the schema walker recurses on Zod's internal type graph and hangs with no timeout or error; FIX: break cycles by extracting shared types into az.lazy()boundary before using the?z2fimport - NEVER assume Zod schema objects survive Vite's module graph isolation intact —
ssrLoadModuleevaluates modules in a fresh context, so schemas imported from barrel files that also import React/RHF may fail due to missing peer globals; FIX: re-export schemas from a dedicated.schema.tsfile with no non-schema imports - NEVER mix
configOverridewith az2f.config.tsthat overlaps the same keys —configOverridewins unconditionally (shallow merge), silently dropping config-file fields; FIX: use eitherconfigPath+ a full config file, orconfigOverrideonly
Errors
Other
default
Renames and re-exports z2fVite