Zim: a desktop wiki that keeps your notes in plain text files you can still read in ten years
Main repository of the zim desktop wiki project
At a glance
- What is it?
- A graphical outliner for notes and journals that writes wiki markup to a folder instead of a database, with the packaging quirks, XDG path traps and version mismatch that come with a two-decade Python and GTK project.
- Who is it for?
- Zim earns its place for anyone who wants a personal knowledge base that a text editor, a shell script or a future migration can still read after the application is gone. Nothing about the format is exotic, which is the point: pages are files, attachments sit beside them, and links to pages that do not exist yet are the mechanism for creating new ones.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A wiki defined by linking to pages that do not exist yet
The README opens by describing the tool rather than the philosophy: Zim is a graphical text editor used to maintain a collection of wiki pages, where each page can contain links to other pages, simple formatting and images. Pages live in a folder structure, the way an outliner arranges things, and they can carry attachments. Creating a new page is as easy as linking to a nonexistent page, which is a design decision with consequences worth pausing on.
That one sentence is the difference between a wiki and a note application with a page list. In Zim there is no create button in the sense of a form to fill in. You type a link, you follow it or export it, and the page materializes as a file in the directory. A missing page is not an error state, it is the normal entry point. That makes capture cheap and makes the resulting folder readable by anything that can read text.
The listed uses follow directly from that model. The README names keeping an archive of notes, keeping a daily or weekly journal, taking notes during meetings or lectures, organizing task lists, drafting blog entries and emails, and brainstorming. The journal and meeting-note cases are the ones that get underused, because a day-based page tree with links between days is exactly the shape a personal archive wants, and every entry is a file you can grep.
Why the files on disk matter more than the editor
All data is stored in plain text files with wiki formatting, and that single line determines what the project is and is not. It is not a database with an export button. It is a directory of documents with an editor attached, which means your notes outlive the application, the version and the platform.
Plugins extend the editor without extending the storage model. The README names four examples: a task list manager, an equation editor, a tray icon and support for version control. Each of those is a feature of the reading experience rather than of the file format. A checkbox is markup inside a page, and the task plugin is what turns that markup into something clickable. A version control plugin does not add history to the files, it points a version control system at the folder that already contains them.
That split is why the repository tree looks the way it does. Alongside the zim.py entry point and the zim package directory there are translations, a debian directory, a windows directory, an xdg directory, data, icons, contrib, tools, website, tests, plus a Makefile, a setup.py and a test.py. The xdg and debian directories are packaging work that only matters if you are installing rather than just reading, and PLUGIN_WRITING.md sitting next to CONTRIBUTING.md tells you the extension surface is meant to be used from outside.
Installing from source when there is already a package for your distribution
The README is direct about the order of preference. Most Linux distributions include zim in their package repository, and on Debian and Ubuntu the package is simply called zim. A Windows installer and a macOS app are collected on the project website at zim-wiki.org/downloads.html. Source installation is presented as an option rather than the recommended path.
Still, the source path is documented in enough detail to be useful, and it starts by telling you not to install at all. You can run the editor straight from the source directory by calling ./zim.py, and the note adds that a translated build from source needs ./setup.py build_trans. The dependency check is ./setup.py --requires, and the stated minimum list is Gtk+ 3.18 or newer, python3 3.10 or newer, python3-gi with the gi based version rather than the older binding, python3-xdg, xdg-utils and python3-pillow. The last three are marked optional, two as recommended and one for wider image format support such as .webp.
Installation itself is one command:
./setup.py installThe Windows route is the unusual one, because there is no native package. The README tells you to install 64-bit MSYS2, open the MSYS2 MSYS terminal from the Start Menu, and install GTK3, Python3 and the Python bindings for GTK:
pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-python mingw-w64-x86_64-python-gobjectFrom that shell you run the editor with /mingw64/bin/python3 zim.py, or from any Windows terminal with C:\msys64\mingw64\bin\python3.exe zim.py. The README also flags a sharp edge: the msys environment ships both a 32 and a 64 bit shell, and packages installed for 64 bit GTK only run from the 64 bit shell.
XDG paths are the part that breaks virtualenv installs
If you install Zim from source inside a Python virtual environment, you have to tell it where to find its data files, and the README gives the exact export:
export XDG_DATA_DIRS=<where-your-virtual-environment-root-folder-is>/share:$XDG_DATA_DIRSThis is the failure mode that catches people who already know their way around Python packaging. Zim resolves data and configuration through the XDG base directory specification rather than relative to the installed package, so a virtualenv that relocates the interpreter can leave the application unable to find its own icons, templates and bundled data. The README calls out the symptom explicitly: if you get an error that zim cannot find its data files, for example because you installed the data files to /home/user/share/zim, you set the data path like XDG_DATA_DIRS=/home/user/share:/usr/local/share:/usr/share.
There is a second environment variable for the case where the Python modules themselves ended up somewhere unusual. If the modules are installed below a path such as /home/user/lib/zim, then PYTHONPATH=/home/user/lib is the setting that makes them importable.
Two variables, two different failure modes, and neither is discoverable from a traceback without knowing which one to blame. Plan for it during install rather than after the first failed launch.
Where the documentation and the packaging metadata disagree
The README states python3 3.10 or newer as a dependency, and the version guard in setup.py enforces something older and looser:
REQUIRED_MINIMUM_PYTHON_VERSION = (3, 6)
USED_PYTHON_VERSION = sys.version_info
if USED_PYTHON_VERSION < REQUIRED_MINIMUM_PYTHON_VERSION:
error_message = 'zim needs python >= {major}.{minor}'.format(
major=REQUIRED_MINIMUM_PYTHON_VERSION[0],
minor=REQUIRED_MINIMUM_PYTHON_VERSION[1],
)
sys.stderr.write(error_message)
sys.exit(1)The check exists and it runs before anything else in the file, which is sensible. The value is (3, 6), a floor that predates the documented requirement by four minor releases. So the packaging script will happily proceed on an interpreter the documentation says is unsupported, and the failure arrives later and further from its cause. Treat the README number as the real requirement and the setup.py constant as a minimum sanity check.
The Makefile is a second place where the project's own tooling shows through. Its targets map directly onto setup.py invocations, with all, help, source, test, install, buildrpm, builddeb, epydoc and clean. The builddeb target is pure Debian, running dpkg-buildpackage with fakeroot and then the rules file under debian. The clean target is thorough to the point of being a reference for what a build leaves behind, removing build output, locale, man, xdg hicolor directories, test_report.html, coverage and html directories, stray byte files, editor backups and the debian helper stamps. Reading it tells you what the project considers disposable.
Testing, contribution and where the licensing is unusual
The project ships its own test entry point. To verify that Zim works properly on your system, the README says to run ./test.py, and it adds a useful calibration: failures do not have to be critical, but in principle all tests should pass. The Makefile test target runs the same script, so both routes reach the same suite.
Contribution is documented in two files rather than in the README body. CONTRIBUTING.md covers work on the source code, translations and documentation, and PLUGIN_WRITING.md covers extension development. The repository root also holds CHANGELOG.md, which matters because the project publishes no GitHub releases. Version history lives in that file and in the version string imported from the zim package.
Licensing is more nuanced than a single license identifier, and the README spells out the exceptions. Zim as a program is open source and distributed under the conditions in the LICENSE file, which GitHub identifies as GPL-2.0. Files are copyright Jaap Karssenberg except for a named list. Translations are copyright their respective translators and, when entered through launchpad or weblate, are distributed under the BSD license with detailed credits in the translation files. Then there are borrowed files: zim/inc/xdot.py credited to Jose Fonseca in 2008, zim/inc/arithmetic.py credited to Patricio Paez for 2010 and 2011, and several pixmaps taken from the default Gnome icon theme and from Gtk+ 2.8, one of them a calendar icon from Jakub Steiner released under GPL with modifications by Gabriel Hurley in 2009.
That inventory is longer than most projects bother with, and it is the more useful signal. A single-license GPL program and a GPL program carrying files from four other sources are different compliance situations. If you redistribute Zim or bundle it into something larger, the per-file list is the part that costs you time.
Editorial conclusion
Zim earns its place for anyone who wants a personal knowledge base that a text editor, a shell script or a future migration can still read after the application is gone. Nothing about the format is exotic, which is the point: pages are files, attachments sit beside them, and links to pages that do not exist yet are the mechanism for creating new ones. What you give up by choosing it is a rendering engine you do not control, a GTK dependency on Linux, and a project whose stated Python floor and enforced Python floor disagree. If you already keep notes in a git repository or a synced folder, Zim slots into that habit rather than replacing it. Check the CONTRIBUTING file for what the maintainers actually want help with, read PLUGIN_WRITING.md before writing your own extension, and treat the XDG environment variables as part of the install rather than an afterthought. The last push to the develop branch was on 2026-09-01, and the project publishes no tagged releases, so the CHANGELOG file in the repository is the version history.
Frequently asked questions
Is Zim wiki open source?
Yes. The README states that Zim is an open-source program that can be used and distributed freely under the conditions in the LICENSE file, and GitHub identifies the license as GPL-2.0. Copyright is held by Jaap Karssenberg except for a named list of files borrowed from other sources, and translations entered through launchpad or weblate are distributed under the BSD license instead.
What is the Zim format?
There is no single Zim file format, because Zim is a directory of files rather than a document. Each wiki page is stored as a plain text file with wiki formatting, pages are arranged in a folder structure like an outliner, and attachments sit alongside them. The README also notes that a ZIM file is a separate concept used by offline readers, which is not what this project produces. Link to a page that does not exist and Zim creates it as a new text file when you follow the link.
Can I run Zim without installing it?
Yes. The README says you do not need to install Zim in order to test it and that you should be able to run it directly from the source directory by calling ./zim.py. Check the dependencies first with ./setup.py --requires, and run ./test.py to confirm the installation is sound. A translated build from source needs ./setup.py build_trans, and an installed copy inside a virtual environment needs XDG_DATA_DIRS pointing at the environment share directory.
What plugins does Zim ship with?
The README names four examples: a task list manager, an equation editor, a tray icon and support for version control. Plugins add functionality to the editor rather than to the on-disk format, so a checkbox stays wiki markup inside a plain text page. Most plugins have their own requirements, which are listed in the individual plugin descriptions, and PLUGIN_WRITING.md in the repository root is the reference for writing one.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zim-desktop-wiki-zim-desktop-wiki)