First, julia has it's own IR (comparable to swift IR as mentioned by Chris), which is used to great effect in the autodiff packages to allow for compile time zero overhead gradients. The flexibility is actually the other way around, Julia's compiler allows these sort of compile time initiatives to be built in Julia rather than hacked into C++ like swift.
Regarding the duck typing vs type checking bit, that's a matter of tooling. It's much harder to replicate Julia's combination of speed and dynamism (for example to do flexible multistage programming) than to capitalize on Julia's the compile time information to build type checking (which are planned)
The compiler lag is going to be gone soon from two ends: more dynamic (interpreting code that doesn't need to be compiled, this is pretty much there already) and more static: Compiling and caching entire Julia programs. There are already fantastic improvements to this situation in 1.2
That leaves the error messages and stack traces, which ...well what's the last version you have tried? I find them to be ok, but they can and will be improved.
Regarding general purpose packages in Julia: check out http://genieframework.com/ as an example.
Julia's multimethods are awesome and a clear advantage over swift's methods. A protocol abstraction is similiar to julia's facility for traits, will at some point will be likely baked into the language (but even now allows for compile time resolution of methods just through multi dispatch abstraction , which again, is only one step away from building type check abstractions!).
If you want to know more about Julia's plans and philosophy in the regards, see: https://github.com/FluxML/Flux.jl/issues/614