I Created a Quilt Pattern Generator App for my Fabric Store with Racket
How this little “teaching” Lisp packs so much power to write an app in record time.
TL;DR
Last week I launched a simple nine-block quilt pattern generator built in Svelte for UI, Python FastAPI for API server, and Racket for the graphic back end after 3 days learning the latter.
Back story
I’m a former software engineer who is now co-owning a family business selling fabrics online to customers nation-wide. I was laid off from a tech startup in the beginning of 2020. Tired of the startup world, I joined my partner’s e-commerce fabric shop full-time, helping out with everything from preparing, ironing, packing, and shipping fabrics to customers nation-wide. After months of tirelessly grinding and being in the red, we finally reached $10k MRR just before last Christmas.
The idea of a quilt pattern generator app came to me after I stumbled onto a definition of a nine-patch quilt block. After googling everywhere, surprisingly the only nine-patch quilt pattern generator result I could find was an old web portfolio with old Macromedia Flash source code. Wanting to build something useful to the quilting community and hopefully bringing more quilters into my business, I started building a user-facing generator based on the definition.
What is a nine-patch block?
The nine-patch block is a common design pattern among quilters. It’s construction methods and primitive building shapes are simple, yet produce millions of interesting variations.
Each block is composed of 9 squares, arranged in a 3 x 3 grid. Each square is composed of one of 16 primitive shapes. Shapes are arranged such that the block is radially symmetric.
The basic building blocks of the nine block are limited to 16 unique geometric shapes. Each shape is allowed to rotate in 90 degree increments. Only 4 shapes are allowed in the center position to maintain radial symmetry.¹
Why Racket?
I spent a day evaluating my options for the fastest way to build the project in less than a week of free time outside normal fabric chucking hours. I wanted a language and/or tool that would allow me to output productive work as I’m learning at the same time, so having a nice REPL is a must.
First one that came to mind was JavaScript. Generating graphics in the browser sounded like a natural win. Moreover, there is more than a few choices of libraries to speed up the work. However, I have had a fair share of JavaScript experience and I personally try to shy away from using JavaScript with anything other than the web UI because it has been very buggy for anything complex.
Python was a great candidate, provided it has tons of great libraries to work on top of, not to mention the interactive REPL. However, contrary to its simplicity and beginner-friendliness, I’ve learned in years of practice that its procedural and OOP nature and the significance of white spaces can introduce many run-time bugs as well.
Then I thought of a functional language that can fits the bill. I have had some experience with Ocaml, Erlang, and Clojure, so I looked around and found Racket, which provides an extremely nice and graphical REPL through DrRacket and a great image library (2htdp/image) with abundant documentation. Racket would be the language that make me productive in the project while learning at the same time. I think Racket (and any Lisp dialect in general) has a very powerful homoiconicity that makes it extremely suitable for projects like this. The code form itself can be mapped visually to the visual pattern of the block with little mental context switch.
(above
(beside (a 0) (b 90) (a 90)
(beside (b 0) (c) (b 180)
(beside (a 270) (b 270) (a 180))
Development
I wrote the Racket code entirely in DrRacket because it actually displayed the image from the function, making the development a fun and fast learning process. I spent on north of three days to learn Racket and the 2htdp/image library and came up with a good enough solution, then I spent another adding the command line capability.
I picked Python FastAPI framework for the API server because of its suitability in writing a simple API service. Moreover, Python is ideal for when I want to extend the app to integrate with my future store on Shopify. Most of the time, the API server calls the Racket executable which creates an image and put it in a temporary directory, upload the image to AWS S3 bucket, and delete the image. It then responds to the request with the corresponding S3 URL.
On the front end, I spent just a day learning Svelte and three more days working on the UI. Coming from Angular and React, Svelte felt like a breath of fresh air. I’d recommend any front end developer to try it.
The API back end was hosted on a simple EC2 instance, using Caddy as a HTTPS proxy server and Gunicorn as a web server. The UI build was hosted on an S3 bucket and served via AWS Cloudfront.
Conclusion
After lauching, I posted on two subreddits, quilting and Fabrics, and got quite good feedback from both. I did seem to me that the app was helpful or at least fun for the target group since there are many apps developed for the use case. I’m really happy with the result and plan to keep adding more and more features. But most importantly, I’m glad I’ve chosen Racket because I couldn’t have done this as quickly, effortlessly, and with such fun that has lifted me from the trough of programmer’s burnout and rekindled my love in programming for the sake of programming, not building software for a VC-magnet.
[1]: Jared Tarbell, Nine Block, http://www.levitated.net/daily/lev9block.html