In 2009 I started working on a crossword editor written in Python called
Palabra (Spanish for "word"). It
was a desktop application developed for Ubuntu Linux that allowed anyone to
construct a crossword grid, fill in words and enter the clues for each entry.
It also included various operations on the grid, such as shifting cells, decorating
a cell and viewing grid statistics.

To create a crossword the application needs to provide all those things: a visual editor displaying
the grid, the ability to load and manipulate lists of words and so on.
Implementing everything in the same codebase seemed like a sensible approach
at the time. But looking
back at the code five years later it has become apparent that there is a much better
approach to constructing the same application: by splitting the functionality
into multiple modules that can be released and developed independently.
This approach is useful for very large software projects but it also applies to
seemingly small applications such as a crossword editor.

For example, the application needs to have the ability to read and write the
crossword to a file format. At the time (and still today) there are various
file formats in use in the crossword community that a crossword editor could
support. This includes the .puz file format, the .jpz file format and the
.ipuz file format.

It's possible to include the read / write functionality for multiple file formats as part of
the application's code. After all it makes little sense to use a
crossword editor if you can't save your work. But this
functionality can be reused in other applications or libraries without
needing the full code of the crossword editor. One can imagine a Python
library for .puz files, a Python library for .jpz files and a Python library
for .ipuz files which can be maintained independently. The
Python library for the .ipuz file format didn't exist yet so I have started
to work on that (entry on PyPI).
These modules can then be used by the Palabra crossword editor.

Taking this one step further we can now explore how a monolithic crossword
editor can be split up into multiple modules:

A module for reading / writing / validating .puz files.

A module for reading / writing / validating .jpz files.

A module for reading / writing / validating .xpf files.

A module for reading / writing / validating .ipuz files.

A module with a canonical data structure for a crossword grid plus common operations on the grid.

A module for filling a crossword grid with words, either manually, semi-assisted or fully-automated.

A module for loading and processing word lists (including fast searches, such as "give me all five-letter words with an S in the fourth position").

Each of these modules can be useful for other applications or purposes. It also
means that the desktop crossword editor needs to do no more than expose the functionality
of the above modules to the user. For example, it is possible to create a
web-based crossword editor by reusing all the Python modules and by
reimplementing only the logic of the editor.