diff --git a/text/0000-isomorphic-ids.md b/text/0000-isomorphic-ids.md
new file mode 100644
index 00000000..07578864
--- /dev/null
+++ b/text/0000-isomorphic-ids.md
@@ -0,0 +1,315 @@
+- Start Date: 2018-03-08
+- RFC PR: (leave this empty)
+- React Issue: (leave this empty)
+
+# Summary
+
+Many accessibility features of HTML require linking elements using IDs. There is
+currently no easy and consistent way to programmatically handle these IDs in a
+way that survives the client hydration process when server-side rendering is
+involved.
+
+The key issue to solve here is a way to express relationships between
+HTML elements that are identified by the ID attribute in a way that allows that
+relationship to be valid and deterministic on both the server-side and
+client-side render of the tree.
+
+# Basic example
+
+Consider a simple Checkbox component.
+
+```js
+// Checkbox.js
+class Checkbox extends React.Component {
+
+ render() {
+ const { label, value, name, disabled } = this.props;
+ const id = generateUniqueId(); // Any UUID-generating function.
+
+ return (
+
+
+
+
+ );
+ }
+
+}
+
+// App.js
+
+```
+
+The current state of the isomorphic world would result in something to the
+effect of:
+
+```
+// Browser console.
+Warning: prop `id` did not match. Server: "Checkbox:..." Client: "Checkbox:...."
+```
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**The goal of this RFC is to ensure that there is a way to guarantee that the
+IDs used by the server and client are the same.**
+
+# Motivation
+
+In order to successfully link the `label` with the `input`, the `input` element
+must have an ID and that same ID must be supplied to the `label` in the `html-for`
+attribute.
+
+From this component's perspective, the relationship between these two elements
+is always encapsulated inside the component. If only considering client-side
+rendering, the simple solution would be to generate a random, unique ID, store
+it as an instance variable, and assign that value to both elements.
+
+This procedure breaks down when introducing server-side rendering because the
+value will be different between the server's execution and the client's execution
+resulting in an invariance violation (see the Basic Example above).
+
+To work around this, the developer must break encapsulation and supply a unique
+value for every instance. This introduces additional human input and puts an
+unnecessary strain on developers to consider and coordinate uniqueness of IDs
+for these types of components.
+
+There should be no need for users of this component to consider global uniqueness
+when the component itself should know everything it needs to know to render
+correctly.
+
+# Detailed design
+
+There are probably several ways that this could be addressed. The simplest from a
+conceptual standpoint would be to ensure that the render path is deterministic so
+that an auto-increment ID generation approach would result in the same number
+being assigned to each ID.
+
+This is not a great solution. First off, it will probably result in a significant
+performance penalty which would be unacceptable. Secondly, it does not take into
+account potential (intentional) differences in what is rendered server-side and
+client-side.
+
+A more robust solution would be to take advantage of the hydration process to
+absorb attributes included in the server-rendered output into the hydrated DOM
+before it is merged into the browser's DOM.
+
+Let us suppose that we had a way to reserve an identifier from React. Something
+akin to the following:
+
+```js
+// Checkbox.js
+class Checkbox extends React.Component {
+
+ constructor() {
+ this.reserveUniqueIdentifier(); // <------------------------------------NEW
+ }
+
+ render() {
+ const { label, value, name, disabled } = this.props;
+ const id = this.reservedIdentifier(); // <----------------------------- NEW
+
+ return (
+
+
+
+
+ );
+ }
+
+}
+
+// App.js
+
+```
+
+On the server, this component would now be rendered as:
+
+```html
+
+
+
+
+```
+
+> NOTE: Calling `this.reservedIdentifier` without (or before) calling
+> `this.reserveUniqueIdentifier` should result in an exception being thrown.
+
+By calling `this.reserveUniqueIdentifier` in the constructor, an additional
+property can be added to the object to tag it as having a reserved ID. This will
+be useful later for quickly determining if additional steps are needed during
+hydration.
+
+Example:
+```js
+const checkbox = ;
+console.log(checkbox.hasReservedUniqueIdentifier);
+// => true
+```
+
+During hydration, whenever a component is encountered that has a reserved ID,
+it is scheduled for an update before the shadow DOM is merged with the browser's
+DOM. That element's position in the tree is determined and the corresponding
+element in the browser's DOM is retrieved, the `data-react-reserved-id` attribute
+is read, and its value is set as the reserved ID for the hydrated component.
+Then that component is enqueued for an update. Finally, after all components with
+reserved IDs have been updated, the hydrated DOM can be merged with the browser's
+DOM in the usual fashion.
+
+In the case where a corresponding element is not found in the browser's DOM
+(meaning that is was omitted during server-side render), then a new unique ID
+is generated and that new ID is used by the hydrated component.
+
+Furthermore, since this process is part of the hydration process then these
+additional checks will not be performed if not intentionally hydrating SSR output
+ensuring that there is no impact on the `render` path.
+
+### Step-by-step procedure
+
+#### Server procedure
+
+1. `ReactDOM.renderToStaticMarkup` is called.
+1. A `Checkbox` component is encountered.
+1. The `Checkbox` constructor calls `this.reserveUniqueIdentifier()`.
+1. `reserveUniqueIdentifier` determines that it is running on the server using
+ `fbjs/lib/ExecutionEnvironment`.
+1. A unique ID is generated (for example using `UUIDv4`) and set to a private
+ property on the instance. (for example `this.__reservedIdentifier`)
+1. Property `hasReservedUniqueIdentifier` is set to `true` on the instance.
+1. `Checkbox` component's `render` method is called.
+1. The reserved ID is retrieved by the `this.reservedIdentifier()` method
+ that retrieves the value of the private instance variable.
+1. The `data-react-reserved-id` HTML attribute is added to the root element
+ of the component with the value of `this.reservedIdentifier()`.
+1. HTML is sent to the client.
+
+#### Client procedure
+
+1. `ReactDOM.hydrate` is called.
+1. A data structure is created to store references to elements that have reserved
+ identifiers.
+1. A component where `hasReservedUniqueIdentifier` is `true`.
+1. A reference to the Component instance is stored in the above data structure.
+1. After the whole client DOM has been processed:
+ 1. Iterate over instances stored in the above data structure.
+ 1. Determine the DOM path of the element in the shadow DOM.
+ 1. Look up the equivalent DOM path in the browser's DOM.
+ 1. If an element is found:
+ 1. Retrieve the value of `data-react-reserved-id`.
+ 1. If an element is not found:
+ 1. Generate a new ID.
+ 1. Set the value of the instance's `__reservedIdentifier` private property.
+ 1. Enqueue that instance for an update.
+ 1. Perform queued in the shadow DOM.
+1. Merge shadow DOM with browser DOM in normal fashion.
+
+#### Alternative client procedure
+
+1. `ReactDOM.hydrate` is called.
+1. A component where `hasReservedUniqueIdentifier` is `true`.
+1. Look up the equivalent DOM path in the browser's DOM.
+1. If an element is found:
+ 1. Retrieve the value of `data-react-reserved-id`.
+1. If an element is not found:
+ 1. Generate a new ID.
+1. Set the value of the instance's `__reservedIdentifier` private property.
+1. Continue processing the tree.
+1. Merge shadow DOM with browser DOM in normal fashion.
+
+
+# Drawbacks
+
+The major drawback with this approach is that it introduces some potentially
+expensive DOM queries to match up the server-generated DOM with the hydrated
+client DOM as well as an extra step during hydration that causes updates to be
+made before the first client DOM update is made. To be successful, this approach
+should not make a noticeable impact on performance.
+
+The design outlined above is intended to have a very light impact on the existing
+architecture but due to my lack of familiarness with the internals of React, there
+will undoubtedly be issues that I have not anticipated.
+
+# Alternatives
+
+Currently available techniques are lacking since they all require the client code
+to be merged with the DOM before queries can be made to extract any attributes
+that have been left by the server-rendered output. This results in either lost
+information (overwritten by the client render) or a double-render which can cause
+some interesting (and unwanted) side-effects.
+
+The best alternative that I've discovered so far is to set `id` as a required
+prop for these kinds of components, requiring the user to supply a valid value.
+This is also less-than-desirable for reasons outlined in the Motivation section
+above.
+
+# Adoption strategy
+
+This would be an opt-in feature and should only affect individual components
+that ask for a reserved ID. It should have no side-effects for components that
+don't opt in. It should also not have any effect outside of the `hydrate` path.
+
+# How we teach this
+
+Since there is special behavior associated with these reserved IDs, care must be
+given when writing the documentation to distinguish this feature from other IDs
+already present in HTML and React. Hence the suggestion of calling them
+`reservedIdentifier` to avoid confusion with the more ubiquitous `id`.
+
+No re-organization needed for existing documentation. There would be a few
+additional entries to the documentation for `Component` as well as maybe a
+tutorial page.
+
+# Unresolved questions
+
+This RFC represents a high-level proposal for how the goal might be achieved.
+Due to my unfamiliarity with the internals of React, there are undoubtedly still
+many questions that would need to be answered. Some examples off the top of my
+head:
+
+- Can the methodology described above for absorbing HTML attributes from the
+ server-rendered markup be accomplished during the hydration phase before the
+ first DOM merge?
+
+- Would this approach cover all use cases?
+
+- Are there unintended and unwanted side-effects?
+
+- Does this approach work with asynchronous rendering?