Automatic folgezettel backlink generation for Obsidian notes with bidirectional cross-linking.
This plugin is a TypeScript translation of the
folgezettel-org-roam.el Emacs package by Blaine Mooers.
Electronic zettelkastens rely on reciprocal hyperlinks to relate parent and child notes. The manual insertion of these links is error-prone and time-consuming. This package provides true automation for creating these links by leveraging the parent-child relationship defined in the indexing system. You do not need to click a button to add the links; they are added automatically.
Most electronic zettelkastens rely either on timestamps or a database ID to identify each unique note. This approach is hopeless if one wants to print out their zettels to store them in a paper-based zettelkasten. Fans of the paper-based approach may object that you should write these notes by hand to better integrate the information into your memory. This may be true, but more frequent perusal of the paper zettelkasten may be compensatory and possibly more effective in the long term. Often, there is just not enough time available to rewrite the notes by hand.
There is no rule against mixing handwritten and printed notes together. The inclusion of the folgezettel index in the title tells the user where to store the note. Paper-based zettelkastens rely on the folgezettel index (also called the Luhmann-style index or the Scheper index) to specify the linear order of note storage. There is a one-to-one mapping between the zettelkasten graph and the order in which the notes are stored.
This approach supports a hybrid zettelkasten, with part electronic and part paper-based. Of course, it also supports a mirrored zettelkasten in both paper and electronic form.
You can print a note on US letter-size paper, fold it in half with the title on the outside, and store it in this zettelkasten. This folded paper corresponds to A5-sized paper. Luhmann used the smaller A6-sized paper.
If the note spans multiple pages, as may be the case with a structure note, keyword note, structure note, or hub note, you can fold the pages in half together. You can also save paper and space by printing on both sides, resulting in a booklet with two pages per side. For example, an eight-page note would span both sides of two sheets of US letter paper. The text will be rotated by 90°, so you will need to write the index across the top of the outside side of the folded paper. I favor this approach over index cards because it provides more space and because US Letter printer paper is cheaper and more readily available. This more practical approach reduces the friction of adding new notes to your paper-based zettelkasten.
Obsidian offers a fantastic, infinite canvas for displaying and organizing notes in all kinds of configurations. The ability to print out the notes opens up the opportunity to work with paper versions on a large tabletop or a corkboard. Sometimes changing the context from an electronic format to a physical format can stimulate the mind. This alternative physical approach to arranging notes is useful when using the notes in assembling a manuscript. You can use the canvas to combine all the notes you want to print. This could be useful for one-off tasks, such as assembling a manuscript, where you may discard the paper notes when you are done.
Notes receive structured addresses like 1.2a3c5 that encode the parent note-child note relationships:
| Address | Meaning |
|---|---|
1 |
Root note |
1.2 |
Second branch of note 1 |
1.2a |
First child of 1.2 |
1.2a3 |
Third sub-branch of 1.2a |
1.2a3aa |
27th subbranch of 1.2a3 |
1.2a3aa55 |
55th sub branch of 1.2a3aa |
Note how after the root note and the period, the numbers and letter alternate.
The numbers can contain multiple digits and there can be multiple letters after z has been used.
No further periods or other symbols are allowed.
- Automatic Parent Linking: When creating a note with a folgezettel address, automatically links to the parent note
- Bidirectional Links: Forward links are added to parent notes, backlinks to child notes
- Cross-Reference Links: Automatically creates reciprocal links when you manually link notes
- Child Suggestions: Suggests the next available child address
- Keyboard Shortcuts: All commands are available via hotkeys
- Links: Works with either WikiLinks or Markdown links.
If you have Emacs compiled with xwidgets and have installed the package grip-mode, you can edit your Obsidian notes inside of Emacs in one buffer and enjoy a live preview in the adjacent buffer.
Your notes will need the Markdown-style links (e.g. [description](URL) ) to be able to navigate from file to file.
- Enjoy editing the notes with the full power of your Emacs configuration with favorite key bindings, packages, home-made functions, and code snippets.
- Use whisper.el to carry out dictation of your notes.
- Access your bibliography with ebib.
Why not move to org-roam? Obsidian's infinite canvas for organizing notes has no full-fledged counterpart in Emacs.
- Open Settings → Community plugins
- Click Browse and search for "Bidirectional Folgezettel"
- Click Install, then Enable
- Download the latest release (
main.js,manifest.json,styles.css). - Create folder:
<vault>/.obsidian/plugins/bidirectional-folgezettel/. - Copy the files into that folder.
- Reload Obsidian.
- Enable the plugin in Settings → Community plugins.
git clone https://github.com/MooersLab/bidirectional-folgezettel
cd bidirectional-folgezettel
make install
make build
make install-plugin VAULT_PATH=/path/to/your/vault| Command | Description | Suggested keybinding |
|---|---|---|
| Add backlink to parent note | Creates bidirectional link with parent. | Option-P |
| Create next child note | Creates a new child note with suggested address. | Option-C |
| Suggest next child address | Shows the next available child address. | Option-A |
- Go to Settings → Hotkeys
- Search for "Folgezettel"
- Assign your preferred shortcuts
When enabled (default), the plugin automatically:
- On note creation: If the note title contains a folgezettel address, creates links to/from the parent note.
- On manual linking: When you create a
[[link]]to another note, a reciprocal link is added to the target note.
| Setting | Description | Default |
|---|---|---|
| Auto-process new notes. | Auto-link on note creation. | On |
| Show notifications. | Display link insertion notices. | On |
| Auto bidirectional cross-links. | Create reciprocal links. | On |
| Parent link description. | Text for parent links. | "Parent" |
| Child link description. | Text for child links. | "Child" |
| Backlink heading. | Section for parent links. | "Related Notes" |
| Forward link heading. | Section for child links. | "Child Notes" |
| Cross-link heading. | Section for cross-references. | "Related Notes" |
You can specify a template file that will be utilized upon the creation of a child note.
The specification is done through the community package called Templater.
This is not to be confused with the core package called template. They use two different template languages.
The core package template has associated with it as a icon that appears in the left panel. When you click on this icon you can select from a template folder in your vault whichever template you wish to use upon the creation of the next note. This core package does not retain memory of the last selection or does it allow you to set a default template.
The problem of setting a default template is solved by the community package Templater. It utilizes its own template language for creating templates. You'll have to turn off the core template package to use this package. See this blog post for the installation steps. The tricky part is step 9. The typical configuration would look like the one below. Under the settings for this package, you can set the default template.
Before you use any templates, you probably have to think about what kind of trouble you may be causing yourself downstream if you're going to export your notes to a different format for use in a different zettelkasten software. You might want to work out the workflow now. At a minimum, you should try running pandoc to convert to the file format required by the target software that you might migrate to. You might have to write your own script to strip out some of the code embedded in the note.
- Node.js 16+
- npm
# Clone the repository
git clone https://github.com/MooersLab/bidirectional-folgezettel
cd bidirectional-folgezettel
# Install dependencies
make install
# Run tests
make test
# Build
make buildmake install - Install npm dependencies.
make build - Build production version.
make dev - Run development mode with watch.
make test - Run test suite.
make test-watch - Run tests in watch mode.
make test-coverage - Run tests with coverage report.
make lint - Check code style.
make lint-fix - Fix code style issues.
make clean - Remove build artifacts.
make install-plugin - Install to Obsidian vault.
make pre-commit - Run all checks before commit.
bidirectional-folgezettel/
├── src/
│ └── main.ts # Plugin source code
├── tests/
│ ├── __mocks__/
│ │ └── obsidian.ts # Obsidian API mocks
│ └── folgezettel.test.ts
├── main.js # Compiled plugin
├── manifest.json # Plugin metadata
├── styles.css # Plugin styles
├── package.json # NPM configuration
├── tsconfig.json # TypeScript configuration
├── jest.config.js # Test configuration
├── esbuild.config.mjs # Build configuration
├── Makefile # Build automation
└── README.md # This file
- Fork the repository.
- Create a feature branch:
git checkout -b feature/name. - Make changes and test:
make pre-commit. - Commit:
git commit -m 'Add feature'. - Push:
git push origin feature/name. - Open a Pull Request.
| Version | Changes | Date |
|---|---|---|
| Version 0.1 | Extensive edits of the README.md. | 2026 January 15 |
| Version 0.2 | Fixed bug in child note index. | 2026 January 16 |
| Version 0.3 | Fixed bug in child note index when parent is a root node. | 2026 January 20 |
| Version 0.4 | Added notes to README.md on problems addressed by this package. | 2026 January 31 |
- NIH: R01 CA242845, R01 AI088011
- NIH: P30 CA225520 (PI: R. Mannel); P30GM145423 (PI: A. West)