diff --git a/docs/source/IntermediateRepresentation.md b/docs/source/IntermediateRepresentation.md
new file mode 100644
index 000000000..f5c302a7f
--- /dev/null
+++ b/docs/source/IntermediateRepresentation.md
@@ -0,0 +1,32 @@
+# Flatbuffers Intermediate Representation {#intermediate_representation}
+
+We use [reflection.fbs](https://github.com/google/flatbuffers/blob/master/reflection/reflection.fbs)
+as our intermediate representation. `flatc` parses `.fbs` files, checks them for
+errors and stores the resulting data in this IR, outputting `.bfbs` files.
+Since this IR is a Flatbuffer, you can load and use it at runtime for runtime
+reflection purposes.
+
+There are some quirks:
+- Tables and Structs are serialized as `Object`s.
+- Unions and Enums are serialized as `Enum`s.
+- It is the responsibility of the code generator to check the `advanced_features`
+ field of `Schema`. These mark the presence of new, backwards incompatible,
+ schema features. Code generators must error if generating a schema with
+ unrecognized advanced features.
+
+
+## Invocation
+You can invoke it like so
+```{.sh}
+flatc -b --schema ${your_fbs_files}
+```
+This generates `.bfbs` (binary flatbuffer schema) files.
+
+Some information is not included by default. See the `--bfbs-filenames` and
+`--bfbs-comments` flags. These may be necessary for code-generators, so they can
+add documentation and maybe name generated files (depending on the generator).
+
+
+TODO(cneo): Flags to output bfbs as flexbuffers or json.
+
+TODO(cneo): Tutorial for building a flatc plugin.
diff --git a/docs/source/Schemas.md b/docs/source/Schemas.md
index 8c6399e49..12c30a5f2 100644
--- a/docs/source/Schemas.md
+++ b/docs/source/Schemas.md
@@ -637,10 +637,14 @@ optional type.
Some `FlatBufferBuilder` implementations have an option called `force_defaults`
that circumvents this "not writing defaults" behavior you can then use
`IsFieldPresent` to query presence.
-
+/
Another option that works in all languages is to wrap a scalar field in a
struct. This way it will return null if it is not present. This will be slightly
less ergonomic but structs don't take up any more space than the scalar they
represent.
[Interface Definition Language]: https://en.wikipedia.org/wiki/Interface_description_language
+
+## Writing your own code generator.
+
+See [our intermediate representation](@ref intermediate_representation).
diff --git a/docs/source/doxyfile b/docs/source/doxyfile
index 3a5bd98b2..8cf9000da 100644
--- a/docs/source/doxyfile
+++ b/docs/source/doxyfile
@@ -768,6 +768,7 @@ INPUT = "FlatBuffers.md" \
"WhitePaper.md" \
"FlexBuffers.md" \
"Internals.md" \
+ "IntermediateRepresentation.md" \
"Grammar.md" \
"../../CONTRIBUTING.md" \
"Tutorial.md" \
diff --git a/docs/source/doxygen_layout.xml b/docs/source/doxygen_layout.xml
index e1a6b81dc..28dd06541 100644
--- a/docs/source/doxygen_layout.xml
+++ b/docs/source/doxygen_layout.xml
@@ -66,6 +66,8 @@
title="FlatBuffers white paper"/>
+