pbvex-components
PBVex components
Use the project's local pbvex through package scripts or npx pbvex; a matching global CLI is optional.
Use public APIs from pbvex/server: define a component with optional module paths, schema, argument validator, environment declarations, and dependencies; bind functions with defineComponentFns; create a root app with defineApp and typed mount results.
rg -n "defineComponent|defineComponentFns|defineApp|mount\(" pbvex packages/pbvex docs
npx pbvex codegen
npx pbvex typecheck
Give every mount a stable, deliberate name. A mount path determines its namespace: two mounts of the same component get isolated tables and IDs, and IDs are invalid across namespaces. Keep an existing mount path for a compatible upgrade; renaming it deliberately selects new data. Removing a mount/table leaves owned data dormant for rollback or a later remount at the same path.
Contracts and generated calls
Component mount args must use a validator. Required args are required; optional/defaulted args may be omitted. Environment bindings are strings at runtime: declare literal values or server environment variable names, never commit secrets merely to make them available. Component functions use the bound ctx.args/ctx.env plus normal capabilities; generated component api.components... and internal.components... references are the only supported typed call path.
Component schemas may own top-level v.image() fields. A component function's generateUploadUrl({ table, field }) resolves the policy from that mounted component schema, while stored file bytes remain in the application-wide object store. Keep authorization and ownership inside the component and follow pbvex-storage for URL modes and variants.