diff --git a/__tests__/__snapshots__/bin.js.snap b/__tests__/__snapshots__/bin.js.snap
index c060e2a3c..ca6d4bbb8 100644
--- a/__tests__/__snapshots__/bin.js.snap
+++ b/__tests__/__snapshots__/bin.js.snap
@@ -2168,6 +2168,304 @@ f5 comment
 "
 `;
 
+exports[`build GFM (e.g. markdown tables) for -f md 1`] = `
+"<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
+
+### Table of Contents
+
+*   [Klass][1]
+    *   [Parameters][2]
+    *   [getFoo][3]
+        *   [Examples][4]
+    *   [withOptions][5]
+        *   [Parameters][6]
+    *   [withDeepOptions][7]
+        *   [Parameters][8]
+    *   [isClass][9]
+        *   [Parameters][10]
+    *   [isWeird][11]
+        *   [Parameters][12]
+    *   [isBuffer][13]
+        *   [Parameters][14]
+    *   [isArrayOfBuffers][15]
+        *   [Parameters][16]
+        *   [Examples][17]
+    *   [MAGIC\\\\_NUMBER][18]
+    *   [event][19]
+*   [CustomError][20]
+    *   [Properties][21]
+*   [bar][22]
+*   [bar2][23]
+    *   [Parameters][24]
+*   [bar3][25]
+*   [Foo][26]
+    *   [bar][27]
+*   [Foobar][28]
+    *   [bar][29]
+*   [customStreams][30]
+    *   [passthrough][31]
+*   [tableObj][32]
+
+## Klass
+
+**Extends Stream.Writable**
+
+Creates a new Klass
+
+### Parameters
+
+*   \`foo\` &#x20;
+
+### getFoo
+
+Get this Klass's foo
+
+#### Examples
+
+this shows you how to getFoo
+
+\`\`\`javascript
+var x = foo.getFoo();
+\`\`\`
+
+Returns **[Number][33]** foo
+
+### withOptions
+
+A function with an options parameter
+
+#### Parameters
+
+*   \`options\` **[Object][34]**&#x20;
+
+    *   \`options.foo\` **[string][35]**&#x20;
+    *   \`options.bar\` **[number][33]**&#x20;
+*   \`otherOptions\` **[number][33]?**&#x20;
+
+### withDeepOptions
+
+A function with a deep options parameter
+
+#### Parameters
+
+*   \`options\` **[Object][34]**&#x20;
+
+    *   \`options.foo\` **[string][35]**&#x20;
+    *   \`options.bar\` **[Object][34]**&#x20;
+
+        *   \`options.bar.buz\` **[string][35]**&#x20;
+
+### isClass
+
+Decide whether an object is a Klass instance
+This is a \\\\[klasssic][Klass][1]
+This is a \\\\[link to something that does not exist][DoesNot][36]
+
+#### Parameters
+
+*   \`other\` **[Object][34]**&#x20;
+*   \`also\` **any**&#x20;
+
+Returns **[boolean][37]** whether the other thing is a Klass
+
+### isWeird
+
+A function that triggers the case where the autolinker doesn't find
+the referenced class type
+
+#### Parameters
+
+*   \`other\` **Weird**&#x20;
+
+Returns **[boolean][37]** whether the other thing is a Klass
+
+### isBuffer
+
+This method takes a Buffer object that will be linked to nodejs.org
+
+#### Parameters
+
+*   \`buf\` **([Buffer][38] | [string][35])**&#x20;
+*   \`size\` **[number][33]** size&#x20;(optional, default \`0\`)
+
+Returns **[boolean][37]** whether the other thing is a Klass
+
+### isArrayOfBuffers
+
+This method takes an array of buffers and counts them
+
+#### Parameters
+
+*   \`buffers\` **[Array][39]<[Buffer][38]>** some buffers
+
+#### Examples
+
+\`\`\`javascript
+var k = new Klass();
+k.isArrayOfBuffers();
+\`\`\`
+
+Returns **[number][33]** how many
+
+### MAGIC\\\\_NUMBER
+
+A magic number that identifies this Klass.
+
+### event
+
+Klass event
+
+## CustomError
+
+a typedef with nested properties
+
+### Properties
+
+*   \`error\` **[object][34]** An error
+
+    *   \`error.code\` **[string][35]** The error's code
+    *   \`error.description\` **[string][35]** The error's description
+
+## bar
+
+Get an instance of [Klass][1]. Will make
+a [klass instance multiword][1],
+like a [klass][1]
+
+Returns **[Klass][1]** that class
+
+## bar2
+
+Rest property function
+
+### Parameters
+
+*   \`toys\` **...[Number][33]**&#x20;
+
+Returns **[undefined][40]** nothing
+
+## bar3
+
+Get an instance of [Klass][1]. Will make
+a [klass instance multiword][1],
+like a [klass][1]. This needs a [number][33] input.
+
+Returns **[undefined][40]** nothing
+
+## Foo
+
+This is Foo
+
+### bar
+
+This is bar
+
+## Foobar
+
+This is Foobar
+must have a distinct id from Foo.bar
+
+### bar
+
+This is bar
+
+## customStreams
+
+I am the container of stream types
+
+### passthrough
+
+I am a passthrough stream that belongs to customStreams
+
+## tableObj
+
+| Col 1 | Col 2 | Col 3 |
+| ----- | ----- | ----- |
+| Dat 1 | Dat 2 | Dat 3 |
+| Dat 4 | Dat 5 | Dat 6 |
+
+[1]: #klass
+
+[2]: #parameters
+
+[3]: #getfoo
+
+[4]: #examples
+
+[5]: #withoptions
+
+[6]: #parameters-1
+
+[7]: #withdeepoptions
+
+[8]: #parameters-2
+
+[9]: #isclass
+
+[10]: #parameters-3
+
+[11]: #isweird
+
+[12]: #parameters-4
+
+[13]: #isbuffer
+
+[14]: #parameters-5
+
+[15]: #isarrayofbuffers
+
+[16]: #parameters-6
+
+[17]: #examples-1
+
+[18]: #magic_number
+
+[19]: #event
+
+[20]: #customerror
+
+[21]: #properties
+
+[22]: #bar
+
+[23]: #bar2
+
+[24]: #parameters-7
+
+[25]: #bar3
+
+[26]: #foo
+
+[27]: #bar-1
+
+[28]: #foobar
+
+[29]: #bar-2
+
+[30]: #customstreams
+
+[31]: #passthrough
+
+[32]: #tableobj
+
+[33]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
+
+[34]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
+
+[35]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
+
+[36]: DoesNot
+
+[37]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
+
+[38]: https://nodejs.org/api/buffer.html
+
+[39]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
+
+[40]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined
+"
+`;
+
 exports[`lint command generates lint output 1`] = `""`;
 
 exports[`should use browser resolve 1`] = `
diff --git a/__tests__/bin.js b/__tests__/bin.js
index 7f46bca1e..088d8755e 100644
--- a/__tests__/bin.js
+++ b/__tests__/bin.js
@@ -368,6 +368,21 @@ test.skip('fatal error', async function () {
   }
 });
 
+test('build GFM (e.g. markdown tables) for -f md', async function () {
+  const data = await documentation(
+    ['build', 'fixture/html/nested.input.js', '--shallow', '-f', 'md'],
+    {},
+    false
+  );
+  expect(data).toMatchSnapshot();
+  expect(data).toMatch(
+    `| Col 1 | Col 2 | Col 3 |
+| ----- | ----- | ----- |
+| Dat 1 | Dat 2 | Dat 3 |
+| Dat 4 | Dat 5 | Dat 6 |`
+  );
+});
+
 test.skip('build --document-exported', async function () {
   const data = await documentation(
     ['build fixture/document-exported.input.js --document-exported -f md'],
diff --git a/src/output/markdown.js b/src/output/markdown.js
index 1f774d9d9..b7a76566c 100644
--- a/src/output/markdown.js
+++ b/src/output/markdown.js
@@ -1,4 +1,5 @@
 import { remark } from 'remark';
+import remarkGfm from 'remark-gfm';
 import markdownAST from './markdown_ast.js';
 
 /**
@@ -25,5 +26,7 @@ export default function markdown(comments, args) {
   if (!args) {
     args = {};
   }
-  return markdownAST(comments, args).then(ast => remark().stringify(ast));
+  return markdownAST(comments, args).then(ast =>
+    remark().use(remarkGfm).stringify(ast)
+  );
 }