diff --git a/text/0000-reparenting.md b/text/0000-reparenting.md
new file mode 100644
index 00000000..78aa8e69
--- /dev/null
+++ b/text/0000-reparenting.md
@@ -0,0 +1,603 @@
+- Start Date: 2018-03-11
+- RFC PR: (leave this empty)
+- React Issue: (leave this empty)
+
+# Summary
+
+When writing a component that contains a set of large subtrees that stay relatively the same, but are simply moved around such that React's virtual DOM diffing can't detect the movement, React will end up recreating huge trees it should simply be moving.
+
+The goal of this RFC is to introduce a "Reparent" API that allows portions of the React tree to be marked in a way that allows React to know when to move them from one part of the tree to another instead of deleting and recreating the DOM and component instances.
+
+# Basic example
+
+## Layout
+
+Using reparents to render a page layout that can change structure between desktop and mobile without causing the page contents and sidebar to be recreated from scratch.
+
+```js
+class Layout extends PureComponent {
+ header = React.createReparent();
+ content = React.createReparent();
+ sidebar = React.createReparent();
+
+ render() {
+ const {isMobile, children} = this.props;
+
+ const header = this.header(
+
+ );
+ }
+ }
+}
+```
+
+## Detach trees of dom nodes / components
+
+```js
+class Foo extends Component {
+ componentDidMount() {
+ console.log('Mounted');
+ }
+ componmentWillUnmount() {
+ console.log('Unmounted');
+ }
+ render() {
+ return null;
+ }
+}
+
+class DetachableTree extends Component {
+ reparent = React.createReparent();
+
+ render() {
+ const content = this.reparent(this.props.children);
+ return this.props.show && content;
+ }
+}
+
+ReactDOM.render(
+
+
+ ,
+ container);
+// log: Mounted
+
+// Children can be detached from the dom tree with `show = false`
+ReactDOM.render(
+
+
+ ,
+ container);
+// But they will not actually be unmounted
+
+// If you set `show = true` later, the previously rendered state tree will be re-inserted
+ReactDOM.render(
+
+
+ ,
+ container);
+
+// The state tree of the reparent is what is retained, not the contents.
+// So if you change the contents of the DetachableTree, then components unmount as normal
+ReactDOM.render(
+
+
+ ,
+ container);
+// log: Unmounted
+// log: Mounted
+
+// But if you unmount the DetachableTree the reparent will unmount
+// and all of the normal react elements inside will also unmount.
+ReactDOM.render(
+ ,
+ container);
+// log: Unmounted
+```
+
+## Table with movable cells
+
+Using dynamic reparents within a table to ensure that cells are not recreated from scratch when moved from one row to another.
+
+```js
+class TableWidget extends PureComponent {
+ state = {
+ table: {
+ cols: 4,
+ rows: 0,
+ cells: [],
+ },
+ };
+
+ addRow() {
+ this.setState(state => ({
+ table: update(state.table, {
+ rows: state.table.rows + 1,
+ cells: {
+ [state.table.rows + 1]: {
+ $set: new Array(state.table.cols).fill(null),
+ },
+ },
+ })
+ }));
+ }
+
+ addData(row, col, data) {
+ this.setState(state => ({
+ table: update(state.table, {
+ cells: {
+ [row]: {
+ [col]: {
+ $set: {
+ id: uuid(),
+ data,
+ },
+ },
+ },
+ },
+ })
+ }));
+ }
+
+ moveData(from, to) {
+ this.setState(state => {
+ let {table} = state;
+ // Set the to cell to the from cell's data
+ table = update(table, {
+ cells: {
+ [to.row]: {
+ [to.col]: {
+ $set: table.cells[from.row][from.col],
+ },
+ },
+ },
+ });
+ // Set the from cell to null
+ table = update(table, {
+ cells: {
+ [from.row]: {
+ [from.col]: {
+ $set: null,
+ },
+ },
+ },
+ });
+ return {table};
+ });
+ }
+
+ removeData(row, col) {
+ this.setState(state => {
+ // Set the cell to null
+ let {table} = state;
+ table = update(table, {
+ cells: {
+ [row]: {
+ [col]: {
+ $set: null,
+ },
+ },
+ },
+ });
+ return {table};
+ });
+ }
+
+ // Dynamic store for reparents, the reparents are created as-needed for cells in the table
+ cells = Object.create(null);
+ getCell = (cell, row, col) => {
+ this.cells[cell.id] = this.cells[cell.id] || React.createReparent();
+ return this.cells[cell.id]();
+ };
+
+ render() {
+ const {table} = this.props
+
+ return (
+
+ {table.cells.map((cols, row) => (
+
+ {row.cols.map((cell, column) => (
+
+ {this.getCell(cell, row, column)}
+
+ ))}
+
+ ))}
+
+ );
+ }
+}
+```
+
+## Dynamic template
+
+Using reparents in a dynamic template/widget structure to avoid recreating widgets from scratch when they are move from one section of the template to another.
+
+```js
+const TemplateWidgetReparentContext = React.createContext({});
+
+class ReparentableTemplateWidget extends PureComponent {
+ static getDerivedStateFromProps(nextProps, prevState) {
+ if ( !prevState.widget || prevState.widgetType !== nextProps.widget ) {
+ const WidgetClass = getWidgetClassOfType(nextProps.widget);
+ return {
+ widgetType: nextProps.widget,
+ widget: new WidgetClass(),
+ };
+ }
+ }
+
+ render() {
+ const {widget} = this.state;
+
+ return (
+
+ {widget.render()}
+
+ );
+ }
+}
+
+/**
+ * This wrapper uses reparents from Template and the widget's own id
+ * to ensure that when a widget is moved from one section to another
+ * it is moved by react instead of recreated.
+ *
+ * This could be turned into an HOC
+ */
+class TemplateWidget extends Component {
+ render() {
+ const {id} = this.props;
+
+ return (
+
+ {templateWidgetReparents => templateWidgetReparents[id](
+
+ )}
+
+ );
+ }
+}
+
+class Section extends PureComponent {
+ render() {
+ const {title, widgets} = this.props;
+
+ return (
+
+
{title}
+ {widgets.map(widget => (
+
+ ))}
+
+ );
+ }
+}
+
+class Template extends PureComponent {
+ static getDerivedStateFromProps(nextProps, prevState) {
+ if ( nextProps.sections === prevState.sections ) return;
+
+ const widgetIds = new Set();
+ nextProps.sections.forEach(section => section.widgets.forEach(widget => widgetIds.add(widget.id)));
+
+ const templateWidgetReparents = {};
+
+ for ( const id of widgetIds ) {
+ if ( prevState.templateWidgetReparents && prevState.templateWidgetReparents[id] ) {
+ templateWidgetReparents[id] = prevState.templateWidgetReparents[id];
+ } else {
+ templateWidgetReparents[id] = React.createReparent();
+ }
+ }
+
+ return {
+ sections: nextProps.sections,
+ templateWidgetReparents,
+ };
+ }
+
+ render() {
+ const {sections, templateWidgetReparents} = this.state;
+
+ // Make sure React detaches trees for reparents we are still using instead of unmounting them
+ for ( const reparent of Object.values(templateWidgetReparents) ) {
+ reparent.keep();
+ }
+
+ return (
+
+ {sections.map(section => {
+
+ })}
+
+ );
+ }
+}
+
+let templateData = {
+ sections: [
+ {
+ id: 's-1',
+ title: 'Untitled 1',
+ widgets: [
+ {
+ id: 'w-1',
+ widget: 'paragraph',
+ props: {
+ text: 'Lorem ipsum...'
+ }
+ }
+ ]
+ },
+ {
+ id: 's-2',
+ title: 'Lorem ipsum',
+ widgets: []
+ }
+ ]
+};
+
+ReactDOM.render(, app);
+
+// Modify the template to move widget:w-1 to section s-2,
+// it should not be necessary to re-create widget w-1 from scratch
+templateData = {
+ sections: [
+ {
+ ...templateData.sections[0],
+ widgets: []
+ },
+ {
+ ...templateData.sections[1],
+ widgets: [
+ templateData.sections[0].widgets[0]
+ ]
+ }
+ ]
+};
+ReactDOM.render(, app);
+```
+
+# Motivation
+
+Up till now the only way to handle reparenting has been using `ReactDOM.unstable_renderIntoContainer` or Portals to separate a dom node from react rendering and allow that node to be moved around. However this is a complex hack that only works with ReactDOM, it does not work with isomorphic React web apps or other environments like React Native.
+
+This reparenting issue have been left alone for awhile. We have an RFC process now. An RFC for a new context API has made an unstable feature of React stable. And accepted RFCs like createRef have given suggestions on what APIs fitting of React might look like. I think now is a good time to try tackling reparenting.
+
+## Goals of reparenting
+
+1. Ensure that react instance state (`state` and `this.*`) is not destroyed when reparenting.
+2. Avoid the high cost of re-render when React could just move a component from one parent to another.
+3. Where possible, retain the state of the underlying element external to React: like video buffers, state contained in custom-element instances, 3rd party library annotations (e.g. jQuery's `data` storage), and other native state.
+
+1 and 2 have a high enough value that it's ok for 3 to not function completely, where incomplete means:
+
+- The platform is non-dom and may not actually have a dom-like concept of moving a view from one parent to another.
+- Some of the state in the native element is lost when we use appendChild like focus, scroll, playing state (see [Limitations](#limitations)).
+
+More motivation can be found in past discussions on reparenting:
+
+- [Support for reparenting (facebook/react#3965)](https://github.com/facebook/react/issues/3965)
+- [A gist that has hosted a lot of reparenting discussion](https://gist.github.com/chenglou/34b155691a6f58091953)
+
+# Requirements
+
+There are a variety of use cases for reparenting. Some of them have certain requirements of the API that not all suggestions cover.
+
+1. It must not rely on user-provided strings.
+
+ We already use string keys for local key comparisons. This works fine for local keys, but guaranteeing the application wide uniqueness of a string should not be a requirement of using a reparent. No other React API works this way and it adds difficulty to usage of reparents within libraries.
+
+2. It must be possible to detach a tree and reuse it later.
+
+ Sometimes you want to detach a tree and hold on to it instead of just moving it around. For example, it may be beneficial to remove a modal's contents when not in use. Or the detached nature may simply be a side effect of complex application logic, perhaps involving async and nested components, which results in it being difficult to guarantee that a reparent is present somewhere in the react state tree. Thus any implementation must provide enough information for React to differentiate between when a reparent is not present in a tree but has just been detached; and when a reparent is no longer in use by its owner and should be unmounted.
+
+3. It must be possible to create reparents dynamically.
+
+ Sometimes instead of a reparent being used for a known tree that you just want to move, it is instead used for dynamic content that comes from some store/database. You need to be able to move the content generated from this from one part of the state tree to another. But any number of these may exist at once.
+
+ Thus it must not be a requirement that reparents be known ahead of time. Additionally, because reparents for dynamic content can be removed dynamically it must be possible to unmount any reparent no longer in use, without the owner of the reparent itself having to unmount.
+
+4. It must be possible to use a reparent in the render method of a component that is a descendent of the actual owner.
+
+ Special use cases the dynamic template example and common use cases like Drag & Drop often may involve moving a reparent from one React component to another React component. Thus it must be possible for the reparent's owner to be a React component higher up in the state tree that is able to pass its reparents down to children (through props or context) and have those children render the reparent.
+
+5. Requirements 2, 3, and 4 interact specially and a proper reparent implementation must satisfy all of them at the same time.
+
+ - Unmounting in React involves the calling of lifecycle methods that may involve cleanup of possible global subscriptions (event listeners, data observers, etc) which may leak if not done. As a result we cannot simply store a reference to the state tree in a reparent and let the state tree be GCd when the reparent is no longer being referenced by the code that created it. React must hold a reference to the state tree and explicitly unmount it when not in use.
+ - Reparents may be created/destroyed dynamically and be owned by a component that may never unmount. So we need to know when we can unmount a reparent, separate from just when its owner unmounts.
+ - We need detached trees, so we cannot simply unmount any reparent that is no longer present in the state tree.
+ - A reparent may be rendered in a component other than its owner. Thus we cannot simply unmount a reparent when it has not been used in the render method of its owner.
+
+ As a result, in addition to implementing the global-ishly unique key behaviour needed to move reparents any implementation also needs to provide an explicit declaration that can be used to differentiate detached from unused reparents.
+
+6. It cannot require React DOM's Portals.
+
+ Portals only work in the client side DOM code. They don't work on the server, if you render something isomorphic and then put it into a portal on the client it will be recreated from scratch. And Portals are not available in non-dom environments like React Native. While native doesn't necessarily need reparenting for native views, reparenting itself is still useful as a way of keeping the state of React components without resorting to moving absolutely everything into Flux/Redux.
+
+# Glossary
+
+- **state tree**: The state tree refers to both the tree of DOM nodes or other tree of native elements React is rendering to (for React Native and 3rd party environments) and the tree of React Components that allows React to reuse an instance of a Component on a future render.
+- **global-ish key**: The global-ish key nature of reparents refers to how normally in react the string `key="..."` is only locally unique within its parent, but a reparent must be unique within any parent. Generally this would be though of as "globally unique", however because reparents have an owner they only actually need to be unique within the portion of the state tree under their owner.
+
+# Detailed design
+
+This proposal introduces a `React.createReparent()` function which returns a new *Reparent*. The "Reparent" naming is open to better name proposals.
+
+The Reparent itself is a function that accepts children for the reparent. The return value is a special Fragment used to render the reparent and its contents somewhere in the state tree.
+
+A Reparent has an additional `.keep()` method that acts like calling the Reparent function but without modifying children or returning the fragment. This function is used to allow components to tell reparents to hold references to state trees without actually rendering them and without doing so in a permanent way that would leak memory. This allows reparents to be hoisted upwards by registering the Reparent in a parent Component and then passing the Reparent down to children through props or context for a descendant to render. And allows them to be used for dynamic and async content where the reparent may not be rendered for a moment. See the "Dynamic template" example.
+
+When the Reparent function or its `.keep()` is called in a `render()` React notes that the component the `render()` belongs to "has a reference" to the reparent.
+
+At the end of a render if no `render()` "has a reference" to the reparent then React will discard the state tree and unmount any components inside the reparent's children as normal.
+
+At the end of a render if at least one `render()` "has a reference" to the reparent but a fragment created by the reparent function is not present in the the result of any `render()` instead of discarding the state tree React will *detach* the state tree and keep a reference to it. React components in the children will not be unmounted. If the native tree can reasonably detached the renderer should make an effort to detach the tree. If the native tree does not have a concept of being detached and re-attached it is acceptable for the native tree to be removed and recreated later.
+
+For react-dom this means using `removeChild` to detach the dom tree and keeping a reference to it in memory to re-insert into the dom later with `appendChild`/`insertChild`. When React DOM intends to move a DOM node (because the Reparent from a previous calls to render has a different parent in the virtual DOM on a later render) React DOM should avoid using `removeChild` and instead just call `appendChild`/`insertChild` without first calling `removeChild` (unless it detects some sort of situation like a reference cycle that would make this impossible). This is an attempt to avoid some of the side effects of Reparenting, in particular it is to avoid IE11's behaviour of pausing a `