AsciiDots: an esolang whose programs are drawings you watch run
Esolang inspired by ASCII art
At a glance
- What is it?
- AsciiDots is a Python esolang in which dots travel down drawn paths and undergo operations as the program executes. It is a teaching and curiosity project, not a production language, and its release history tells you as much as its interpreter does.
- Who is it for?
- AsciiDots fits teaching, conference demos, and anyone curious about dataflow drawn as pictures, and it fits nothing else. Do not pick it for work that needs a maintained toolchain, because the newest tagged release, 1.3.4, dates from 2020-03-09 even though the last push was on 2026-08-15.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 69 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Dots move down the drawing, and the drawing is the program
AsciiDots is described as an esolang inspired by ASCII art, and the project's own summary of the idea is short: in this language, dots, represented by periods, travel down ASCII art paths and undergo operations. That single sentence describes the whole execution model. A program is a picture. Lines drawn with slashes, dashes, pipes, and hashes act as wires, and the period that starts the flow is a token that moves along those wires until it hits a symbol that changes it.
A complete program can be two characters wide. The hello world sample is a period, a dash, and a quoted string:
.-$"Hello, World!"The period enters the path, the dash carries it rightward, and the dollar sign triggers the operation that prints the quoted text. There is no variable declaration, no function syntax, and no statement ordering in the textual sense, because there is no text. The structure of the program is the geometry of the drawing. The interpreter reads the picture and simulates motion through it, which is why the language is called dataflow in practice even though the repository topics list it under esoteric-language and programming-language.
The samples make the model concrete. The counter program is a closed loop that repeatedly increments a value, and the factorial calculator threads several values through a branching arrangement of paths. The prime finder is the largest of them, with a sieve-like structure drawn across many rows. A quine sample exists too, and a code-golfed 15 byte counter by @ddorn shows that the drawing can be compressed when a program can be routed more tightly.
Installing the interpreter with pip, Docker, or from source
The project offers three ways in, and the documentation is direct about which is easiest. The online demo at ajanse.me/asciidots and the Try it Online entry at tio.run both let you run code without touching a local Python environment, and the documentation points there first.
For a local install, pip is the shortest path:
pip install asciidotsThat pulls the `asciidots` package and installs a console script, because setup.py registers the entry point `asciidots=dots.__main__:main`. The only hard dependency listed in requirements.txt is Click.
A published Docker Hub image is available too, and the given commands show both a bundled sample and a local file:
docker run -ti --rm aaronduino/asciidots samples/hello_world.dotsdocker run -ti --rm -v $PWD:/data aaronduino/asciidots /data/test.dotsThe second form mounts the current directory so the interpreter can read a file from your machine. The image itself is minimal: the Dockerfile starts from `python:3`, installs click with `pip3 install --no-cache-dir click`, copies the repository into `/code`, and sets `ENTRYPOINT ["python", "__main__.py"]`.
Building from source is a three-line sequence, with a Windows-only extra step:
git clone https://github.com/aaronjanse/asciidots
pip install -r requirements.txt
# and only if on windows:
python -m pip install windows-cursesFrom a source checkout the interpreter is run directly:
python __main__.py [arguments]The first argument is the `.dots` file to run. The documentation also shows how to alias the checkout so the `asciidots` command works from anywhere:
# on Ubuntu, replace `.bash_profile` with `.bashrc`
echo "alias asciidots='python $(pwd)/__main__.py'" >> ~/.bash_profile
source ~/.bash_profileStepping through a program with the -d debug flag
The interpreter's flags are aimed squarely at watching a program move, which is the whole point of a language drawn as a picture. The full list given in the documentation is:
-t [ticks] Run the program for a specified number of ticks (Default to 0: no limit)
-o [output-limit] Run the program for a specified number of outputs (Default to 0: no limit)
-s Run without printing ANYTHING to the console. Useful for benchmarking
-d Run the program in debug mode. It shows the program and highlights the dots with red. Press enter to step the program once.
Some extra flags when debugging:
-a [delay] Step the program automatically, using the specified delay in seconds. Decimal numbers are permitted, and so is 0.
-w Run the program without using ncurses. This can fix problems related to Windows.
-l [line-count] When not in compatibility mode, reserve the specified number of the lines for displaying the programDebug mode redraws the program and marks the dots in red, and each press of enter advances the simulation by a single tick. The `-a` flag automates that stepping with a delay in seconds, and the documentation pairs it with a concrete example on the counter sample:
$ asciidots samples/counter.dots -t 300 -d -a 0.05The limit flags are the practical ones. `-t` caps the number of ticks and `-o` caps the number of outputs, and both default to 0, which means no limit. Without one of these, a program that loops forever will keep the terminal occupied indefinitely, which is a realistic hazard in a language where closed loops are the idiomatic way to build a counter. `-s` suppresses all console output, which the documentation notes is useful for benchmarking, and `-l` reserves a number of lines so the program display does not collide with the terminal area used for output.
The samples directory is where the language is actually explained
The prose documentation lives off-site at ajanse.me/asciidots, and the README mainly points there. The in-repository explanation is the sample programs, of which there are more than twenty under samples/. Their names cover the range of what the language can express: hello_world.dots, counter.dots, counter.compact.dots, factor.dots, factorial.dots, factorial.compact.dots, factorial.tiny.dots, fibonacci.dots, fibonacci.compact.dots, fibonacci.tiny.dots, find_primes.dots, subtract.dots, 2darray.dots, equality_tester.dots, evilness_tester.compact.dots, operators.dots, three.dots, game.dots, and the quine pair quine.dots and quine_sig.dots.
Two of them are worth singling out. The compressed variants show the same algorithm redrawn to occupy less space, which makes the routing decisions visible: a compact version is not shorter text but a tighter arrangement of paths. The two library samples, using_libs.dots and using_compress_decompress_libs.dots, show that the language can pull in reusable pieces, and setup.py packages the contents of dots/libs as package data so those libraries ship with the install.
The rest of the tree supports that idea of a workspace rather than a flat script collection. Alongside the samples directory the repository contains dots/, workspace/, docs/, test/, a default.nix file, a distribute.sh script, and a .devcontainer/ directory. The test/ directory and the .travis.yml configuration file suggest the interpreter is exercised by an automated check, and the presence of a devcontainer means the author expects people to open the project in a containerized editor.
For a newcomer the practical route is to read a small sample next to the documentation site, then to change one path and watch what the -d view does.
Click is the only dependency, and ncurses is the fragile part
The dependency surface is unusually small. requirements.txt contains a single line, Click, and the Dockerfile mirrors that by installing only click. setup.py declares `python_requires='>=2.6, <4'` and lists classifiers for Python 2.6, 2.7, 3, 3.3, 3.4, 3.5, and 3.6, so the package was written for a wide interpreter range rather than a single modern release.
That same file carries a label worth noting. The license field reads `APGL-v3.0`, and the classifier list includes `License :: OSI Approved :: GNU Affero General Public License v3`, while the repository ships a License.md and the GitHub record for the project lists the licence as AGPL-3.0. The typo in the setup.py field is a packaging detail, not a different licence, but it is the sort of inconsistency that makes a quick `pip show` reading misleading.
The practical fragility sits in the terminal rendering rather than the dependency list. The `-d` mode shows the program and highlights dots in red, and the `-w` flag exists specifically to run the program without using ncurses, with the note that this can fix problems related to Windows. The source install instructions also add `python -m pip install windows-curses` on Windows only. In other words, the curses-based display is a hard requirement of the normal mode, and the escape hatch is the `-w` flag, which gives up the interactive display. Debugging a dataflow language without the animated view is much less useful, so anyone on a minimal or non-standard terminal should test that path early.
The setup.py metadata also carries a `Development Status :: 5 - Production/Stable` classifier and an `Intended Audience :: Education` classifier, which is a fair description of what this project is for.
What AsciiDots is not for
The language's shape makes the wrong-tool cases easy to name. Because a program is a picture, there is no way to write a large routine in AsciiDots and keep it readable, and the geometry of the layout becomes the cost of every change. Editing a value means moving wires, and moving wires can break a routing that was not obvious. The compact and tiny sample variants exist precisely because shrinking a drawing is hard.
Input and output are also thin. The language has a quoted-string output operation, and the game sample reads a numeric reply and branches on it, but the repository contains no documented mechanism for reading files, and the samples that exist work with numbers and short strings. Anything needing a real data source or a large text corpus is outside what the visible feature set covers.
The interpreter is single-file and Python based, with the whole program in `__main__.py` and a `dots` package. There is no versioned release since 1.3.4, which the release list dates to 2020-03-09, while the last push to the repository was on 2026-08-15. So the code is not frozen, but there is also no recent tagged build to pin.
Finally, the AGPL-3.0 licence is a network copyleft. Hosting a modified interpreter as a service, or shipping it inside a product, pulls in source obligations for the modified work. That is a matter for whoever handles the licensing question on your side, not something this article should interpret, but it is a real constraint on where the project can be dropped into a stack.
AsciiDots against a conventional program with the same behaviour
The most honest comparison is not against another esolang but against the obvious alternative: writing the same program in an ordinary language. The counter sample is the clearest case. In AsciiDots it is a closed loop of drawn paths with a `+` box, a value of `1` entering, and a counter cell incrementing on each pass. The output is not printed line by line but emerges as the dot visits the output operation on every circuit, and the `-o` flag exists to cap how many outputs you see.
A conventional implementation of the same counter is a loop with a variable, an increment, and a print call, and it is shorter, easier to test, and it does not need a redrawing of the screen on every tick. What the conventional version cannot do is show its own structure as an image that a reader can understand without reading code.
That is the whole trade. AsciiDots trades editing convenience and program size for legibility of control flow, and it does that trade on small programs where the picture fits on a screen. It is a good fit for a conference talk, a language tutorial, a lecture on dataflow, or a curiosity project, and a bad fit for anything where the logic grows past what a reader can hold in one view. The alternative is not a specific competing tool but a familiar one: for anything beyond a demonstration, the same behaviour in a conventional language is the lower cost path, and the AsciiDots implementation is worth keeping as the illustration.
Editorial conclusion
AsciiDots fits teaching, conference demos, and anyone curious about dataflow drawn as pictures, and it fits nothing else. Do not pick it for work that needs a maintained toolchain, because the newest tagged release, 1.3.4, dates from 2020-03-09 even though the last push was on 2026-08-15. Before you commit, check that the sample programs in samples/ still run under your Python version, that your terminal handles the ncurses rendering the -d flag depends on, and that the AGPL-3.0 licence in License.md is acceptable for whatever you plan to do with it.
Frequently asked questions
How do I install and run AsciiDots?
The shortest route is `pip install asciidots`, which installs the `asciidots` console script, or `pip install -r requirements.txt` from a source checkout followed by `python __main__.py [arguments]`. A Docker image is also published, and the documentation points to an online demo and a Try it Online entry as the easiest way to try the language without a local install.
What is the AsciiDots language and how does it work?
It is an esolang inspired by ASCII art where dots, represented by periods, travel down ASCII art paths and undergo operations. A program is a picture of paths and symbols, and the interpreter simulates dots moving through that picture, so the geometry of the drawing is the control flow.
How do I debug an AsciiDots program?
Run it with `-d` to enter debug mode, which shows the program and highlights the dots in red, then press enter to step one tick at a time. Add `-a 0.05` to step automatically with a delay in seconds, and use `-t 300` to stop after a fixed number of ticks, since both `-t` and `-o` default to no limit.
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/aaronjanse-asciidots)Was this useful?