Easy, you make use of tree-shaking, which is actually older concept than minifying JavaScript, and add glue it together with an executable header that boots the image.
I don't feel like this really answers OP's question, which is more about the user experience than the technical approach.
When, as a dev, I use Smalltalk, it opens up what's effectively a virtual machine on my desktop. The whole Smalltalk GUI runs inside its own frame, none of the controls are native, etc. And it's a development environment - I have access to a class browser, a debugger, a REPL, and so on. I can drill down and read/modify the source code of everything. Which is great as a dev, but may be intimidating for an end user.
Is that what the end user experience is like as well? I think that's what OP is asking. I've never used a Smalltalk application as an end user to my knowledge, so I can't say myself.
The user experience, in commercial Smalltalks, like Cincom Smalltalk, is just like any other compiled application.
The application packager removes everything that is related to Smalltalk as developer environment, and possibly other classes that are also not used by the application, so you get a slimmed down image.
Then you have the VM boot code, as native executable, that is responsible for starting the image execution.
Thanks to the way executable files work in most platforms, the packing tool merges that boot loader and the slimmed down image into a single executable.
When the executable starts, the loader locates the image inside the executable, loads it, and transfers execution to the runtime.
Java and .NET also have similar techniques available, see jlink, or Single-file deployment respectively.
No, you can tell the image to not boot the 'world', only the application you've been building. The details probably vary a lot between versions of the language, but you wouldn't be forced to put system browsers and all that in the face of your user.
> Calling it "tree shaking" is web development term AFAIK.
I think that's backwards. Lars Bak and the other V8 folks came from the Smalltalk world and brought the "tree shaking" term with them as far as I know.
In any case, before the JavaScript usage, it seems that treeshaking applied to objects to be included in a runtime image. The JavaScript usage is actually more akin to the dead-code elimination and link-time symbol removal of compiled and linked languages.
Tree shaking in this context is not unlike a compiler: it looks at all the code and determines if it will ever run in the image, eliminating any unnecessary code and delivering the minimal image needed. The code is in a “tree” format like an AST, and you’re shaking the tree to test what can be removed.