handwrite: turning a handwriting sample into a usable font
Handwrite generates a custom font based on your handwriting sample.
At a glance
- What is it?
- handwrite is a Python package that generates a custom font from a handwriting sample form and renders text in it, aimed at anyone who has to submit handwritten work but finds typing faster. It uses OpenCV and Pillow for image processing and Fontforge for the font itself.
- Who is it for?
- handwrite suits a student or professional who has to produce work that looks handwritten and would rather type than write it, since the sample form and the generated font are the whole workflow and the result drops into any word processor.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 56 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 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem it addresses
handwrite is described in one line as generating a custom font based on your handwriting sample. The README expands the motivation: long-winded assignments that a teacher always wants handwritten, and written work that is messy because the writer thinks faster than they can write.
The pitch is that you can finish such work with the ease of typing, in your own font. The claim is that handwrite makes typing written assignments efficient, convenient and authentic, and the generated font can easily be used in text editors and word processors such as Microsoft Word and LibreOffice Writer.
The second audience is named too: handwrite is also helpful for those with dysgraphia. That is a meaningfully different use case from the student who wants their work to look handwritten, and it explains a design decision that would otherwise look odd. A dyslexic or dysgraphic writer is not trying to disguise the origin of the text, they are trying to have a legible, personal output that they can produce efficiently rather than painfully.
The homepage is the PyPI project page for handwrite, and the README links a separate documentation site at yashlamba.github.io/handwrite for getting started. The repository is a modern Python package layout, with a pyproject.toml, a uv.lock, a .python-version file, a tests directory, a docs directory and an mkdocs.yml.
How the pipeline is put together
The README's Credits and Reference section is the closest thing to a design document, and it names four components.
The Potrace algorithm and package has been immensely helpful, and that is the tracing step: converting the bitmap strokes of the handwritten sample into vector outlines. Potrace is the well known bitmap to vector tracer, and choosing it means handwrite is not doing the vectorisation itself.
Fontforge handles packaging and adjusting font parameters, which is where the traced glyphs become a real font file with the metrics and metadata a word processor needs. The reference to Sacha Chua's project, sachac-hand, is described as a great reference for fontforge python, so the Python side of driving Fontforge follows an approach that already existed.
The third piece is the converter from SVG to TTF, and the README is careful about the attribution: all credit for the svgtottf converter goes to the pteromys/svgs2ttf project, with the note that they made quite a lot of modifications of their own but the base script idea was derived from there.
So the pipeline runs from an image of handwriting, through bitmap tracing to vector shapes, through a converter into font outlines, and finally into a packaged font. The declared runtime dependencies in the manifest are opencv-python and Pillow, which is where the image reading and preprocessing happen, and Fontforge is an external program the project drives rather than a Python package.
The sample form and the workflow
The workflow starts with a form. The README says you just need to fill up a form, and shows a filled sample image, followed by the end result as a rendered sentence.
That is the entire user journey as documented, and it is worth being precise about what it implies. You provide a handwriting sample, the tool traces the glyphs and builds a font, and you then use that font in whatever you were writing. There is no per-character drawing interface and no manual correction step described, so the sample form is doing the work of specifying the alphabet in one pass.
The consequence for anyone evaluating this is that the quality of the result depends on the sample. A form filled carefully, with each letter clearly formed and separated, produces clean outlines, while a rushed or overlapping sample produces outlines that trace the strokes rather than the letter shapes. That is inherent to a tracing approach: the tool is not being told what an a looks like, it is being shown one example of it and reproducing the curves.
The documentation site linked from the README is where the form itself is hosted, so a reader who wants to see the exact layout and the set of characters covered should look there rather than inferring it from the screenshots.
The command line entry point
The package installs a single console script. The manifest declares it under the project scripts table:
[project.scripts]
handwrite = "handwrite.cli:main"So the CLI lives in a handwrite.cli module with a main function, and the tool is invoked as handwrite once installed. The README does not document the individual flags, and the project documentation site is the place to look for them.
The manifest also pins the interpreter floor, which is unusually high and worth noting before you try to install it:
requires-python = ">=3.14"The classifier confirms it, listing Programming Language :: Python :: 3.14, and the black configuration sets a matching target version of py314. There is a .python-version file in the repository root, which is the usual companion for tools that manage interpreters, and the presence of a uv.lock shows the project is developed with uv.
For a package whose whole output is a font file, the size of the interpreter requirement is worth weighing. Python 3.14 is recent, and an environment pinned to an older release, which is common in a locked-down production image, cannot run this as a library either.
Dependencies, packaging and the developer toolchain
The dependency picture is short. The runtime dependencies are:
dependencies = [
"opencv-python",
"Pillow",
]Two libraries, both for image handling, and notably no font library. That is a consequence of the architecture: the font work is delegated to Fontforge and to the derived svgtottf script rather than to a Python font package, so the Python side is reading and preparing an image while the font construction happens outside Python's type system.
The build system is setuptools with a minimum of version 77, which is required for the PEP 639 style licence metadata the project uses. The licence field is MIT with license-files pointing at the LICENSE file, and the package data section includes a single file, default.json, under the handwrite package, which is most likely the configuration the CLI loads on first run.
The dependency groups are tidily separated. The dev group holds black and pre-commit, matching the pre-commit configuration file and the black badge in the README. The docs group holds mkdocs, mkdocs-material, mkdocstrings with the python extra, and pymdown-extensions, which is the standard MkDocs Material setup for generating API documentation from docstrings, and matches the mkdocs.yml at the repository root. The tool.uv section sets the default group to dev, so a uv sync installs the formatting tools by default.
The three named authors are Yash Lamba, Saksham Arora and Aryan Gupta.
Where handwrite is the wrong tool
Three limits are structural. The first is that Fontforge has to be present. The README credits it for packaging and adjusting font parameters, and it is not among the Python dependencies, so it is an external program that has to be installed on the machine, and the README's own reference to a fontforge python approach suggests the tool is driven through that tool's own scripting interface. On a machine where you cannot install system packages, or in a container image that only installs Python packages, this will not work without additional setup that the README does not document.
The second is that a traced font is not a designed font. The tool reproduces the curves of one handwriting sample, which means it inherits the letterforms of that sample, including its spacing, its proportions and its irregularities. A font designed for reading has deliberate spacing, optical corrections and consistent stroke weights, none of which come out of tracing. The result is legible and personal, which is what the project promises, but it is not going to hold up in a publication.
The third is the version floor combined with the release history. The manifest requires Python 3.14, and the releases are 0.4.0 on 2026-08-28, 0.3.1 on 2022-03-14 and 0.3.0 on 2021-11-26, so there was a long gap between the 0.3 line and the current one. The 0.3.0 release notes say additional CLI arguments and removed multiple input support, which tells you the CLI surface changed and that multi-sample input was dropped, which is consistent with the single-sample workflow the README describes.
The alternative approach, and the difference in approach is worth stating plainly, is a handwriting recognition engine. A recogniser takes your written text as an image and converts it to typed characters, so the output is text you can edit. handwrite takes a sample and produces a font, so the output is text you type that looks handwritten. The first preserves your original wording and requires no font installation; the second gives you an editable document that carries your handwriting as a style and works anywhere a font can be installed.
Editorial conclusion
handwrite suits a student or professional who has to produce work that looks handwritten and would rather type than write it, since the sample form and the generated font are the whole workflow and the result drops into any word processor. It is the wrong tool if you need typographic quality, since the point is a likeness of a handwriting rather than a well-drawn font, and it is the wrong tool if your environment cannot install Fontforge, which the project credits for packaging and adjusting font parameters. Verify first that Python 3.14 is available, since the manifest requires it, and note that the newest release is 0.4.0 from 2026-08-28 with the last push on the same day.
Frequently asked questions
What does handwrite do?
It generates a custom font based on your handwriting sample, which can then be used in text editors and word processors such as Microsoft Word and LibreOffice Writer. You fill in a sample form and the tool produces a font from your letters.
How is the handwrite font generated?
The README credits the Potrace algorithm for tracing, Fontforge for packaging and adjusting font parameters, and a converter derived from the pteromys/svgs2ttf project for turning the vector output into a font. The Python dependencies opencv-python and Pillow handle the image side.
Which Python version does handwrite require?
The manifest sets requires-python to >=3.14 and the classifier lists Python 3.14, with the black target version set to py314. The package also ships a .python-version file and a uv.lock, and is developed with uv.
How do I run handwrite after installing it?
The package installs a console script declared as handwrite = "handwrite.cli:main" under project.scripts, so you invoke it as handwrite from the command line. The README does not document the individual flags, so the documentation site at yashlamba.github.io/handwrite is the place to find them.
Is Fontforge needed to use handwrite?
Yes. Fontforge is credited with packaging and adjusting the font parameters and is not among the Python dependencies, so it is an external program that has to be installed separately from opencv-python and Pillow.
What is the latest version of handwrite?
The newest release is 0.4.0 from 2026-08-28, the PyPI project page is pypi.org/project/handwrite/, and the licence is MIT with the LICENSE file in the repository root.
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/yashlamba-handwrite)Was this useful?