Skip to content

Instantly share code, notes, and snippets.

@bmaupin
Last active October 14, 2024 23:38
Show Gist options
  • Save bmaupin/67af52c1a99cc9b0542a4c70e8949a9c to your computer and use it in GitHub Desktop.
Save bmaupin/67af52c1a99cc9b0542a4c70e8949a9c to your computer and use it in GitHub Desktop.
Modern high-level languages that compile to native binaries

Goal

A simple way to write native applications (particularly CLI applications but optionally GUI applications) in a modern language (e.g. not C++/Qt) that's fun to use (e.g. not Go). This is primarily for small utilities where speed isn't a big concern. Binary size is a mild concern. Most of the rest is just icing on the cake (cross-compile support, etc).

Summary

Language High-level Garbage-collected Cross-compiling REPL Backed by large organization Cross-platform GUI library Comments
πŸ‘‰ TypeScript with pkg yes yes yes yes yes yes This isn't really "native" but may be the best option for something quick and dirty without having to resort to less-fun languages (like Go). See test-javascript-executables for ways to get the binary as small as possible.
Kotlin with GraalVM yes yes ⚠ no yes yes yes Fun to write (unlike Go) and truly cross-platform (unlike Swift) although binaries may be large and not super efficient and ⚠ no cross-compiling support (see workaround)
Dart yes yes ⚠ no ⚠ no yes yes Without cross-compilation or a REPL, the only advantage this might have over Go is that it looks like it's probably enjoyable to use
Go ⚠ no yes yes ⚠ no yes no Probably best choice to build small, fast, cross-platform binaries, but ⚠ terribly pedantic and not fun to write, made worse by lack of REPL
Swift yes yes ⚠ no yes yes no Not a terrible choice, but ⚠ not truly open or cross-platform (e.g. see comments here, here, here; IBM has stopped working on Swift; Swift for TensorFlow has been abandoned)
Kotlin Native yes yes yes ⚠ Can't use JVM libraries, no REPL?
Nim yes yes non-trivial ⚠ no ⚠ no ⚠ No REPL, hasn't gained enough traction to prove it will be around for a while yet, footguns (significant whitespace)
Crystal yes yes ⚠ no ⚠ no ⚠ No REPL, hasn't gained enough traction to prove it will be around for a while yet, footguns, Ruby syntax
Zig ⚠ no ⚠ no yes ⚠ no ⚠ no ⚠ No REPL, too low-level (no exceptions, no built-in string types), not garbage-collected
Rust ⚠ no ⚠ no ⚠ no yes ⚠ No REPL, too low-level, not garbage-collected, too complex, too many footguns, slow compilation

Notes

  • Kotlin with GraalVM
    • Pros
    • Cons
      • GraalVM may not support 100% of Kotlin JVM code yet
      • Large-ish binary size (probably not a big deal except for very small CLI utilities, ~5 MB overhead)
  • Kotlin Native
    • Pros
    • Cons
      • Kotlin Native can't use JVM libraries
  • Swift
  • Nim
    • Pros
      • Garbage collected
    • Cons
      • Python syntax (i.e. whitespace is significant)
      • Cross-compiling seems to require some legwork
      • Footguns (macros, operator overloading)
  • Crystal
    • Cons
      • Ruby syntax (one more thing to learn)
      • Footguns (macros, operator overloading)
  • Go
    • Pros
      • Backed by Google
      • Very fast
      • Great concurrency support
      • Great tools
      • Spec is consise and simple enough you can hold most of the language in your head
      • Cross-compiling is super simple
    • Cons
      • Not fun to write πŸ˜•
        • Very pedantic; compiles will fail with unused libraries, variables, etc
        • No exceptions, only error codes, which must all be handled explictly which is annoying to do and the code ends up littered with error code handling
      • No REPL for quick hacking
      • Too low-level: have to deal with pointers and dereferencing
  • Zig
    • Pros
      • Cross-compiling supported out of the box
      • Very small binaries
      • Simple with no footguns (macros, operator overloading)
    • Cons
      • Not backed by any major organization
      • Memory must be managed manually 😬
      • No native string support
      • Too low-level: have to deal with pointers and dereferencing
  • Rust
    • Pros
      • Very safe
    • Cons
      • Memory must be managed manually 😬
      • Very complex
      • Lots of footguns (macros, operator overloading, etc)
      • Slow to compile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment