# How to distribute julia software to the general public

**URL:** <https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981>\
**Category:** Tooling\
**Created:** [July 30, 2019, 2:32pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981 "2019-07-30T14:32:43Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 30, 2019, 2:32pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/1 "2019-07-30T14:32:44Z")

</div>

Which is the best way to distribute a software developed in Julia for the general public? I mean, assuming the installation of the Julia interpreter is out of question.

Most specifically, I have a software that performs some heavy calculations, written in Julia, and that is used as a backend in another software that has a simple GUI for Windows.

Normally, I would distribute an executable with static libraries. I understand that this is not possible (yet) with Julia.

I wander if there is a way to package all the functions and routines used by my package and distribute it as a “minimal” Julia interpreter with the package. Even if it is not an executable, this solution would be good enough and could be hidden from the user.

Thank you for your thoughts.  
Leandro.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 30, 2019, 2:51pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/2 "2019-07-30T14:51:25Z")

</div>

> [@lmiq](#):
>
> I mean, assuming the installation of the Julia interpreter is out of question.

Why? A Bash script that

1. downloads a given version of Julia, then extracts it in a subdirectory,
2. sets up another subdirectory as your depot path,
3. extracts/downloads your project and instantiates the dependencies, and perhaps compiles them into the image

is reasonably simple.

The other solution would be a container, eg with Docker. I guess this is fine too, especially the backend can operate through a local network connection.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [July 30, 2019, 2:57pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/3 "2019-07-30T14:57:52Z")

</div>

There’s also [ApplicationBuilder.jl](https://github.com/NHDaly/ApplicationBuilder.jl) and a [nice talk](https://youtu.be/kSp6d3qSb3I) on it from JuliaCon 2018. It might not be the easiest to get working though; I haven’t used it myself actually.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 30, 2019, 2:57pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/4 "2019-07-30T14:57:55Z")

</div>

I suppose something like that could be included as part of a Setup wizard for Windows, but it would still generate a ton of data for a package which, statically linked, would occupy 1MB.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 30, 2019, 3:14pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/5 "2019-07-30T15:14:19Z")

</div>

Sadly, there really aren’t any solutions right now for having reasonably sized binaries. It does require ~ 600 MB at least to run any Julia code. The only way around that (in principle) is building static binaries with PackageCompiler, but I don’t know if anyone has managed to get the total binary size much smaller than that.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 30, 2019, 4:10pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/6 "2019-07-30T16:10:22Z")

</div>

> [@lmiq](#):
>
> generate a ton of data for a package which, statically linked, would occupy 1MB.

I don’t think that 1MB is a reasonable expectation for a language like Julia. You may never get binaries the size of C, but for a desktop/productivity program that does something genuinely useful, people should not balk at 1GB these days (for which SSD storage costs about 10 cents, and download takes a few minutes on a wired connection).

Or you can set it up as a service on a website.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 30, 2019, 5:48pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/7 "2019-07-30T17:48:33Z")

</div>

In this specific case my contribution to the code is one number crunching application which is important but would not take much space. The UI etc takes about 100MB and is developed by other people.

I will probably just translate the code to Fortran or C at the end, which is not terrible for this application, but not what we would like to do, of course.

Thank you for all your comments.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [July 31, 2019, 9:22am UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/8 "2019-07-31T09:22:06Z")

</div>

Another alternative is a web application and run the Julia part on your own servers.

---

<div class="post-metadata">

**Author:** ![jpsamaroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpsamaroo/32/46804_2.png) [@jpsamaroo](https://discourse.julialang.org/u/jpsamaroo)\
**Post date:** [July 31, 2019, 12:10pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/9 "2019-07-31T12:10:44Z")

</div>

> [@Tamas\_Papp](#):
>
> I don’t think that 1MB is a reasonable expectation for a language like Julia. You may never get binaries the size of C, but for a desktop/productivity program that does something genuinely useful, people should not balk at 1GB these days (for which SSD storage costs about 10 cents, and download takes a few minutes on a wired connection).

I disagree with this sentiment. There isn’t anything (other than explicit calls to `eval` at runtime) that should stop Julia code from being static compiled to a very small binary. Take a look at the size of CUDAnative kernels; they’re tiny and they can do tons of number crunching. Adapting this approach to native binaries with init logic and a C-callable interface is really all the OP would need to make their project feasible.

Also, let’s please not encourage software bloat just because disk space is getting cheaper. There is no reason why 1GB should be needed for a very small program which is only doing basic number crunching.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 31, 2019, 12:48pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/10 "2019-07-31T12:48:57Z")

</div>

> [@jpsamaroo](#):
>
> There isn’t anything (other than explicit calls to `eval` at runtime) that should stop Julia code from being static compiled to a very small binary.

I am not sure about this. The complete universe of (parametric) types used is perhaps fixed for some programs _in theory_, but deriving this in a foolproof manner _in practice_ is a very hard problem. So you need the whole machinery.

Eg consider

```julia
struct Bar{T}
    x::T
end

f(z::Bar) = rand() > 0.9 ? z : f(Bar(z))

f(Bar(1))

```

While this is a contrived example, higher-level logic may not be type stable even in well-written Julia programs, especially if they use external input.

> [@jpsamaroo](#):
>
> There is no reason why 1GB should be needed for a very small program which is only doing basic number crunching.

People have been complaining about this since the early days of eg Common Lisp (“you need 10MB to do _what_?”), but as disks are getting cheaper and programmer time remains expensive, expect this trend to continue.

Eg if it takes me an afternoon to shave off 50MB from a program that will run on less than 1000 machines, then working on this would make sense only if I put a very low value on my time.

---

<div class="post-metadata">

**Author:** ![jpsamaroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpsamaroo/32/46804_2.png) [@jpsamaroo](https://discourse.julialang.org/u/jpsamaroo)\
**Post date:** [August 2, 2019, 3:10pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/11 "2019-08-02T15:10:31Z")

</div>

I won’t disagree with the example you posted; something like that _will_ be hard to deal with, unless we’re somehow able to construct and work with types without doing any codegen (which may be possible by interpreting until we get back to compiled code paths). I’ll keep this example in mind ❤

> [@Tamas\_Papp](#):
>
> People have been complaining about this since the early days of eg Common Lisp (“you need 10MB to do _what_ ?”), but as disks are getting cheaper and programmer time remains expensive, expect this trend to continue.

I get that this has always been the case, but I still find 1GB to be absolutely absurd for a very small program, even by today’s standard. And the fact that static languages like C can make amazingly small binaries with a modern compiler urges me to figure out how to do the same in Julia.

> [@Tamas\_Papp](#):
>
> Eg if it takes me an afternoon to shave off 50MB from a program that will run on less than 1000 machines, then working on this would make sense only if I put a very low value on my time.

I also place a high value on my time, but I’m also hoping that once written, a Julia static compiler would be able to do this automatically without the developer having to spend any time working on it at all. I certainly wouldn’t want smaller and smaller binaries to require more and more developer time!

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [August 2, 2019, 3:16pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/12 "2019-08-02T15:16:11Z")

</div>

> [@jpsamaroo](#):
>
> And the fact that static languages like C can make amazingly small binaries with a modern compiler urges me to figure out how to do the same in Julia.

I think a prerequisite for that is a set of dynamically linked libs that are always available no matter where the executable is run. Julia obviously does not have that.

But, if you absolutely don’t need to hide your source code, distributing a small package is as good (or even better) than a small binary, I think.

---

<div class="post-metadata">

**Author:** ![jpsamaroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpsamaroo/32/46804_2.png) [@jpsamaroo](https://discourse.julialang.org/u/jpsamaroo)\
**Post date:** [August 2, 2019, 3:20pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/13 "2019-08-02T15:20:46Z")

</div>

Sure, and so we’ll probably need, at a minimum, libc and possibly libjulia for each program. Other than that, there shouldn’t be any required dependencies for very simple programs that don’t make heavy use of the task runtime, BLAS, etc. An example I like to think of is an email filter (milter) that does very simple text wrangling of emails as they are received by a mail server. All that would probably need (in terms of shared libraries) is libc, libjulia, and PCRE.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [August 2, 2019, 3:22pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/14 "2019-08-02T15:22:54Z")

</div>

I feel that it wouldn’t hurt much if the compiler asked the developer which are the types of the parameters for the function calls it couldn’t strictly determine. In static languages we do that while coding, I don’t see why that would be a big issue if one wants a static compiled code.

---

<div class="post-metadata">

**Author:** ![dhazeghi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dhazeghi/32/7107_2.png) [@dhazeghi](https://discourse.julialang.org/u/dhazeghi)\
**Post date:** [August 2, 2019, 3:56pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/15 "2019-08-02T15:56:47Z")

</div>

Is there such a thing as a small Julia-built binary? Even without static linking, my binaries are huge - minimum of about 160MB for trivial ones. For simple short-running tools, it’s far from ideal.

---

<div class="post-metadata">

**Author:** ![jpsamaroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpsamaroo/32/46804_2.png) [@jpsamaroo](https://discourse.julialang.org/u/jpsamaroo)\
**Post date:** [August 2, 2019, 4:34pm UTC](https://discourse.julialang.org/t/how-to-distribute-julia-software-to-the-general-public/26981/16 "2019-08-02T16:34:20Z")

</div>

You’re referring to PackageCompiler binaries, which simply compile your code on top of the sysimage - and that sysimage is, by default, ~170MB on the typical Linux machine. I’m aiming for static compilation like what CUDAnative does for its kernels. Those kernels can be arbitrarily small, probably down to below a single page of memory (4KB) if the kernel doesn’t do anything too complicated. That’s the approach that I plan on taking.
