Looking for feedback for my first crystal project

Hi everyone! I just created tdiff, a cli app for comparing JSON/YAML files.

I would love to read your suggestions regarding organization, idiomatic crystal, general advise, etc. Also I’m scratching my head around how to properly create portable binaries for OSX and Windows, if at all possible, or at the very least a proper installation script for those platforms.

Anyway, thanks in advance for the time, and I’m excited to be part of this great community for such a cool language.


Easiest way for Linux would be to provide a static binary, and maybe a Snap package for it. A more robust way would be to, of course, is the provide the package via each OS’s package manager. However , I don’t really have any experience with this, but I imagine it could get painful versus Snap/static binary.

Mac would require building from source, or ideally use Homebrew.

Windows isn’t really supported ATM, so will just have to wait on that.

Thanks! a snap package would certainly be more robust. For this project, I created the binary with shards build --production --release --static --no-debug but I’m not sure if I should be aware of any potential issue with that running the binary in some random linux machine.

I guess a homebrew package would make a lot of sense. I’ve never tried it but it shouldn’t be that hard.

Nah, don’t have to wait. It works right now for this particular case :smiley:


And actually the resulting executable is fully portable (static), as I understand


also (sorry for hijacking this), you can indeed build for Windows with GitHub Actions.
With just this:

    runs-on: windows-latest
      - uses: actions/checkout@v2
      - uses: oprypin/install-crystal@v1
      - run: crystal build src/tdiff.cr
      - run: .\tdiff.exe

Some resources that I found helpful when working on https://github.com/Blacksmoke16/oq.


Can reference the Crystal blog post, and an example snapcraft file I use for oq.


I setup a GH action that will build/upload a static binary into the release assets when a release is created. AFAIK this binary should run on any AMD64 architecture UNIX based OS. Probably wont need the --link-flags option, as thats for libxml2.


Homebrew is the most painful of the three. Currently I’m handling this by just manually building/uploading the bottle. I suppose I could setup some job within GH actions to automate this, but :shrug:. Ideally, the package would be in homebrew core, which handles bottling for you.

The first link was super helpful is figuring out how to setup the bottle. The second is my cheatsheet so I remember what to do in order to update the bottled version.


@oprypin, Is that assuming there aren’t any dependencies? Like wouldn’t libyaml need to be installed?


Hehe I put the (static) libs to be published as a CI artifact https://github.com/crystal-lang/crystal/actions/runs/104687833/workflow#L108 - so they’re there

1 Like

Welcome to Crystal! :tada:

1 Like

That’s awesome! And great news!


Wow! Thanks for the amazing response! This will be super useful

Awesome! thanks for the link!

I confirm that the resulting executable is fully self-contained, because I copied only it and ran through Wine and it works :smiley:


Glad to see this github action! Nice work!


Who that’s awesome.

@oprypin So what features of Crystal I should not try to use while compiling on Windows?

Just a very late update, but thanks to @Blacksmoke16 I now have available instructions for homebrew (non-bottled) and snap.

And thank you @oprypin, I’m already publishing the windows binaries via gh actions.

I’d love to see some sort of how-to blog[s] for generating self-contained binaries for various platforms; or as part of the official docs. It would probably be great [critical?] for promoting Crystal v 1.0!