diff --git a/website/_data/guides.yml b/website/_data/guides.yml
index f020ebb8fc2..13e12bf18be 100644
--- a/website/_data/guides.yml
+++ b/website/_data/guides.yml
@@ -103,6 +103,14 @@
- path: "/docs/libdefs/"
# - path: "/docs/libdefs/usage/"
- path: "/docs/libdefs/creation/"
+ additional_reading:
+ - guide: declarations
+
+- id: declarations
+ pages:
+ - path: "/docs/declarations/"
+ additional_reading:
+ - guide: libdefs
# - id: errors
# pages:
diff --git a/website/_data/i18n/en.yml b/website/_data/i18n/en.yml
index 7184f9f72bd..2d75f86bddb 100644
--- a/website/_data/i18n/en.yml
+++ b/website/_data/i18n/en.yml
@@ -218,6 +218,9 @@ docs_additional_reading: "Additional Reading"
"/docs/libdefs/usage/":
title: "Using Library Definitions"
description: ""
+"/docs/declarations/":
+ title: "Declaration Files"
+ description: ".js.flow"
"/docs/modules/":
title: "Modules"
description: ""
@@ -426,6 +429,10 @@ guides:
description: >
Learn how to create and use library definitions for the third-party code
your code depends on.
+ declarations:
+ title: "Declaration Files"
+ description: >
+ Learn how to write and publish types alongside your NPM package.
# errors:
# title: "Debugging Errors"
# description: >
diff --git a/website/en/docs/declarations/index.md b/website/en/docs/declarations/index.md
new file mode 100644
index 00000000000..692f1c153af
--- /dev/null
+++ b/website/en/docs/declarations/index.md
@@ -0,0 +1,87 @@
+---
+layout: guide
+---
+
+## What's a "Declaration File"?
+
+Let's look at a more general, and sometimes more convenient, way to
+declare types for modules: `.js.flow` files.
+
+The exported types of a module may be declared in a _declaration file_ with
+the `.js.flow` extension, colocated with the corresponding _implementation
+file_ with the `.js` extension.
+
+A declaration file for a module shadows a
+colocated implementation file for that module when typechecking other code
+that may depend on that module.
+
+
+For example, suppose we have the following code in a file `src/LookBeforeYouLeap.js`:
+
+```js
+// @flow
+import { isLeapYear } from "./Misc";
+if (isLeapYear("2020")) console.log("Yay!");
+```
+
+Next, suppose that `src/Misc.js` had an incompatible implementation of
+`isLeapYear`, just as above.
+
+```js
+// @flow
+export function isLeapYear(year: number): boolean {
+ return year % 4 == 0; // yeah, this is approximate
+}
+```
+
+If we now create a declaration file `src/Misc.js.flow`, the declarations in it
+will be used instead of the code in `src/Misc.js`. Let's say we have the
+following declarations in `src/Misc.js.flow`.
+
+> NOTE: The syntax for declarations in a declaration file is the same as we've seen in
+> [Creating Library Definitions section](../libdefs/creation).
+
+```js
+// @flow
+declare export function isLeapYear(year: string): boolean;
+```
+
+What do you think will happen?
+
+Right, the `isLeapYear` call in `src/LookBeforeYouLeap.js` will typecheck.
+As this example shows, declaration files must be written with care: it is up
+to the programmer to ensure they are correct, otherwise they may hide type
+errors.
+That said, declaration files provide a very convenient way to write
+specifications for modular typechecking. Sometimes, the implementation code
+may not yet be free of type errors, but we may want to move on and come back
+to fixing the type errors later. Another important use of this feature is for
+libraries, whose implementation code may be too complex to typecheck
+satisfactorily, but whose clients we still want to typecheck against
+well-defined specifications.
+
+## Inlining declarations in regular code
+
+As noted above, declarations should be distinct from regular code. But
+sometimes, it is useful to do declarations "inline," as part of the source of
+an implementation file.
+
+**Proceed with caution!**
+
+The most common use is writing "work-in-progress" code while ensuring that
+your code typechecks. In the following example, say you want to finish writing
+the function `fooList` without bothering to mock up its dependencies first: a
+function `foo` that takes a `number`, and returns a `string` and a class
+`List` that has a `map` method. Easy! (Just don't forget to replace the
+declarations with proper implementations.)
+
+```js
+declare class List {
+ map(f: (x: T) => U): List;
+}
+declare function foo(n: number): string;
+
+function fooList(ns: List): List {
+ return ns.map(foo);
+}
+```
diff --git a/website/en/docs/libdefs/creation.md b/website/en/docs/libdefs/creation.md
index 42e559b605a..0fb77d80a69 100644
--- a/website/en/docs/libdefs/creation.md
+++ b/website/en/docs/libdefs/creation.md
@@ -89,8 +89,7 @@ declare module "some-third-party-library" {
The name specified in quotes after `declare module` can be any string, but it
should correspond to the same string you'd use to `require` or `import` the
third-party module into your project. For defining modules that are accessed via
-a relative `require`/`import` path, please see the docs on the `.js.flow` files
-which will be available soon.
+a relative `require`/`import` path, please see the docs on the [`.js.flow` files](../declarations)
Within the body of a `declare module` block, you can specify the set of exports
for that module. However, before we start talking about exports we have to talk