| name | julia-development |
| description | Expert guidance for Julia package development following SciML standards, Distributions.jl patterns, and Julia ecosystem best practices |
Julia Package Development
Use this skill when working with Julia packages to ensure proper development workflows, testing patterns, documentation standards, and performance best practices.
Development Workflow
Environment Management
# Start Julia with project environment
julia --project=.
# Activate project in REPL
using Pkg
Pkg.activate(".")
# Install dependencies
Pkg.instantiate()
# Update dependencies (PREFERRED over direct Project.toml editing)
Pkg.update()
# Add new dependency
Pkg.add("PackageName")
# Add development dependency
Pkg.add("PackageName"; io=devnull) # Then manually move to extras/test deps
# Check package status
Pkg.status()
IMPORTANT: Always use Pkg.update() to update packages.
Never edit Project.toml directly for version updates.
Testing
# Run all tests (from project root)
julia --project=. -e 'using Pkg; Pkg.test()'
# Run tests with test environment
julia --project=test test/runtests.jl
# Run tests skipping quality checks (if supported)
julia --project=test test/runtests.jl skip_quality
Test Organization:
- Use
TestItemRunnerwith@testitemsyntax for modular testing - Organize tests by component:
test/component/,test/package/ - Package-level tests in
test/package/for quality (Aqua, DocTest, formatting) - Use
@testitem "description" begin ... endfor individual test items
Example test structure:
using TestItemRunner
@testitem "Basic functionality" begin
using MyPackage
@test my_function(1) == 2
end
@testitem "Edge cases" begin
using MyPackage
@test_throws ArgumentError my_function(-1)
end
Documentation
# Build documentation locally
julia --project=docs docs/make.jl
# Build docs skipping notebooks (faster)
julia --project=docs docs/make.jl --skip-notebooks
# or via environment variable
SKIP_NOTEBOOKS=true julia --project=docs docs/make.jl
# Start Pluto server for interactive notebooks
# (check project-specific task or command)
Documentation Structure:
- Use Documenter.jl for documentation
- Auto-deployment to GitHub Pages via CI
- Structure defined in
docs/pages.jlordocs/make.jl
Code Quality
# Run pre-commit hooks
pre-commit run --all-files
# JuliaFormatter (typically configured in .JuliaFormatter.toml)
# Usually handled by pre-commit hooks
Quality Checks:
- Aqua.jl tests for package quality
- JuliaFormatter.jl for code formatting
- Pre-commit hooks for automated checks
Code Style Guidelines
SciML Coding Standards
Follow SciML (Scientific Machine Learning) coding standards:
- Avoid type instability
- Ensure efficient precompilation
- Use appropriate type annotations for performance
- Write type-stable code
Type Stability:
# Good - type stable
function compute(x::Float64)
result = 0.0 # Type is known
for i in 1:10
result += x * i
end
return result
end
# Avoid - type unstable
function compute_bad(x)
result = 0 # Type might change
for i in 1:10
result = result + x * i # Type may vary
end
return result
end
Formatting Rules
- Max 80 characters per line
- No trailing whitespace
- No spurious blank lines
- Use JuliaFormatter.jl for consistent formatting
Documentation Standards
Docstring Syntax
Use @doc with either raw strings or regular strings:
# For simple docstrings without LaTeX or templates
@doc "
Brief description of the function.
# Arguments
- `x`: Description of x
- `y`: Description of y
# Returns
- Description of return value
# Examples
```jldoctest
julia> my_function(1, 2)
3
" function my_function(x, y) return x + y end
For docstrings with LaTeX math
@doc raw" Computes the mathematical function:
f(x) = \int_0^x t^2 dt
Use raw strings when including LaTeX to preserve backslashes. " function math_function(x) # implementation end
### DocStringExtensions Templates
**IMPORTANT**: Template expansion rules:
- Use `@doc "` (regular string) for templates (allows expansion)
- Use `@doc """` with escaped backslashes when combining templates with LaTeX
- **NEVER** use `@doc raw"` with templates (prevents expansion)
```julia
using DocStringExtensions
# Good - template will expand
@doc "
$(TYPEDSIGNATURES)
Brief description.
# Fields
$(TYPEDFIELDS)
"
struct MyType
"Field description"
field::Int
end
# Good - template + LaTeX with escaped backslashes
@doc """
\$(TYPEDSIGNATURES)
Computes: ``f(x) = \\int_0^x t^2 dt``
Note the escaped backslashes in LaTeX: \\int, not \int
"""
function combined_function(x)
# implementation
end
# Avoid - raw string prevents template expansion
@doc raw"
$(TYPEDSIGNATURES) # This will NOT expand!
"
Documentation Structure Best Practices
- Keep interface method docstrings concise (1-2 lines)
- Use "See also" sections for cross-references
- Avoid duplication between related functions (pdf/logpdf, cdf/logcdf)
- Include mathematical formulations in main type/constructor docstrings
- Provide minimal but sufficient examples using
@exampleblocks
Cross-referencing:
@doc "
Compute the cumulative distribution function.
See also: [`logcdf`](@ref)
"
function cdf(d::MyDist, x::Real)
# implementation
end
@doc "
Compute the log cumulative distribution function.
See also: [`cdf`](@ref)
"
function logcdf(d::MyDist, x::Real)
# implementation
end
Package Structure
Typical Julia package structure:
MyPackage.jl/
├── src/
│ ├── MyPackage.jl # Main module file with exports
│ ├── component1.jl # Component implementations
│ ├── component2.jl
│ ├── docstrings.jl # DocStringExtensions templates
│ └── utils/
├── test/
│ ├── runtests.jl # Main test file
│ ├── component1/ # Tests by component
│ ├── component2/
│ └── package/ # Quality tests (Aqua, formatting)
├── docs/
│ ├── make.jl # Documentation build script
│ ├── src/ # Documentation source
│ └── pages.jl # Page structure (optional)
├── Project.toml # Package dependencies
└── README.md
Performance Best Practices
Type Stability
# Check type stability with @code_warntype
@code_warntype my_function(args...)
# Look for red (Any) types - indicates type instability
Precompilation
# Ensure efficient precompilation
# Use PrecompileTools.jl for complex packages
using PrecompileTools
@compile_workload begin
# Representative workload for precompilation
my_function(example_args...)
end
Performance Patterns
- Use in-place operations when possible (
!suffix convention) - Preallocate arrays for loops
- Use
@simd,@inboundswhen safe - Consider
StaticArrays.jlfor small fixed-size arrays - Profile with
@time,@benchmark(BenchmarkTools.jl)
Common Dependencies and Patterns
Distributions.jl Interface
When implementing distributions:
- Implement required methods:
pdf,logpdf,cdf,logcdf,quantile,rand - Implement support methods:
minimum,maximum,insupport - Optionally implement:
mean,var,std(if analytically tractable) - Vectorization handled automatically via broadcasting
- Consider specialized batch methods:
pdf!,logpdf!,cdf!
Turing.jl and AD Compatibility
Ensure compatibility with automatic differentiation:
- ForwardDiff.jl
- ReverseDiff.jl
- Zygote.jl
- Enzyme.jl
Avoid non-differentiable operations in AD-sensitive code.
Common Julia Ecosystem Tools
- Pkg: Package management
- TestItemRunner: Modern testing framework
- Documenter.jl: Documentation generation
- DocStringExtensions: Documentation templates
- JuliaFormatter.jl: Code formatting
- Aqua.jl: Package quality testing
- BenchmarkTools.jl: Performance benchmarking
- PrecompileTools.jl: Precompilation optimization
When to Use This Skill
Activate this skill when:
- Developing Julia packages
- Writing Julia tests
- Documenting Julia functions
- Setting up Julia package infrastructure
- Working with Distributions.jl, Turing.jl, or SciML packages
- Optimising Julia code performance
This skill provides Julia-specific development patterns. Project-specific architecture and domain knowledge should remain in project CLAUDE.md files.