This is probably a very ignorant question, but would it be possible to compile platforms into a core binary plus a library for each optional features, which would all be included in the distributed archive and linked by the roc compiler only as needed?
Seems like it would make platform development more complex if possible
So from an application author’s perspective it would feel like roc is doing dead code elimination/ live code inclusion for platform code
That is definitely a possibility. Though if we were to do something like that, no point in distributing the binary at all. Just make the whole platform a group of static libraries. Note, you would also need function sections and gc sections to get the dead code elimination.
This is essentially the legacy linker, but with multiple libraries instead of just one.
Sadly, being essentially the legacy linker comes with all the pain points of the legacy linker. The biggest two issue being:
It would be great if we could use the surgical linker to combine a platform binary with new optional features, but the surgical linker is only able to work with roc because roc has no dependencies. So it wouldn't work for essentially any optional feature given optional features probably make system calls and doing other things of that nature to enable new platform functionality
Interesting. So it sounds like in order to be feasible while maintaining Roc’s speed goals, we would need some kind of new linking system for binary application developers, regardless of what language they are using. Some kind of system that standardizes things regardless of language and system. Is that a correct understanding?
I don’t even know if it would be possible to create a linking system like that, it just sounds like a much deeper problem than one language compiler can solve, if I’m understanding correctly.
I mean you would still have the dependency issues even with a new linking system.
And yeah, really is not a rabbit whole we want to look down.
Of course, if someone wants smaller output, there will always be workarounds.
The simplest would be to make a custom slimmed platform or link roc into a static library letting the host language control the entire complication process instead of roc controlling the process.
I know 3MB is enormous for a web app shipped to the browser, but I have no idea how big it is in the context of CLI tools.
Having a separate platform for those who need small binaries doesn’t seem terrible.
I mean these sizes are essentially what you would get with rust, so makes sense for a rust based cli platform
What I’m getting from this is that Roc’s platform/application split is just very very useful. Need a smaller binary? Build a simple platform with Zig or something. Other needs? Do something else.
I wonder how small a zig cli platform without network functionality could get
What I’m getting from this is that Roc’s platform/application split is just very very useful. Need a smaller binary? Build a simple platform with Zig or something. Other needs? Do something else.
I don't think that's the right thing to take away from this. In general your app is going to be written for a single platform. Swapping it is not something that you'd expect to be easy.
In the long term we'd expect to have one or two platforms for web servers, one or two for CLI apps, one or two for graphical apps, etc. You can't switch out a web server platform for a graphical app platform, it doesn't make sense.
Just to clarify, rust has larger binaries because it does a lot of static dependencies. So instead of linking to a shared library it will tend to compile all the code into a single binary.
Our rust basic cli platform is 3MB, but only has 4 shared library dependencies.
curl
as a c example, is 300KB, but has 33 shared library dependencies.
Brian Carroll said:
What I’m getting from this is that Roc’s platform/application split is just very very useful. Need a smaller binary? Build a simple platform with Zig or something. Other needs? Do something else.
I don't think that's the right thing to take away from this. In general your app is going to be written for a single platform. Swapping it is not something that you'd expect to be easy.
That makes sense. You may not have an application that can be dropped into multiple contexts, but you can possibly reach for a different platform instead of reaching for a different language.
yeah that's true in theory, it's like if I have a Python website built on Django framework it's possible to swap it to use Flask framework instead but I'm not expecting it to be easy.
Its pretty easy to build the roc app into a library using roc build --lib myApp.roc
. If you give that to cargo or zig can it link it and then strip the unused stuff out? doesn't work for url packages, but could be another way to get a smaller app executable.
Brian Carroll said:
yeah that's true in theory, it's like if I have a Python website built on Django framework it's possible to swap it to use Flask framework instead but I'm not expecting it to be easy.
Yeah I wouldn’t expect that to be easy by any stretch of the imagination. I guess I’m thinking more of the ability to choose Roc when beginning a project rather than rewriting code to use a different platform.
If I’m starting a project with a particular set of constraints, and a Roc platform exists that is well suited to those constraints, I can use Roc.
Elias Mulhall said:
I wonder how small a zig cli platform without network functionality could get
I don’t remember which talk it was in, but I think I remember Loris Cro saying something about committing a zig binary to git and using it in CI.
If you give that to cargo or zig can it link it and then strip the unused stuff out?
We may need to enable some function section stuff, but yeah, in general. Also, probably want --no-link
cause --lib
is currently a shared lib and you really want a static lib.
Sorry, I feel like I derailed the topic a bit.
26 messages were moved here from #contributing > basic-cli reqwest lib size by Brendan Hansknecht.
No worries, can always move messages to more specific topics
That works!
Re CURL: if it was built with MUSL it would be a lot larger yeah? So basically you have to choose between larger binaries or the challenges of dynamic linking.
committing a zig binary to git and using it in CI
I think that might have been the Wasm binary they use to bootstrap the self-hosted compiler
Yeah, curl would be way larger without all the dynamic dependencies. In fact just adding back in lib curl, the total size is already 1MB.
Brian Carroll said:
committing a zig binary to git and using it in CI
I think that might have been the Wasm binary they use to bootstrap the self-hosted compiler
Maybe that was it. All I remember is that he was able to make a very small binary.
Last updated: Jul 05 2025 at 12:14 UTC