Yesterday, I published my first open source Racket package.
It’s a loader for
.env files. Nothing fancy, but it fills an obvious gap in the language’s library offerings.
The process was largely painless, but understanding a few things up front would’ve helped me along the way.
Start With The Package Template
At first, I trawled through the package index, looking for anything with passing tests and documentation.
I looked at package structures, function names, documentation, and anything else that looked like an important part of
packaging. This was mostly unnecessary. Running
raco pkg new dotenv would’ve set up a sane default directory
for my package without any extra fuss.
Making Sense Of
When you make the package template, you’ll want to get into
main.rkt right away. It has a few interesting features
that I didn’t understand on first reading. The
forms define the modules
test module is declared twice, but the
module+ form actually
concatenates them into one instead of redeclaring the same module. In
dotenv, I removed the
test module from
main.rkt entirely and put it in its own file at
private/tests.rkt. Inside, I declared the
test module and put
my test code inside. It’s a section of imperative code that sets up some boilerplate and checks the results of functions,
one after the other. Just because it’s Racket doesn’t mean it needs to be impressive functional code.
To run your tests, type
raco test . in your package directory. It’ll find and execute every module called
output the results.
Don’t make the same mistake I did and type
raco test and assume that the empty output indicates success.
You can also run
raco test -x . to exclude loading of files that lack a
For my modest test suite, this cuts execution time from 4s to 2s.
There’s also a curious comment
;; Code here which seems to suggest that you start programming directly inside
main.rkt. You could publish a perfectly fine package like this, but I prefer to leave
main.rkt exclusively for
package setup boilerplate. Instead, I moved my main code out to
private/dotenv.rkt. This allowed me to
every single function from
dotenv.rkt for consumption by my unit tests while only providing a much smaller
quantity of API functions via
info.rkt is more straightforward. One small disagreement I have with the default
info.rkt is that it includes
rackunit-lib as a runtime dependency by default. There’s really no reason an end user would ever run unit tests,
so move it to
Unless I am mistaken, inclusion as a runtime dependency also means
rackunit-lib would get built into any executable,
which sounds like pointless bloat.
The actual act of publishing is by far the easiest part. The package repository on racket-lang.org is straightforward to use. Upload your code to some git repository, Github perhaps, and the package repository will handle the rest. It’ll build the package, build the docs, host the docs, and provide test results. One caveat is that unlike Composer, it does not track versions automatically. You’ll need to manually add each new version to your package description for it to know about anything besides the latest commit.
Racket features a unique documentation system called Scribble. It not only produces pleasing HTML output, but also
creates links within your own documentation and links back to the main Racket documentation. Sure, you’ll want to have
something in your
readme.md, but the Scribble docs will be superior.
To get started, you’ll want to add
scribblings/*.css to your
.gitignore so you don’t end up committing built documentation files like I did.
The next obvious change is to add your actual name and email address to the top.
I didn’t spend enough time to really understand the Scribble docs, but I was able to eventually figure out that
@author[@author+email["Royall Spence" "firstname.lastname@example.org"]] would add my name and email together.
My documentation for dotenv starts off with a section with concrete usage examples as a quickstart for my users.
It’s easy to do, but it’s not featured in the default Scribble:
Just having other Scribble docs available was the best thing to help me get started.
You might consider the one I wrote for dotenv
to help you get started.
If you’re having trouble with your own project, the best thing to do is get on the mailing list and describe your question. Racket has the friendliest community I’ve ever seen. When you get your package published, get on Twitter and tag the official Racket account with a release announcement. They’ll retweet so the wider Racket world knows of your new package.
Particular thanks to Jack Firth whose advice served as source material for half of this post.