Preact 6


  • Preliminary React DevTools support thanks to the amazing @robertknight! 🙇


  • Prevent against reassignment of the same value to TextNodes in Firefox (#368, thanks @zbinlin)
  • When swapping the base of a composed child component, update its parent's base reference (#349)
  • Prevent accidental duplicate recycling of elements when swapping a component's root element (#373, thanks @jakearchibald)

With 6.3.0, the children prop (on a VNode) is now always an Array, even if there are no children. This allows us to skip an existence check when plucking children within render:

// 6.2.1 & prior:
({ children }) => children && children[0];

// As of 6.3.0:
({ children }) => children[0];

This change is backwards compatible since previously an empty array was already being returned for no children in some cases. Now it's just more consistent! 🌈

Bugfix: Switch to using the render parent to determine if re-rendering starting from within an SVG, since the current element may not exist (eg: for a component).


  • Support for infinitely nested children!
  • Massive performance boost for h() (the hyperscript/jsx processor/reviver).
  • Tons of little performance optimizations
  • Allow components to not inherit from Component without caring
  • Add aliases.js and typings.json to the NPM package.

Public Changes

  • Rename Component._disableRendering to Component._disable to save a few bytes
  • Removed undocumented support for getInitialState() on classful components.

This has never been part of the API but was left in core in order to support preact-compat's use. It is now being moved into preact-compat. This allows preact to normalize class components that don't inherit from Component.


  • Fix regression in 6.1.0 where state changes in componentDidUpdate() resulted in synchronous re-renders
  • Fix issue where rendering an SVG element using the className prop (alias) would incorrectly assign className as an attribute. /cc @pl12133
  • Fix serializing class for SVG (test included) (#334)
  • Tons of little optimizations!
  • Don't skip empty values in extend() (and thus in setState()). Fixes #308.
  • Address ownership issue when rendering using reclaimed DOM. Fixes #297.
  • Fix issue where re-rendering an intermediary high order component could remove (or fail to add) the associated element.
  • When removing old props from the DOM, skip those with empty values.
  • Exclusively rely on DOM state when diffing value and checked props. Fixes #326.
  • Use strict equality when comparing attribute values against prop values. Fixes #327.
  • Upon initial entry into diff, check if the diff should start out in SVG mode. Fixes #331.
  • Fix prop cache reset triggering in the wrong case (affected performance)
  • Add typings path to package.json. Fixes #318.
  • Add support for single level of array children in h() (#313)
  • Move both className to class normalization and hashed class stringification out of h() and into the DOM renderer.
    • Tiny possible breakage here: if you were creating VNodes using className and expecting them to have attributes.class instead of attributes.className, that is no longer the case.
  • Fix <input list="id"> when datalist element is placed after the input in the DOM (Issue #294, thanks @vutran!)
  • Fix HMR issue caused by recycling of a re-used Component base. (Issue #295, thanks @katopz!)
  • Make 6.x the official latest release!
npm install --save [email protected]


  • Add support for SVG <foreignObject> (#278, thanks @amio!)
  • Add preact/aliases import: A copy of preact that includes a createElement() alias (#168/#274, thanks @ngasull!)
  • Switch to use event capturing for increased consistency with React (#266/#271, thanks @i-like-robots!)

Breaking Changes

  • Discard keyed nodes when diffing children instead of allowing them to be reused unkeyed
  • linkState() no longer falls back to components path lookups and no longer auto-invokes functions
    • These features were unused & poorly documented, and added extra weight
  • Remove default empty options.vnode hook
    • While this is technically a breaking change, very few people use this API
    • Simply perform an existence check on the previous hook prior to calling it

Bug Fixes

  • Fix and tests for regression in 5.7 that could cause nodes to be removed (related to #260/#277)
  • Fix initial render failing to reuse certain components when picking up from SSR (#260)
  • When swapping between Text, Comment and Element nodes, recycle whole orphaned trees
  • Prevent the recycler from collecting non-Element nodes 🐛
  • Switch back to the pre-5.7 case-sensitive on prefix for event handler props (#275, thanks @c2h5oh!)