Cosma Docs

Cosma is a document graph visualisation software. It allows you to represent interrelated notes as an interactive network in a web interface. Cosma is designed to work with Markdown text files and is suitable for both small collections (about a hundred documents) and sprawling knowledge bases (up to several thousand documents).

Cosma was created through the HyperOtlet research programme, funded by the National Agency of Research (ANR, France).

1 Introduction

Cosma is a document graph visualisation software. It allows you to represent interrelated notes as an interactive network in a web interface. Cosma is not a note-taking application: it was designed to work in conjunction with note-taking software, only requiring that notes be structured according to a specific format.

Most visualisation tools present themselves through a graphical user interface (GUI), from which it is possible to export structured data or static images. Cosma reverses this logic: the application part, which we call the cosmographer, is just a form; the export, an HTML file we call the cosmoscope, is the actual visualisation interface. This stand-alone file contains an interactive graph, internal navigation tools (index, search engine, filters) and the full text of the records; it also includes the source data as JSON and can be used offline.

Cosma is designed to give a high degree of control to its users.

Firstly, Cosma works with any directory of text-based files and only reads the data: using or uninstalling the software will not alter your files and therefore does not interfere with your storage, versioning and editing practices.

Second, almost all of Cosma’s interface elements are customisable: the network drawing algorithm, the colours, the stroke of links… You can even add permanent shortcuts to specific visual configurations (“views”) you may come across during navigation and want to access again later.

Thirdly, documentary and semantic enrichments are possible through the addition of metadata on both nodes (documents) and links (relationships between documents). This is done through generic mechanisms, allowing you to use the typologies and ontologies of your choice.

And fourthly, Cosma is modular, interoperable and portable, but above all free software. The code is public, documented, and it is accessible and reusable free of charge under the MIT license. Our work can thus be evaluated, archived and continued by others.

2 Installing

2.1 Pre-requisites

Install Node.js version 12 or higher.

Using the cosmoscope requires a web browser. You can use the following browsers, in the version mentioned or higher:

The cosmoscope is not compatible with Internet Explorer.

2.2 Downloading Cosma

Download the Cosma git repository by typing the command below in a terminal, or by clicking on the following link:

git clone

2.3 Installing the dependencies

Cosma relies on other programs called dependencies. Cosma uses the NPM dependency manager which is installed at the same time as Node.js. Install the dependencies necessary for the application to function properly with the command below:

npm install --only=production

3 Settings

Cosma uses a YAML configuration file. It is a hierarchical list of parameters whose values modify the behaviour of the software.

For an introduction to YAML, click here. For Cosma, it is particularly important to know that in YAML the hierarchy of parameters is implemented by indentation, i.e. the presence of spaces at the beginning of a line, and that the use of tabs to indent lines is forbidden in YAML. It is recommended to choose an indentation unit corresponding to a multiple of 2 spaces (2 or 4) and to stick to it for the whole file.

Run the following command to create the configuration file (config.yml) if it does not already exist. You can also delete the file and use this command to reset it. The file generated by this command is a template with all the parameters that must be filled in for the configuration to be considered valid.

node app config
node app c

3.1 Obligatory parameters

The configuration must contain the following parameters:

Path to the directory containing the Markdown files to be read.
Example: /Users/user/Fiches/', D:\repertoire\
Path to the directory where to export the cosmoscope.
Example: ./', D:\repertoire\

The files_origin and export_target paths must end in a slash.

List of record types. Each type is defined by a name: value pair where name is the name of the type and value is a colour of your choice. The colours are declared as in HTML with their predefined name or an RGB, HEX, HSL, RGBA or HSLA value in quotes.


  undefined: '#546de5'
  very important: red
  reading note: 'rgba(157, 62, 12, 0.7)'
  concept: 'hsl(14, 100%, 80%)'
List of relationship types. Each type is defined by a name parameter whose value is a list of two parameters, which affect the representation of the links in the graph: stroke corresponds to the shape of the line and color to its colour. The value of stroke can be single (single solid line), double (double solid line), dash or dotted. Colours are declared as in HTML, in the same way as for the record types.


    stroke: simple
    color: grey
    stroke: dash
    color: 'rgba(157, 62, 12, 0.7)'

The default type undefined must be set for both record types and link types.

The links settings affects their readability in the graph. In the following example, the user has defined three types of qualified links in the manner of a thesaurus (specific s, generic g and associated a). The parameters are set to enhance the visibility of the qualified links: the default (undefined) links are discrete dotted grey lines, while qualified links are more legible, with solid lines and a brighter colour.

    stroke: dotted
    color: grey
    stroke: simple
    color: 'rgba(157, 62, 12, 0.7)'
    stroke: simple
    color: 'rgba(157, 62, 12, 0.7)'
    stroke: dash
    color: 'rgba(157, 62, 12, 0.7)'

3.2 Graph settings

The following parameters define the default value of the graph parameters. Most of these parameters can be changed live in the cosmoscope interface, where you can test different values before setting them in the config.yml file: the values set there are restored each time the cosmoscope is reloaded.

  background_color: white
  highlight_color: red
  highlight_on_hover: true
  text_size: 9
    x: 0.5
    y: 0.5
    force: -50
    distance_max: 800
    verticale: 0
    verticale: 0
  arrows: false
Background color of the graph.
Example: whitesmoke ,#ccc, rgb(57, 57, 57)
Highlight color for selected items.
Example: red ,#0642ff, rgb(207, 52, 118)
Size of node labels. The implicit unit is pixels. The minimum value is 5; the maximum value is 15.
Horizontal (x) and vertical (y) position of the graph centre. The value must be between 0 (far left) and 1 (far right).
Parameters of the simulation of forces between nodes.
force: overall power. The lower it is, the looser the links between nodes are. Values below 50 tend to cause incessant collisions.
distance_max: maximum distance between nodes. Above 1000, this parameter has no measurable effect. The value of distance_max also indicates the maximum effective value of force. For example, if distance_max: 500, then increasing force beyond 500 will have no effect.
verticale: The force of attraction towards the vertical axis. A value of 0 means that this parameter is disabled.
horizontale: force of attraction towards the horizontal axis. A value of 0 means that this parameter is disabled.
Display arrows on links, depending on whether you want a directed or undirected graph. Boolean value: true or false.

3.3 Optional parameters

You can add the following parameters to the configuration file:

Path to the JSON CSL file containing the list of bibliographic references. Enables the bibliography of records.
Reduces the size of the cosmoscope.html file, at the expense of the readability of the source code. Value: true or false. Disabled by default.
Applies any styles declared by the user in the /template/custom.css file. Value: true or false. Disabled by default.
Exports a copy of the cosmoscope and its data to a time-stamped sub-folder of the history folder. Value: true or false. Enabled by default.
List of metadata to be used as meta tags in the header of thecosmoscope.html file. You may use any metadata. When using the --publish / -p flag on the modelize command, some metadata will also be displayed in the interface if they exist: the title replaces the logo at the top of the menu pane; title, author, date and description are displayed in the About pane.


  author: Firstname Lastname
    - Zettelkasten
    - document graph
  description: "This is my personal knowledge base."
Maximum focus distance. The value must be an integer greater than or equal to 0.
List of views appearing in the cosmoscope Views section. Each view is defined by a name: value pair, where name is the name of the view and value is a string generated via the Save current view button.


  A nice view: eyJmaWx0ZXJzIjpbImNvbmNlcHQiXX0%3D
  Another view (with focus): eyJyZWNvcmRJZCI6MjAyMTAyMjExNDQ0NTF9

3.4 Change the configuration from the command line

The following commands allow you to quickly change the configuration.

Generate a template configuration file:

node app config
node app c

Modify the path to the source files:

node app import <chemin>

Modify the cosmoscope export path:

node app export <chemin>

Add a record type:

node app atype <nom> <couleur>

Create a custom.css file in the /template directory:

node app css

Add a view:

node app aview <nom> <code>

4 Using the cosmographer

4.1 Data format

Cosma does not prescribe writing software, but requires a specific data format which combines several writing standards aiming to increase interoperability and data durability:

This combination of writing standards lies at the intersection of several textual cultures: documentation; wikis; note-taking with the Zettelkasten method; academic writing with Pandoc. Therefore, Cosma works particularly well when used in tandem with writing environments that share this approach, such as Zettlr or the Foam extension for Visual Studio Code and VSCodium.

To be correctly interpreted by Cosma, Markdown files must therefore respect a certain structure, and in particular the presence of a YAML header at the beginning of the file.


title: A clever title
id: 20201209111625
type: undefined
- some relevant keywords
- some more keywords

The YAML header is delimited by two sets of three single dashes on a line (---). Cosma recognises and uses the following four fields:

A unique identifier. Mandatory. By default, Cosma uses a timestamp (year, month, day, hours, minutes and seconds) to generate a 14-digit identifier, as some popular Zettelkasten note-taking software do – including The Archive and Zettlr.
A record type. Optional. Only one type can be assigned to one record. If the type field is not included or its value does not match one of the types stored in the configuration under the record_types parameter, Cosma will interpret the type of the record as undefined.
Any keyword(s) attached to the record. Optional. The value must be a list. A record can have as many keywords as you wish.

According to the YAML specification, the list of keywords can be entered in block mode:

- some relevant keywords
- some more keywords

Or in flow mode:

tags: [some relevant keywords, some more keywords]

You can add additional fields arbitrarily, for example a description field.

After the header, you can freely enter your content.

The rendering of Markdown files as HTML in the cosmoscope is limited to textual elements. Images, for example, are not included and will be replaced by their alternative text when it has been set.

4.2 Creating records with the cosmographer

You can create a Cosma-compliant Markdown file by hand or by using the cosmographer through the command line. There are two options. The first one requires several inputs in succession:

node app record
node app r

The second option is a one-liner, allowing you to create a record in one command:

node app autorecord <titre> <type> <mots-clés>
node app a <titre> <type> <mots-clés>

Only the title is mandatory.

Within a record, you can create a link to another record with the identifier of the target record in double brackets. The cosmographer recognises these links and uses them to model the structure of the graph.


A link to [[20201209111625]] another record.

You can also qualify the link according to the typology you have specified under link_types in the configuration. The link type is then added as a prefix to the identifier, with a colon as a separator.


Concept B derives from [[generic:20201209111625]] concept A.

4.4 Bibliography

You can integrate citation keys into your records. They can be recorded with the bibliographic reference software Zotero and then exported with a unique identifier into a JSON CSL file thanks to its extension Better BibTeX. This identifier can then be wrote in your records (in the style of Pandoc software), between square brackets as below.

According to [@ledeuffTempsHumanitesDigitales2014, 22; @perretFonctionDocumentairePreuve2020].

You must target into the configuration the JSON CSL file exported with Zotero.

library_origin: 'D:\documents\ma_bibliotheque.json'

The following commands are used to generate a cosmoscope using Cosma’s built-in Citeproc converter

node app modelize --citeproc
node app modelize -c

Each citation key is then replaced by a short reference and an entry in the bibliography.

According to (Le Deuff 2014, p. 22; Perret 2020).


LE DEUFF, Olivier, 2014. Le temps de humanités digitales. FYP. ISBN 978-2-36405-155-5.

PERRET, Arthur, 2020. Fonction documentaire de preuve et données numériques. [en ligne]. 9 septembre 2020. [Consulté le 14 septembre 2020]. Disponible à l’adresse :

You can change the citation style (default: ISO690-author-date-fr) by replacing the /template/citeproc/styles.csl file. Download a new style from the Zotero database.

You can change the translation of the keywords of the bibliographic record (default: French) by replacing the file /template/citeproc/locales.xml. Download a new translation from the CSL database.

4.5 Exporting

To create the cosmoscope.html file, use one of these commands:

node app modelize
node app m

You can also obtain a published version of the cosmoscope with the following command. It allows you to name, introduce and sign your export from the “About” menu (accessible from the button at the bottom of the left-hand menu). It integrates the title, author and description metadata entered in the configuration (option metas). If it is filled in, the title metadata also replaces the logo at the top of the left-hand menu.

node app modelize --publish
node app m -p

The cosmoscope.html file is exported to the directory defined by export_target in the configuration. If the file already exists in the same location, it is overwritten.

If the history parameter is set to true, a time-stamped subdirectory is also created in the /history directory with the following contents:

This export facilitates data sharing and reuse in other visualisation software.

5 Using the cosmoscope

The cosmoscope.html file can be opened with a web browser. It can also be shared online, e.g. by uploading on a server via FTP. You can link to a specific record within an online cosmoscope by adding its ID preceded by a # at the end of the URL. Example:


5.1 Interface overview

The interface is organised in three columns:

Left side panel (Menu)
Displays the main navigational features, including search, keywords, index and views, as well as controls for the force-based layout algorithm and other graphical parameters.
Central area (Graph)
Displays the graph and associated controls (zoom, focus).
Right side panel (Record)
Displays the records’ metadata and contents, as well as a list of outgoing and incoming links (the latter called backlinks).

Interface of Cosma (click on the image to extend it)

5.2 Graph

The central area of the interface displays the graph. Each node corresponds to a record; the label corresponds to the title of the record. The links correspond to the links established between the records via their identifiers in double brackets.

If highlight_on_hover is set to true, hovering over a node temporarily highlights it and its connections. Clicking on a node highlights it and its connections and opens the corresponding record.

You can zoom into the graph with a mouse or touchpad, by double-clicking on the graph background or with the dedicated buttons at the bottom left. The Refocus button (shortcut: R key) resets the zoom.

The nodes’ positions are set by a force-based layout algorithm. A coloured bar under the Cosma logo indicates the status of the simulation. Click on it (shortcut: Space key) to restart the simulation.

Press the Space key repeatedly to progressively “unfold” a tangled graph.

The nodes can be moved around slightly by clicking and dragging, but stay subjected to the simulation, so they will snap back to their position.

The controls at the bottom of the left side panel allow you to change the way the graph is displayed:

These changes will be overwritten each time the page is reloaded. To make them permanent, change the default values set under graph_config in the config.yml file.

Modify force and distance_max to adapt the display to your screen resolution and size. Modify verticale and horizontale to apply a centripetal force towards the corresponding axis, which in particular helps to bring isolated islands and nodes closer to the centre.

The cosmoscope can be displayed on all types of screens but is not optimised for mobile terminals: hovering does not work with touch-based interaction, and small screens limit the usefulness of the graph.

5.3 Records

Records can be opened by clicking on a node, an index entry, a search engine suggestion, or a link in the body of another record. Opening a record displays its contents in the right-hand side panel. This also updates the URL of the page with the record ID: this allows you to navigate between the records you have visited via the browser’s Previous / Next functions, but also you browser’s history, and to link directly to a record.

Clicking on the “Close” button closes the pane and deselects the corresponding node in the graph.

The links in the body of the records are clickable. You can open these links in a new tab by right-clicking them. The title of the link (displayed in a tooltip after 1-2 seconds of hovering) is that of the corresponding record.

At the bottom of the record is a list of the records to which it refers (outgoing links), as well as the records that points to it (incoming links or backlinks). Links and backlinks are contextualised: when hovering over them, a tooltip is displayed showing the paragraph in which the link is located in the corresponding record.

5.4 Focus mode

The Focus button (shortcut: F key) at the bottom left of the graph allows you to restrict the display to the selected record and its direct connections. Focus mode only works if you have selected a record.

The slider under the Focus button allows you to increase and decrease the focus’ range, i.e. the distance up to which connections are displayed. The maximum range is defined by the value of the focus_max parameter in the configuration.

The focus range slider can be controlled with the arrow keys. You can chain shortcuts: F to activate the focus, then the arrows to vary the focus range.

5.5 Searching

The text field at the top of the left side panel is a search engine. It suggests a list of records whose title is close to your input, using fuzzy search. Clicking on a suggestion selects the corresponding node in the graph and opens the corresponding record in the right side panel.

The available suggestions are constrained by the record type filters and the focus mode: a record hidden by any of these features will not be accessible via the search engine.

5.6 Filtering by record type

The list of record types at the top of the left-hand side panel allows you to filter the display. Clicking on a type will hide all corresponding records from the graph, index and search engine suggestions. Clicking on a type while holding down the Alt key hides all records of the other types.

For a record type to appear, it must be declared under record_types in the configuration and be assigned to at least one record.

5.7 Tags

The list of tags in the left-hand side panel allows you to highlight the records that use each tag. Selecting a tag highlights the label of the corresponding nodes in the graph and restricts the index to the corresponding records. You can activate several keywords simultaneously. To deactivate a keyword, click the corresponding button again.

For a tag to appear, it must have been added in at least one record via the tags field.

5.8 Index

The alphabetical index of records in the left side panel allows you to access records without going through the graph. Clicking on a title selects the corresponding node in the graph and opens the corresponding record. The index can be sorted in ascending or descending alphabetical order. Filters, keywords and focus mode modify the display of the index.


At any time, the current state of the graph (selected record, active filters, focus mode) can be saved for quick access. Think of browser bookmarks, but for visual configurations. Clicking on the Save View button copies a code to your clipboard. This code must then be added with a name under the views parameter in the configuration:

  An interesting view: eyJwb3MiOnsieCI6MCwieSI6MCwiem9vbSI6MX19

This adds an button with that name to the Views section in the left side panel. Clicking the button applies all settings that were active when the view was saved. Clicking the button again restores the normal view.

5.10 Customizing the interface

The interface is built from a Nunjucks (.njk) template file and CSS stylesheets stored in the /template subdirectory.

The interface can be customised by adding a custom.css file in the /template folder. You can create the file manually or run the following command:

node app css

The custom_css parameter in the configuration allows you to enable or disable the use of this file without having to delete it.

The CSS declarations in custom.css replace those in /template/styles.css and /template/print.css (for print styles) and apply to the /template/template.njk file. Check these files directly or with your web browser’s inspector to find out which selectors to use for which declarations. For example, the cosmoscope stylesheets use CSS variables to define the colours and fonts used. You can redefine only these variables to quickly change all the interface elements to which they apply.

In the example below, the custom.css file contains statements that modify the fonts used in the cosmoscope:

:root {
  --sans: "IBM Plex Serif", sans-serif;
  --serif: "IBM Plex Serif", serif;
  --mono: "IBM Plex Mono", monospace;
  --condensed: 'IBM Plex Sans Condensed', sans-serif;

6 Development

This part of the documentation is aimed at experienced JavaScript developers. It presents the tree structure and the concepts on which the two parts forming Cosma, the cosmographer and the cosmoscope, are based.

We strongly recommend that you read the rest of the documentation in order to fully understand the uses of the source code presented below.

6.1 Terminology

The Markdown files interpreted by Cosma are referred to here as “cards” or “records” rather than “notes”, in reference to the tradition of the index card in scholarly practice and documentation. In French, we use the word “fiche”, which has no direct translation into English (although “index card” is often used). However, it is conceptually very close to the word “record” from records management. Cosma’s source code therefore uses the word record to designate a card.

6.2 Code architecture overview

Cosma is mainly implemented in JavaScript. The software is based on two distinct systems, the cosmographer and the cosmoscope.

The cosmographer is based on the Node.js environment. A series of scripts are used to :

The cosmoscope is an HTML file run on web browsers, created from a Nunjucks template (template.njk). It incorporates :

6.3 File tree

Below you will find a complete description of the software’s tree structure, allowing you to distinguish between cosmographer-related files and cosmoscope-related files.

├── docs/                   | documentation directory
│   ├── api/                | API index directory
│   │   └── [x].md          | introduction to API index of [x]
│   └── api-config-[x].json | config. of the API index of [x]
├── functions/              | cosmographer functions
│   ├── autorecord.js       | command-line one-liner for creating Markdown files
│   ├── history.js          | creation of export history directories
│   ├── links.js            | analysis of wiki-style links and their attributes
│   ├── log.js              | display alerts and create logs
│   ├── modelize.js         | Markdown file analysis and data model creation
│   ├── record.js           | command-line form for creating Markdown files
│   ├── template.js         | integration of data, style and body of cosmoscope
│   └── verifconfig.js      | configuration validation and modification
├── template/               | 
│   ├── libs/               | JavaScript libraries
│   ├── scripts/            | cosmoscope functions
│   │   ├── counter.js      | activate entity counters
│   │   ├── filter.js       | apply filters
│   │   ├── focus.js        | apply focus
│   │   ├── graph.js        | graph generation according to data and configuration
│   │   ├── history.js      | history of navigation between sheets
│   │   ├── index.js        | control of the left menu panes and buttons
│   │   ├── keyboard.js     | assignment of keyboard shortcuts
│   │   ├── main.js         | global variables and logo animation
│   │   ├── nodes.js        | display of nodes
│   │   ├── record.js       | opening/closing the right side panel
│   │   ├── search.js       | search engine settings
│   │   ├── tag.js          | apply tags
│   │   ├── view.js         | save and apply a view
│   │   └── zoom.js         | set the movement (lateral, zoom) within the graph
│   ├── cosmalogo.svg       | software logo
│   ├── template.njk        | cosmoscope structure
│   ├── print.css           | cosmoscope printing styles
│   └── styles.css          | cosmoscope styles
├── app.js                  | addressing of the terminal commands
└── package.json            | list of Node.js dependencies

6.4 API index

Click on the links below to view the list of functions used by the cosmograph and cosmoscope:

6.5 How the cosmograph works

There are three possible uses of the cosmographer via the command line. These different requests are received by app.js which returns them:

The configuration (the contents of the config.yml file turned into a JavaScript object) is exported globally (from verifconfig.js). It can be called as demonstrated below:

const config = require('./verifconfig').config;

const folderToExport = config.export_target;

6.6 Reading files

From the modelize.js file, we extract from each Markdown file the metadata (the YAML header) and the content (following the YAML header) (modelize.js file).

The content is first read by a series of regular expressions to extract the paragraphs, and for each paragraph the wikilinks contained. The paragraph becomes the context of its links and is translated into HTML.
The contents of the file are then transformed to turn the wikilinks into Markdown links
The content of the file is fully translated from Markdown to HTML.

The first and third functions use the markdown-it library. It can be replaced.

6.7 Generating the cosmoscope

The cosmoscope is generated using the function cosmoscope().

This instantiates the Nunjucks template /template/template.njk and injects the configuration data, records, graph entities and styles (serialized by the colors() function).

Nunjucks also imports CSS stylesheets and JavaScript libraries in the head, as well as JavaScript functions in script tags at the end of the document. The record and configuration data are integrated via loops and other Nunjucks control structures.

The whole thing is saved in a cosmoscope.html file and then exported.

6.8 Displaying the graph

Generating and animating the graph relies on the [D3.js] library ( It receives its data from the global object graph. This object is composed of two arrays.

This array contains all the data relating to the nodes, including a series of booleans to indicate their display status (see the serialization by the registerNodes() function). This indicated state is updated each time the display changes.
This array contains all data relating to links (see serialization by the registerLinks() function).

6.9 Displaying the graph with other libraries

The arrays presented in the previous section can be injected into other graph generation JavaScript libraries.

Example 1: Vis.js Network (repository, code sample).

In /functions/modelize.js:

function registerLinks(file) {
// ...
  for (const link of file.links) {
  // ...
      // ...
      from: Number(,
      to: Number(,
      // ...

In /template/scripts/graph.js:

const network = new vis.Network(
  , data = {
    nodes: new vis.DataSet(graph.nodes),
    edges: new vis.DataSet(graph.links)
  , {  } // options

Example 2: Sigma.js (repository, code sample).

const network = new sigma({
  graph: {
    nodes: graph.nodes,
    edges: graph.links
  container: 'network'

6.10 Graph parameters

The graph parameters are extracted from the graph_config part of the config.yml configuration file. It is injected into the Nunjucks /template/template.njk template via the cosmoscope() function. In the template, it is both used as the default value for forms in the “Graph settings” menu and implemented as a global JavaScript object graphProperties.

This same global object is updated by the various forms in the “Graph settings” menu. The forms then call the updateForces() function to restart the evaluation of these parameters by D3.js.

6.11 Keyboard shortcuts

Keyboard shortcuts for the cosmoscope are implemented in the /template/scripts/keyboard.js file. The global pressedKeys object contains the list of keys that are monitored for behavioural changes. Other keys (letters) are listed to call certain functions and are not added to the global pressedKeys object.

The global boolean keyboardShortcutsAreWorking defines whether shortcuts can be used or not. When entering text in a field, the letters must not be used for anything other than writing.

7 Credits

7.1 Team

7.2 Dependencies

To improve the maintainability and readability of the source code, the development team used the following libraries:

7.3 Project history

August 2020
The “Lexicographer”, a prototype based on the Otletosphere.
Décembre 2020
Cosma has a name, a logo and specifications for development.
Avril 2021
Cosma v1.0 is released on GitHub and archived on Zenodo.