Use when you write a Julia package
Scanned 9/12/2026
Install to Claude Code
npx -y skills add thedixitjain/the-mega-skill-library --skill developing-julia-package --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Developing Julia Package?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/thedixitjain-developing-julia-package)More formats (shields.io, HTML) on the badges page.
---
name: developing-julia-package
description: "Use when you write a Julia package"
category: general-purpose
source_repo: hashgraph-online/awesome-codex-plugins
source_path: "plugins/AtelierArith/atelier-arith-julia-development-skills/skills/developing-julia-package/SKILL.md"
source_url: https://github.com/hashgraph-online/awesome-codex-plugins/blob/HEAD/plugins/AtelierArith/atelier-arith-julia-development-skills/skills/developing-julia-package/SKILL.md
---
# Developing a Julia package
Notes on developing Julia packages.
Assume the package is named `MyPkg`. Substitute your actual package name wherever `MyPkg` appears.
Use `src/MyPkg.jl` as the package entry point. Keep the module declaration, exports, and `include` list there; put substantial implementation in focused files under `src/`.
```julia
module MyPkg
export fit_model, FitResult, GaussianModel
include("models.jl")
include("fit.jl")
include("preprocess.jl")
end
```
Split files to improve readability, not to recreate Python-style class or submodule hierarchies. Prefer one public module unless there is a real user-facing namespace boundary.
Guidelines below.
## Avoid excessive `export`s
- Do not `export` helpers that are only used internally just so tests can reach them. Prefer importing explicitly in tests:
```julia
# test/runtests.jl
using Test
using MyPkg: <internal-only helper>
```
Test public behavior through the public API first. Import internals only when the helper has meaningful behavior that is hard to exercise through the public path:
```julia
using Test
using MyPkg
using MyPkg: initial_guess
@testset "fit_model" begin
result = fit_model(x, y; model = GaussianModel())
@test result isa FitResult
end
@testset "initial_guess" begin
@test initial_guess(x, y, GaussianModel()) isa NamedTuple
end
```
## Julia-idiomatic style
### Multiple dispatch
Prefer splitting behavior across methods instead of a large `if`/`elseif` chain on `isa`, unlike typical Python style.
```julia
# Do not write if else end
function f(x)
if x isa Integer
return 2x
else
return x
end
end
```
Instead, use multiple dispatch:
```julia
f(x) = x # generic implementation
f(x::Integer) = 2x # specialized implementation for x::Integer
```
For package APIs, make the dispatch object explicit and keep symbol options as a thin compatibility layer if needed:
```julia
abstract type AbstractModel end
struct GaussianModel <: AbstractModel
baseline::Bool
end
GaussianModel(; baseline = true) = GaussianModel(baseline)
fit_model(x, y; model::AbstractModel = GaussianModel()) =
fit_model(model, x, y)
function fit_model(model::GaussianModel, x, y)
guess = initial_guess(x, y, model)
# gaussian-specific implementation
end
```
Use a marker or configuration struct for the model choice, and use a separate result struct for fitted values. Do not mutate a model type into a mixed "algorithm plus fitted state" object unless that is clearly the public contract.
```julia
struct FitResult{P,T}
params::P
residuals::Vector{T}
converged::Bool
end
```
This keeps `GaussianModel()` as the method-selection/configuration value and `FitResult` as the returned fitted state.
### Type annotations
- On **public** APIs, narrow signatures when it prevents misuse or clarifies the contract.
- Inside the package, avoid over-constraining types everywhere; leave room for the compiler and for generic code.
### Type stability
- On hot paths, avoid return types that vary unpredictably across inputs (type instability hurts specialization).
- Confirm bottlenecks with profiling before micro-optimizing.
## Code formatting (JuliaFormatter)
- Format package sources with **[JuliaFormatter.jl](https://github.com/domluna/JuliaFormatter.jl)** so layout and whitespace stay consistent across contributors and CI.
- Optionally commit a **`.JuliaFormatter.toml`** at the repository root (or rely on defaults) so everyone applies the same rules.
From the package root:
```julia
using JuliaFormatter
format(".") # formats src/, test/, etc. under the current directory
```
Run formatting before merging substantive edits; wire the same command into CI or pre-commit hooks if the team wants enforcement.
## Performance and allocations
- Measure with **`@benchmark` / `@btime`** from BenchmarkTools.jl rather than guessing.
- Watch unnecessary array copies from slicing and broadcasting; when an in-place API is needed, expose it explicitly (separate function name or keyword argument) so callers opt in.
## Errors and documentation
- Raise **`ArgumentError`**, **`DomainError`**, or other appropriate exceptions; messages should tell the caller what to fix.
- Give **docstrings** to exported/public functions—ordinary docstrings above definitions integrate cleanly with Documenter.jl; use `@doc` when you attach documentation programmatically.
---
**Source:** [`hashgraph-online/awesome-codex-plugins`](https://github.com/hashgraph-online/awesome-codex-plugins) → `plugins/AtelierArith/atelier-arith-julia-development-skills/skills/developing-julia-package/SKILL.md`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!