# Automatically load extension if available

**URL:** <https://discourse.julialang.org/t/automatically-load-extension-if-available/116980>\
**Category:** General Usage\
**Tags:** question, package\
**Created:** [July 12, 2024, 7:37pm UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980 "2024-07-12T19:37:17Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bclyons12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bclyons12/32/33734_2.png) [@bclyons12](https://discourse.julialang.org/u/bclyons12)\
**Post date:** [July 12, 2024, 7:37pm UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980/1 "2024-07-12T19:37:17Z")

</div>

Suppose I have MyPkg which has as an extension MyExt. I basically always want MyPkg to use MyExt if that package is available in the environment. Is there a way to automate it so that `import MyPkg` always does `import MyPkg, MyExt` if MyExt is available?

Better yet, I don’t even want `MyExt` in the upper level namespace, so someway that this would happen internal to MyPkg would be even better. Basically it would activate the extension not if MyExt is loaded but if MyExt is available in the environment and MyPkg is loaded.

The best solution I’ve found so far would be to make a separate module, something like:

```julia
module MyPkg_Ext
using Reexport
@reexport using MyPkg
import MyExt
end

```

Then I could do `import MyPkgExt as MyPkg`, but that’s kind of clunky.

---

<div class="post-metadata">

**Author:** ![bclyons12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bclyons12/32/33734_2.png) [@bclyons12](https://discourse.julialang.org/u/bclyons12)\
**Post date:** [July 12, 2024, 8:32pm UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980/2 "2024-07-12T20:32:26Z")

</div>

This is similar to the idea here, but I don’t see this particular point resolved in the thread.

> [@Are extension packages importable?](https://discourse.julialang.org/t/are-extension-packages-importable/92527/5):
>
> To be concrete, suppose the package Foo has an extension Ext which depends on Bar and Baz. Then it may be nice to let pkg\> add Foo[Ext] be a shorthand for pkg\> add Foo, Bar, Baz (thus allowing the fact that Ext depends on Bar and Baz to be an implementation detail). And further, it may be nice to let import Foo[Ext] be a shorthand for import Foo, Bar, Baz const Ext = Base.get\_extension(Foo, :Ext)

I wouldn’t need the actual Ext extension module exposed to the REPL, just a shorthand to load the necessary packages.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 12, 2024, 9:33pm UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980/3 "2024-07-12T21:33:41Z")

</div>

> [@bclyons12](#):
>
> import MyPkg, MyExt

This part is impossible, extensions aren’t intended to be exposed namespaces, that’s what packages are for.

I don’t understand why this is an extension to begin with, I might be misreading this. If MyExt is attached to your package MyPkg like extensions are, but you want MyExt to be loaded solely based on MyPkg being imported, why isn’t MyExt just part of MyPkg? It can be a submodule if you need the separate namespace.

---

<div class="post-metadata">

**Author:** ![bclyons12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bclyons12/32/33734_2.png) [@bclyons12](https://discourse.julialang.org/u/bclyons12)\
**Post date:** [July 12, 2024, 9:46pm UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980/4 "2024-07-12T21:46:54Z")

</div>

Here I meant MyExt to be the package that is loaded that causes the internal extension module to get loaded. Let me use rewrite the example based on [Code Loading · The Julia Language](https://docs.julialang.org/en/v1/manual/code-loading/#man-extensions)

So in my case I’d have a Project.toml for MyPackage that looks like:

```julia
name = "MyPackage"

[weakdeps]
ExtDep = "..." # uuid

[extensions]
FooExt = "ExtDep"

```

If I have an environment MyEnv with a Project.toml that looks like:

```julia
[deps]
MyPackage = "..." # uuid
ExtDep = "..." # uuid

```

and I do

```julia
julia> import Pkg; Pkg.activate("MyEnv")
julia> import MyPackage

```

I would like the FooExt extension in MyPackage activated because ExtDep is in the environment without having to explicitly load ExtDep into the REPL.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 12, 2024, 9:58pm UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980/5 "2024-07-12T21:58:18Z")

</div>

That’s clearer, thanks, I was thrown off because the trailing `Ext` is the convention for the extension itself, not the extension dependencies.

> [@bclyons12](#):
>
> I would like the FooExt extension in MyPackage activated because ExtDep is in the environment without having to explicitly load ExtDep into the REPL.

This isn’t done because it’s not sound design. If `ExtDep` isn’t a mandatory dependency of, or in other words imported by, `MyPackage`, then you are asserting you can import `ExtDep` on its own or `MyPackage` on its own in a Julia process, and it follows that loading `FooExt` depends on you explicitly importing both.  
Instead of unexpected deviations from that rule, the existing way to do what you want is to make `MyPackage` import `ExtDep`. `FooExt` only depends on `MyPackage`’s import and thus doesn’t even need to be an extension, it can just be part of `MyPackage` after `ExtDep`’s import. Extensions are a cool and relatively new feature but it doesn’t redundantly supplant established features.

---

<div class="post-metadata">

**Author:** ![bclyons12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bclyons12/32/33734_2.png) [@bclyons12](https://discourse.julialang.org/u/bclyons12)\
**Post date:** [July 12, 2024, 10:36pm UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980/6 "2024-07-12T22:36:06Z")

</div>

Okay thank you. The idea here is that `MyPackage` is public but `ExtDep` is a private package. `MyPackage` works fine without `ExtDep`, but if `ExtDep` is available it unlocks a bunch of features in `MyPackage`. Thus, if a person has it available in an environment (i.e., they have permission to use `ExtDep`), it would be great for it to get loaded and used by `MyPackage` as smoothly as possible. It’s analogous to `MyPackage` being the free version of a software and `ExtDep` being a plugin that you pay for. If a user has paid for `ExtDep`, you’d like `MyPackage` to see and to use that seamlessly.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 13, 2024, 12:26am UTC](https://discourse.julialang.org/t/automatically-load-extension-if-available/116980/7 "2024-07-13T00:26:40Z")

</div>

> [@bclyons12](#):
>
> `MyPackage` works fine without `ExtDep`, but if `ExtDep` is available it unlocks a bunch of features in `MyPackage`. Thus, if a person has it available in an environment (i.e., they have permission to use `ExtDep`), it would be great for it to get loaded and used by `MyPackage` as smoothly as possible.

You’re trying to make the environment itself designate what code is loaded by a package’s import, and that is not at all what extensions are designed for nor is it sound design. Emphasizing that packages aren’t just low-level code caches but also high-level namespaces in an interactive runtime, where would `ExtDep` go? Is it loaded to the same parent module I’m importing `MyPackage` into, as if I ran `using MyPackage, ExtDep`, or inside the `MyPackage` module itself as if it were a true dependency? It may seem obvious to you, but people can reasonably expect the implicit behavior to be either, or even something else entirely. Either way, how would you resolve conflicts of the name `ExtDep` and possibly its exported names with separate names belonging to the parent module or `MyPackage`? You could deliberately avoid those names in `MyPackage` yourself as the developer, but users can’t be expected to do the same in their parent modules. As you already intuited, you can best control names by making a 3rd reexporting package for users to add instead, but even those few lines seem like an unsatisfactory amount of work to trim an import statement, doesn’t it? Hence your search for something automatic.

Not that those namespace issues have a satisfying automatic solution, but even if it could be designed, it shouldn’t. On a practical level, what if I _want_ to add `MyPackage` and `ExtDep` to my environment yet import them completely independently, possibly in different sessions or in different modules within the same session? This would not only take that choice from me, it would scale poorly to more independent packages forcing each other’s imports in an opaque indefinite web across the ecosystem (package A forces B, B forces C, etc), vastly increasing load times for code I didn’t even need in a given session. This is only preventable when 1 isolated import has 1 behavior no matter the state of the environment; extensions don’t have this propagating issue because they’re only triggered by 1 fixed set of packages, not other extensions. This isn’t the first time someone wanted extensions to behave like automatically loaded packages, but that’s not what they are, and despite a couple similarities, they lack many aspects of packages to keep programming sane; extensions are really just extensions for packages, not alternatives.
