Wiki for Pet Projects
[main page]
Wiki For Pet Projects in Clojure and Polylith
16 august, 2026 / color theme: ef-spring
Wiki For Pet Projects
People maintain their wiki/Zettelkasten in Obsidian or in org-mode files.<br>It helps to prepare for interviews, to find needed CLI commands, to store credentials to their personal servers and for lots of other stuff.
Yet it's not common to store code in such wiki projects.<br>I have lots of unfinished pet projects and little scripts, and I'm trying new libraries all the time.<br>It'd be cool to keep final results in this wiki and build new stuff upon that, even if the project itself won't be released.
My idea is: make a monorepo with all the code, grow the monorepo, and grow new projects from it.
in Clojure and Polylith
These days, all the code I write is in Clojure and ClojureScript.<br>REPL feels natural: it's like using surgeon's scissors instead of a sword for experimenting with the code, and a dynamic language helps to write scripts that target CLI.
As for the monorepo structure, I only know one architecture called Polylith.<br>It allows you to extract modules into components and reuse them in the new projects.
Polylith is an architecture, and it can be applied in any language.
If you don't want to use Clojure, then most probably you don't know it any other language will do, good candidates are Python and JS, and in general several languages could be used together.
Below is an example of Polylith architecture in my monorepo.
Polylith Structure
The root of Polylith repositories looks like this:
$ tree -L 1<br>├── components<br>├── bases<br>├── projects<br>├── development<br>├── build.clj<br>├── deps.edn<br>├── Makefile<br>├── package.json<br>├── readme.md<br>└── workspace.edn
It consists of 4 directories:
components are the reusable modules, for example:
authn/authz
log module for Clojure
log module for Python
interface for Postgres
interface for third-party services
domain entities: if there is a user entity and several projects depend on it, then we could extract it from the projects and move here.
The bases directory has base blocks for the projects. Every base glues together several components and defines the public API for them.
the base block itself consists only of the interface and leaves all the implementation to the components.
projects disectory usually consists of service files that help to build the project from several components and one base block.
development directory serves as a scratch or fiddle space for experimenting with the current components and bases.
Also, the root contains service files such as deps.edn for Clojure dependencies.
Makefile and build.clj help to build and test the projects,<br>and package.json is needed by ClojureScript.
workspace.edn stores metadata for the Polylith CLI command.<br>Polylith has a CLI tool, but it's entirely optional.<br>In the monorepo I use it to create new components.
How to migrate existing projects
Polylith allows you to migrate existing projects into the monorepo incrementally.
First, you need to create a base block, clone everything you have, and fix the build.
That's called a "fat base", since it's not split into components yet.<br>Then you can split the block further into the components.<br>To me, I've only recently finished the migration, and I haven't extracted lots of components yet:
$ tree -L 1 ./components<br>./components<br>└── postman
postman stores a counterpart for curl/Postman tools for invoking REST services via the REPL.
The bases directory looks like this:
$ tree -L 1 ./bases<br>./bases<br>├── clj_scraper<br>├── clj_tasks<br>├── doodle_editor<br>├── fe_experiments<br>└── truth_or_dare_clj
Here, fe_experiments contains this site written in ClojureScript, that was a way for me to learn DOM and how to control it (DOM API is surprisingly imperative and strange to use for declarative HTML pages).<br>If I need it again, I could either extract a component or grep usage examples.
clj_tasks is a monorepo from the pre-Polylith era: Advent of Code, LeetCode and Clojure Camp problems, Jupyter Notebooks for Deno TS runtime,<br>and a presentation about gorillas written in Clojure's Jupyter Notebook counterpart - the clerk library:
$ tree -L 1 ./bases/clj_tasks/src/snyssfx/clj_tasks/<br>./bases/clj_tasks/src/snyssfx/clj_tasks/<br>├── aoc2024<br>├── aoc2025<br>├── clojure_camp<br>├── common<br>├── curl_command.go<br>├── di<br>├── external_ip.go<br>├── gm.clj<br>├── gm.sql<br>├── gorillas.clj<br>├── hs.clj<br>├── leetcode<br>├── logic<br>├── lucky_tickets.clj<br>├── mb<br>├── our_mathematical_universe<br>├── other<br>├── portal.clj<br>├── test_deno.ipynb<br>└── vi.clj
In projects, I have several projects, for example, the site fe_experiments looks like this:
$ tree -L 1 ./projects/fe_experiments<br>./projects/fe_experiments<br>├── deps.edn<br>├── node_modules<br>├── package.json<br>├── package-lock.json<br>├── shadow-cljs.edn<br>└── target
Here I have the files with JS and CLJS dependencies, node_modules, and a bundled site in target for copying it to the server after the build.
What else?
It's convenient to have...