主题与校验器是独立包,需按需额外安装对应主题包和 validator 包;README 未给出具体安装命令,上述命令需按官方文档核对
react-jsonschema-form
rjsf-teamApache-2.0活跃维护用 JSON Schema 自动生成 React 表单,省去手写表单和校验逻辑,适合配置化、动态表单场景。
A React component for building Web forms from JSON Schema.
npm install @rjsf/core @rjsf/utils @rjsf/validator-ajv8README 未说明
用 JSON Schema 声明式生成 React 表单的组件库,省去手写表单代码
用 JSON Schema 自动生成 React 表单,省去手写表单和校验逻辑,适合配置化、动态表单场景。
核心能力
- 根据 JSON Schema 声明式构建并自定义 Web 表单
- 提供 Ant Design、MUI、Chakra UI 等十余种主题包
- 拆分出 @rjsf/utils 与多种 validator 校验库
- 提供在线 Playground 可直接试玩表单效果
容易踩的坑
- v6.11.16.11.1最新正式版2026-11-05 · 2026-11-05 08:16 UTC
@rjsf/core
- Updated
markdown-to-jsxfrom^9.8.2to^9.10.3(#5420) - Fixed
Formfailing validation withmust be boolean(or the matching type error) when the rootformDatais a falsy value such asfalse,0or''. Onlyundefinedis now treated as missing before validating, fixing #5404 - Fix
Formcrashing withMaximum update depth exceededwhen a widget orsetFieldValue()callsonChangemore than about 50 times in one event (#5631, #5532) - Fix
Formignoring later changes after a change whosecustomValidateortransformErrorsthrows. The form keeps its state and the error is rethrown from a timeout (#5631) - Potentially breaking change: Change
setFieldValue()so a throw fromcustomValidateortransformErrorsis rethrown from a timeout, so atry/catcharoundsetFieldValue()no longer catches it (#5631) - Potentially breaking change: Change
Formto no longer call its deprecatedomitExtraData()method, so a subclass overriding it no longer affectsliveOmit, a submit orvalidateForm(). A submit no longer callsvalidateFormWithFormData()either (#5631) - Potentially breaking change: Change
customValidate,transformErrorsand the validator to run whileFormrenders a change, so they must be pure: they can run more than once per change, and must not set another component's state (#5631) - Potentially breaking change: Remove the undocumented
FormmemberspendingChangesandprocessPendingChange()(#5631) - Change
noValidateto hide custom errors a widget raised, including ones raised before it was turned on; they show again once it is turned off (#5631) - Fix
ErrorListand theonChangeevent still listing a widget's custom error after an edit cleared it, with live validation off (#5631) - Change live validation on change to run once per burst of changes in one event, for the last one; the events of the changes before it report the errors from before the burst (#5631)
- Fix
Formreverting changes made in the same event as a submit, or as a blur withliveValidateorliveOmitset to'onBlur'. A throw from a blur's live validation is now rethrown from a timeout (#5631, #5660) - Potentially breaking change: Change a submit to validate and submit the data and schema of the changes made in the same event, rather than those from before them, so
onSubmitgets the data the form shows. ItscustomValidateandtransformErrorsnow run whileFormrenders,focusOnFirstErroris called after the errors render, and a throw is rethrown from a timeout. WithcreateRoot, a change made outside a React event, such as after anawait, or in a transition is still not included (#5631) - Fix a blur with
liveOmitset to'onBlur'omitting extra data against the schema from before a schema change the parent made in the same event as a field change (#5631) - Fix the errors of an old schema coming back after a schema chang
- Updated
- v6.11.06.11.02026-09-28 · 2026-09-28 23:53 UTC
查看更新说明
New feature
- requiredBooleanDefault was added to the
Experimental_DefaultFormStateBehavior
@rjsf/core
- Fixed a
schemaprop change being silently dropped when it adds a property with adefault, either as the parent's reply toonChangeor at any point after a change to an uncontrolled form. The guard that keeps a oneOf/anyOf option switch from reverting now only applies when the form re-derives its ownformData(an uncontrolled form, or a parent holding whatonChangeemitted, including when it reshaped the emitted value by spreading it, storingundefinedasnullor round-tripping it through JSON) with the sameschemaandexperimental_defaultFormStateBehavior, and it keeps only thatformDatarather than dropping the rest of the prop update, fixing #5294 - Fixed switching between
oneOf/anyOfoptions keeping a value the previous option'sdefaultput there, so a property whose value still matches that default, or a whole option that does, now picks up the new option'sdefaultthe way a scalar property already did, and switching back to an option restores its own defaults. A property the new option cannot hold as it stands now picks the newdefaultup as well instead of arriving empty — one whose type differs between the options, or areadOnlyone edited away from its default. Values are compared whole, so a nested object the user has partly edited keeps the rest of the old option's defaults, and a value equal to the old default is replaced no matter who supplied it, including one passed informData, since the two cannot be told apart, fixing #4476
@rjsf/utils
- Updated
Experimental_DefaultFormStateBehaviorto add a newrequiredBooleanDefaultoption, and updatedgetDefaultFormState()to honor it:skipturns off thefalsepopulated for a required boolean with nodefault(introduced in 6.9.0 by #5170), so a form that models an unanswered boolean as its own state can keep itundefinedand letrequiredreport it. The default,populateFalse, keeps the 6.9.0+ behavior
@rjsf/validator-ata
- Updated
ata-validatorfrom^1.7.1to^1.23.0, picking up the corrected error shape forunevaluatedProperties(the error now carriesparams.unevaluatedProperty), the removal of a quadratic inadditionalProperties: falseschemas with many properties, a fix for a hang on truncated JSON input, and enforced strict-mode schema checks (#5293)
Dev / docs / playground
- Documented the
requiredBooleanDefaultoption inform-props.mdandinternals.md, and added a selector for it to the playground
- requiredBooleanDefault was added to the
- v6.10.16.10.12026-09-16 · 2026-09-16 15:29 UTC
查看更新说明
@rjsf/core
- Fixed a
dependencies/ifbranch switch nested inside an object property never sanitizing a sibling field's now-invalid value. The check gating sanitization only compared the root retrieved schema, which never reflects a conditional resolved deeper in the tree, so it always skipped sanitizing in that case, fixing (#5250) - Fixed
NumberFieldlosing or misinterpreting decimal input in comma-decimal locales, and passing a locale-formatted string instead of anumberto custom and format-registered widgets, fixing #5199 and #5241 - Fixed
NumberFieldstill comma-formatting the displayed value for atextwidget with an explicitui:options.inputTypeoverride in a comma-decimal locale;getInputProps()gives that override priority over the locale-basedtextfallback, so it rendered a native, locale-unaware<input type="number">that rejected the comma-formatted string
@rjsf/mantine
- Fixed
BaseInputTemplatepassing anundefinedvalue straight through toNumberInput/TextInput, which let the DOM input fall out of sync with React's controlled value and retain a stray digit after clearing a multi-digit number field (#5269) - Backported the
fluidContainerlayout fix from the v7 Mantine 9 upgrade (#5260):GridTemplate's andObjectFieldTemplate's rootContainernow use Mantine'sfluidprop so forms fill their available width instead of centering at Mantine's default 960px max-width
@rjsf/shadcn
- Fixed the documented
import '@rjsf/shadcn/dist/[theme].css'failing to resolve. The prebuilt stylesheets were in the published tarball but noexportsentry matched them, so Node and every bundler that honours the exports map rejected the path
@rjsf/utils
- Fixed
sanitizeDataForNewSchema()to resolvedependencies,if/then/elseandallOf(not just$ref) on each property's old/new schema before comparing them, so a conditional nested inside an object property is taken into account when sanitizing its data, fixing (#5250) - Added
schemaHasNestedConditional(), whichFormuses to detect adependencies/ifnested below a schema's top level (behind a$ref,patternProperties, tupleitems,additionalPropertiesorallOf/anyOf/oneOf) so sanitization isn't skipped just because the root retrieved schema looks unchanged (#5250) - Fixed
getInputProps()defaultingtype: numberschemas to a nativenumberinput in locales whose decimal separator isn't., where the browser rejects the localized value; it now defaults to atextinput in those locales unless an explicitinputTypeis set - Added
resolveDefaultWidget(), extracting the widget-name/enumOptionsfallback logic shared by@rjsf/core'sStringFieldandNumberFieldso the two can no longer drift out of sync - Upgraded
@x0k/json-schema-mergeto^1.0.6, which now preserves Symbol-keyed properties (e.g.Symbol(__rjsf_ref)) when mergingallOfschemas and no longer collapses distinctallOf.containsbranches into one over-constrained schema; removed the corresponding Symbol-preservation andcontains-extraction workarounds fromretrieveSchemaInternal(), fixing (#5146) - Fixed defaults from a dependency subschema being omitted when
getDefaultFormState()is called without form data or with an empty object, fixing #5198 - Fixed
computeDefaults()to merge a non-object schema's
- Fixed a
- v6.10.06.10.02026-09-09 · 2026-09-09 16:27 UTC
查看更新说明
New Feature added
autocapitalize support was added to the uiSchema
Also, since 6.9.0 failed to release properly, this also contains all of its content
@rjsf/chakra-ui
- Removed an
environmentprop the test wrapper passed toEnvironmentProvider, which has no such prop and silently ignored it
@rjsf/core
- Fixed defaults not being restored when returning to an
anyOforoneOfoption with disjoint properties (#3736) - Added
ui:autocapitalizesupport for inputs rendered byBaseInputTemplate, allowing mobile keyboards to apply the requested capitalization behavior (#2187)
@rjsf/mantine
- Added
ui:autocapitalizesupport for text inputs (#2187)
@rjsf/mui
- Added
ui:autocapitalizesupport for text inputs (#2187)
@rjsf/utils
- Fixed
sanitizeDataForNewSchema()clearing existing arrays or preserving staleundefinedvalues instead of retaining data or applying defaults for properties newly defined by the incoming schema (#3736) - Added
autocapitalizeUI option handling togetInputProps()and its public input prop types (#2187)
@rjsf/validator-ajv8
- Changed the
standaloneCodeimport to name the file,ajv/dist/standalone/index.js, instead of the directory subpathajv/dist/standalone. Atsc-aliasreplacer used to patch this into the emitted output; the source now says what it means. No public API changed
Dev / docs / playground
- Relative TypeScript imports now name their real
.ts/.tsxsource file (and an explicitindex.tsfor directory imports), and TypeScript'srewriteRelativeImportExtensionsemits the.jsspecifiers directly. This removestsc-aliasand its post-emit string rewriting entirely, along with thetsc-alias-replacer/directory, bothtsconfig.replacer.jsonfiles, thecompileReplacerscripts andmove-file-cli. Naming the source file rather than the output is deliberate: Node's native type stripping requires exact.tsextensions and does no extension or directory-index searching, so this avoids a second repository-wide import migration later - Fixed
packages/daisyui/test/tsconfig.json, which was configured to emit into../dist— the esbuild/rollup bundle output directory — instead of type-checking without emit like every other test project - Collapsed each package's
tsconfig.json+tsconfig.build.json+src/tsconfig.jsonchain into one source config plus one test config extending a new shared roottsconfig.test.json. Building a package no longer pulls its dependencies' test projects into the graph - Fixed the root
tsconfig.json, which referencedsnapshot-teststwice and omittedmantine,primereact,validator-ataandvalidator-cfworker. It now lists every source and test project once, and a new roottypecheckscript runs in CI, so tests are typechecked for the first time. That surfaced stale tests in@rjsf/chakra-uiand@rjsf/validator-ataand two drifted playground samples, fixed here.@rjsf/chakra-ui'stype-checkscript previously ran against a solution config withfiles: []and checked nothing - Every package now emits
lib/with the same settings:esnexttarget plus.js.mapand.d.ts.map. Previously only@rjsf/coredid; the rest emitted ES2018 with JS source maps only, depending on which root config theirsrc/tsconfig.jsonextended tsconfig.tsbuildinfois no longer written intolib/and publis
- Removed an
- v6.9.06.9.02026-08-30 · 2026-08-30 21:07 UTC
查看更新说明
Potentially breaking change:
lodashandlodash-esare no longer dependencies of any@rjsf/*package. No RJSF public API changed, but an application that importslodashitself without declaring it — relying on it being hoisted intonode_modulesbecause RJSF depended on it — must now addlodashto its ownpackage.json.@rjsf/antd
- Updated
CheckboxWidgetto append a*onto the end of the label when the field is required AND the schema value is hardcoded totrue, fixing #4136 - Declared
"sideEffects": falseinpackage.json, allowing bundlers to tree-shake unused exports - Fixed
BaseInputTemplateto clearnumber/integerfields back toundefinedinstead ofnullwhen theInputNumberwidget is emptied, fixing #5213 - Fixed
BaseInputTemplate'sui:allowClearTextInputsclear button to storeui:emptyValue(undefinedby default) instead of always storing"", so clicking it now behaves exactly like clearing the input by typing. Potentially breaking change: an app that never setsui:emptyValueand clicks the clear button on a field (rather than backspacing it) previously got""back; it now getsundefined, matching every other way of emptying the field.
@rjsf/chakra-ui
- Updated
CheckboxWidgetto append a*onto the end of the label when the field is required AND the schema value is hardcoded totrue, fixing #4136 - Declared
"sideEffects": falseinpackage.json, allowing bundlers to tree-shake unused exports - Fixed
BaseInputTemplate'sui:allowClearTextInputsclear button to storeui:emptyValue(undefinedby default) instead of always storing"", so clicking it now behaves exactly like clearing the input by typing. Potentially breaking change: an app that never setsui:emptyValueand clicks the clear button on a field (rather than backspacing it) previously got""back; it now getsundefined, matching every other way of emptying the field.
@rjsf/core
- Declared
"sideEffects": falseinpackage.json, allowing bundlers to tree-shake unused modules; a consumer importing onlyFormno longer bundles the AJV validator chain pulled in bygetTestRegistry, shrinking a minimal bundle by ~34kB gzipped - Fixed
TimeWidgetto respect schemamultipleOftime precision, preserving second-precision values while keeping minute-precision native inputs synchronized with their displayed value (#5174) - Replaced all path-based
lodashusage (get,set,unset,toPath,pick) with the new@rjsf/utilspath utilities - Replaced the remaining non-path
lodashusage (isEmpty,isObject,isPlainObject,each,flatten,includes,intersection,last,uniqueId,noop) with native equivalents, and dropped thelodash/lodash-esdependencies entirely - Fixed the clearing of errors on change so that only the field that actually changed loses its error, along with the errors the containers holding it own, rather than every field under the top-level key holding it, fixing #5197 (#5205)
- Updated
CheckboxWidgetto append a*onto the end of the label when the field is required AND the schema value is hardcoded totrue, fixing #4136 - Renamed the test file
Form.test.tsxtoForm.behaviors.test.tsxso all theFormtest files follow theForm.<topic>.test.tsxnaming pattern introduced by #5219 - Fixed
ObjectFieldto coerce a clearedadditionalProperties/patternPropertiesvalue to the
- Updated
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Supported Themes
- Ant Design v5
- Bootstrap v3
- Chakra UI v3
- Daisy UI v5
- Fluent UI v9
- Mantine
- Material UI v7
- React-Bootstrap (Bootstrap v5)
- Semantic UI v2
- Shad CN
API Libraries
Documentation
Read our documentation, powered by Docusaurus.
Live Playground
A live playground is hosted on GitHub Pages.
Contributing
Read our contributors' guide to get started.
Credits
Testing powered by BrowserStack
