Inline Docs

Embed markdown documentation in code.

Build Status

Ideally, documentation and code are written in parallel. Good code is self-explanitory as far as the "what" is concerned. Documentation is a way to record the "why". Linking related parts together helps other developers understand how the system meets business needs and fits together as a whole.


npm install -g inline-docs

Running from CLI

Run inline-docs > docs.html in your project's root directory. Creates docs like

See Command line interface for more options.

Running from javascript

See Module entry point for API details.

Getting started

Writing docs

  • all documentation is written in markdown format. You can do this either in a .md file, or embed a markdown document within the comments of a source code file.

  • markdown documents will only be used if they pass some basic validation rules. See Validating markdown documents for details.


  • every level-1 and level-2 heading becomes a link anchor.
  • to link to a level-1 heading use the heading text in brackets like [[Heading text goes here]]. This will be converted to an html hyperlink when the final docs are generated.
  • linking to level-2 headings works the same, except with two parts [[Heading text goes here][And subheading here]]

Refining sources

  • You may come across cases where you want to exclude certain files from being parsed by inline-docs (eg. to avoid junk in your docs).
  • To exclude a single file, add the /* inline-docs:ignore */ directive to the top of the file.
  • To exclude a set of files, override the patterns defined at Module entry point: Default options.



Project goals

There are many existing tools to help you generate documentation from code, but most of them are geared towards describing APIs. Put more generally, the tools and documentation are focussed on what the code is doing and how to properly call each function. This is useful, but a lot of the time we need to document why things were done in a certain way. Every design-decision and tradeoff made today impacts the possible decisions that can be made tomorrow, and this information is critical to new developers becoming involved in the project.

Along with this, inline-docs has the following goals:

  • There should be a simple standard to follow when documenting code.
  • Considering that one part of the codebase often only makes sense in the context of the whole, there should be a natural way to make connections across a codebase. Reading the docs should be like having a guided tour of the code.
  • The tool should encourage documenting as a primary development task.

Template specs

  • any valid html document is fine.
  • the placeholder {{ content }} must be included somewhere. This will be replaced by the generated docs.

Validating markdown documents

  • To be considered valid, a source file must have exactly one level-1 heading in the markdown portion.
  • Any comments before the level-1 heading are ignored.
  • Single-line comments are only included if they begin with a //> (eg. //> comment goes here...)

Default options

By default we locate all .js files in the project directory, except for those in the node_modules directory.

prepend a directive so that the generated file is not included the next time we run inline-docs

Command line interface



inline-docs -o $OUTPUT_FILE --template=$TEMPLATE $PROJECT_DIR

Exclude pre-heading markdown tokens

Every doc is expected to begin with a level-1 heading, so anything before this is ignored.

It's common to see metadata comments near the top of a file which we wouldn't want to include. Also, expecting a level-1 markdown heading gives the developer a natural way to opt-in so we're not creating nonsense-documentatation for files that weren't intended to use comments in this way.

Extract C-Style Comments

Most source files will use one or both forms of c-style comments (block or single-line), so we can use a generic approach to extracting comments.

Rewrite doclinks in-place.


  • text: string
  • replaceFunc: function, will be called with the link parts, and the return value will be used in place of the doclink. Eg. replaceFunc(['Section', 'Subsection'])

Output: string

Zeroing comment indentation

Often a comment will be indented, so we need to make sure that doesn't affect the markdown interpretation.

We'll assume that the leading whitespace on the first non-empty line represents the indentation applied to all lines. We can subtract this from all lines to zero the indentation.

Creating heading anchors

Each level-1 and level-2 heading can be linked to. We create a unique anchor ID by converting the heading text into a suitable format.

Parsing directives

Directives allow you to instruct the doc parser how to handle the current file.


  • Any single-line comment may contain a directive, in the form of inline-docs:<key> [value].
  • A key may only contain letters and dashes.
  • The value is optional, and if omitted we'll assume key is a flag and set the value to true.

Process a file

To process source files we extract comments and parse as markdown.

To process markdown files we treat them as one big comment, so that the data format is consistent.

Rendering the document as HTML

After extracting comments we need to put it all together. The end result will be:

  • a single HTML element containing all content rendered from markdown.
  • each level-1 heading is rendered as a section.
  • each comment is rendered with an extra element that gives a reference back to the source file it came from.
  • before converting markdown to html we also replace special "Doc Links" with the markdown equivalent.

Html template

This template is used when rendering docs to html, to wrap the markdown inside an html document.

Default styles

All of the default styles are embedded in the template, to avoid extra http requests and make distribution easier.