# Basic Package Extension Example

**URL:** <https://discourse.julialang.org/t/basic-package-extension-example/102969>\
**Category:** Tooling\
**Tags:** package-extensions\
**Created:** [August 18, 2023, 11:40pm UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969 "2023-08-18T23:40:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [August 18, 2023, 11:40pm UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969/1 "2023-08-18T23:40:41Z")

</div>

Hello,

I’m having some trouble getting a basic example of package extensions working. I might’ve missed it, but there is no “starting from zero” example of how to create package extensions in the docs [here](https://pkgdocs.julialang.org/v1/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)). So hopefully someone can help me understand how to do this properly.

I want to use package extensions to add CairoMakie plotting support for my simple package. Here is my simple package defined in `src/MyPackage.jl`.

```julia
module MyPackage

export MyObj

struct MyObj
    a::Vector{Float64}
    U::Float64
    L::Float64
end

end # module MyPackage

```

Now I want to add CairoMakie support by defining `lines()` for `MyObj`. So in `ext/` I create `PlotsExt.jl`.

```julia
module PlotsExt

using MyPackage, CairoMakie, LinearAlgebra

function CairoMakie.lines(obj::MyObj)
    n = length(obj.a)
    x = collect(LinRange(obj.L, obj.U, n))
    y = obj.a
    return fig, ax, ln = lines([x y])
end

end # module

```

I don’t think I am ready to start using this package yet though, right? I need to update the `Project.toml` file. I need to manually add the following

```julia
[extensions]
PlotsExt = "CairoMakie"

```

And so then my `Project.toml` looks like this.

```julia
name = "MyPackage"
uuid = "..."
authors = ...
version = "0.1.0"

[extensions]
PlotsExt = "CairoMakie"

```

At this point though I am unsure I’m done? I think I still need to add CairoMakie as a dependency. So then I do that and now my `Project.toml` looks like this

```julia
name = "MyPackage"
uuid = "..."
authors = ...
version = "0.1.0"

[deps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"

[extensions]
PlotsExt = "CairoMakie"

```

Hm, so the example in the link above says `weakdeps`. Am I supposed to manually change that or does Pkg do it? For now I’ll just do it myself.

```julia
name = "MyPackage"
uuid = "..."
authors = ...
version = "0.1.0"

[weakdeps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"

[extensions]
PlotsExt = "CairoMakie"

```

I go to my Example environment and add my local package.

```julia
Pkg.develop(path="MyPackage/")

```

I also add `CairoMakie`.

Finally I try to run the following example script.

```julia
using MyPackage

L = 10
M1 = MyObj([(x / L)^2 for x in 1:10], 1, 10)

using CairoMakie

tmp = lines(M1)

```

I get the following error

```julia
`Makie.convert_arguments` for the plot type Lines{Tuple{MyObj}} and its conversion trait PointBased() was unsuccessful.

```

Any hints on where I went wrong here? Or the proper workflow to utilize package extensions?

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [August 19, 2023, 8:40am UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969/2 "2023-08-19T08:40:36Z")

</div>

Try swapping the order of your `using` statements.

```julia
using CairoMakie
using MyPackage
Base.retry_load_extensions() # you might not need this
L = 10
M1 = MyObj([(x / L)^2 for x in 1:10], 1, 10)

tmp = lines(M1)

```

Also, if you try and resolve and precompile the project, you should see your `PlotsExt` precompiling if everything if it is detected properly.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [August 19, 2023, 9:20am UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969/3 "2023-08-19T09:20:56Z")

</div>

> [@TI36XPro](#):
>
> Hm, so the example in the link above says `weakdeps`. Am I supposed to manually change that or does Pkg do it? For now I’ll just do it myself.

AFAIU, yes, you have to do this manually. And I think the easiest way is the one you just used: use `Pkg.add` to add the `[deps]` line with the correct UUID, then manually edit the `Project.toml` file to move the relevant line to a (potentially new) `[weakdeps]` section.

> [@TI36XPro](#):
>
> I get the following error

This looks like everything works from the package extensions point of view, and the error comes from your implementation of `CairoMakie.lines(::MyObj)`… or am I mistaken? (In any case, this would be more clearly seen if you posted the entire error, including the backtrace)

  

A debugging hint that helped me when creating my first package extension is to (temporarily) define an ` __init__ ()` method in the extension to see whether/when it is loaded:

```julia
module PlotsExt

using MyPackage, CairoMakie, LinearAlgebra

# TODO: remove this once everything works!
__init__ () = println("Extension was loaded!")

function CairoMakie.lines(obj::MyObj)
   # [...]
end

end
```

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [August 19, 2023, 10:40am UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969/4 "2023-08-19T10:40:03Z")

</div>

For my own reference, I made a MWE because I had trouble figuring out package extensions from the documentation. Here is the [link](https://github.com/itsdfish/PackageExtensionsExample.jl) in case it is helpful for you or anyone who comes across this thread in the future.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [August 19, 2023, 11:31am UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969/5 "2023-08-19T11:31:08Z")

</div>

Moving `using CairoMakie` first was the trick.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [August 24, 2023, 3:20am UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969/6 "2023-08-24T03:20:50Z")

</div>

On second thought, I’m not sure why I would need `Base.retry_load_extensions()`. I was just watching the Juliacon [presentation](https://www.youtube.com/watch?v=vG6ZLhe9Hns&t=23594s) and the example shown has the weak dependency (`Gadfly`) being loaded _after_ the main package (`MyPkg`).

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [August 24, 2023, 4:56am UTC](https://discourse.julialang.org/t/basic-package-extension-example/102969/7 "2023-08-24T04:56:03Z")

</div>

I only use `Base.retry_load_extensions()` for debugging/development when I’ve `dev`’d my package, in case the package extension hasn’t been loaded. It shouldn’t need to used outside of development.

As for the order, I agree that the order in which the deps are loaded should not affect whether the package extension loads. I have only been testing using `dev` on my main package in which the order matters, so perhaps this is just a bug?
