Contributing to JuliaFEM.jl
May 10, 2026 · View on GitHub
Thank you for considering a contribution. Please read AGENTS.md in the
repository root before opening a pull request; it describes the current
architecture, the non-negotiable invariants (zero-allocation hot paths,
type stability, mirrored test/src layout) and the documentation style.
Quick start
-
Fork and clone the repository.
-
Create a topic branch from
main. -
Make your change, keeping it small enough to review.
-
Run the full test suite from the repository root:
julia --project=. -e 'using Pkg; Pkg.test()' -
Respect the layer dependency contract in
docs/src/developer/architecture_layers.md. CI runsjulia scripts/check_layer_contract.jl; run it locally before pushing if you touchsrc/domains/or foundation directories (topology,quadrature,geometry,basis,sparse). -
Open a pull request with a clear description of the change and any relevant benchmark or test output.
Time to first success
From a clean clone of JuliaFEM.jl, expect roughly this order:
julia --project=. -e 'using Pkg; Pkg.instantiate()'— resolve dependencies.julia --project=. -e 'using Pkg; Pkg.test()'— full bundled suite (same command CI uses for the package tests).- Optional checks from the repository root:
julia scripts/check_layer_contract.jl— static layer dependency audit (same as CI).
- Optional documentation smoke tests from the repository root:
julia --project=. scripts/verify_docs_quickstart.jl— keeps the Documenter minimal elasticity snippet aligned with the mesh indocs/src/snippets/minimal_elasticity_quickstart.jl.cd juliafem.github.io && julia scripts/check_website_docs.jl— curated site Markdown links and patterns.
- Package API HTML (when editing
docs/src/):
julia --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
thenjulia --project=docs docs/make.jlfrom the repository root.
If any of these fail before you touch application code, fix the environment
(Julia version versus [compat], stale Manifest.toml, or missing Quarto
when rendering the website) rather than chasing false positives in the library.
Coding rules worth highlighting
- Use ASCII identifiers in code (
u,v,wfor reference coordinates, notxi,eta,zetaor Greek letters). Greek may appear in comments and docstrings where it aids reading. - Hot paths must remain zero-allocation. The regression for this lives
in
test/assemblers/test_dof_based_zero_alloc.jl. New code that touches the assembly path should not addDict,Vector{Any}, untyped closures or growable buffers inside loops. - Tests for
src/<topic>/<feature>.jlgo totest/<topic>/test_<feature>.jl. - Prefer one file per commit; two paths is fine when they are one story
(e.g. implementation + its test). Never
git add .orgit add -Aunless you mean it. The full protocol is in.github/prompts/commit.prompt.md. Withgit config core.hooksPath .githooks, pre-commit allows at most two staged files per commit, and commit-msg enforces the subject / summary / bullet layout plus an 80-character line cap (merge commits skip while.git/MERGE_HEADexists). - Match commit message depth to the patch: a short summary suffices for small edits; large files, large diffs, or several concerns in one commit should add grouped bullets (major API or behavior, wiring, migrations, caveats) so history stays readable without re-walking every hunk.
SPDX file headers
SPDX tags belong at the top of new files when the rest of the tree uses them,
but they must always sit inside comment syntax that matches the file type.
Never paste raw SPDX-* lines into prose formats where they would render as
visible text or break the format.
-
Julia (
.jl), shell, Python, and other#line-comment languages:# SPDX-FileCopyrightText: 2015-2026 Jukka Aho # SPDX-License-Identifier: MIT -
TOML, INI-style configs, and similar
#comment formats: same#lines as above. -
Markdown, Quarto (
.md,.qmd), and other HTML-friendly prose: wrap the tags in an HTML comment so renderers hide them:<!-- SPDX-FileCopyrightText: 2015-2026 Jukka Aho SPDX-License-Identifier: MIT -->
Formats that genuinely lack comments (for example strict JSON) cannot carry an in-file SPDX block; keep licensing in repository-level files or omit an in-file tag rather than emitting invalid syntax.
Documentation pull requests
When you change user-facing prose (Quarto juliafem.github.io/docs/, examples
index, book landing pages) or docstrings that feed the site API page:
- From
juliafem.github.io/, run
julia scripts/check_website_docs.jl
(denylist + relative Markdown /book/index.qmdchapter targets). - If you edited JuliaFEM docstrings or
docs/api/sources used by the site builder, run
julia --project=. scripts/build_docs.jl api
fromjuliafem.github.io/and commit the regeneratedapi/output if your project tracks it. - Add or adjust
juliafem.github.io/docs/documentation-map.mdwhen you introduce a new top-level guide readers should trust. - For package-only Documenter (
docs/make.jl), use thedocs/environment:
julia --project=docs -e 'using Pkg; Pkg.instantiate()'then
julia --project=docs docs/make.jlfrom the repository root (seedocs/README.md).
Documentation style
When writing READMEs, docstrings, design notes or session logs:
- No emoji.
- No markdown bold for emphasis. Plain prose carries enough weight.
- Prefer short, technical sentences and precise code references over marketing copy.
Where things go
src/repository_layout.md is the
authoritative file organisation guide and contains a decision tree for
any new file. A short pointer lives at repository_layout.md.
In particular, local session logs and scratch notes often live under a
gitignored llm/ tree, not under docs/ or test/.
Website and Quarto CI
The juliafem.github.io/ tree is a Quarto site checked by
.github/workflows/SiteDocs.yml. Visual tokens and navbar/logo rules live in
juliafem.github.io/docs/contributor-guide/design_system.md. After changing
site Markdown or book landing links, run from juliafem.github.io:
julia --project=. scripts/build_docs.jl api
julia scripts/check_website_docs.jl
A full local site build is quarto render from juliafem.github.io/. It fails
if two inputs share the same HTML stem (for example paired Literate *.md and
*.qmd, or Documenter api/index.md next to api/index.qmd); build_docs.jl
removes those duplicates after regenerating API and examples.
If you change default_quadrature or quadrature tables under src/quadrature/,
regenerate the user-guide table snippet from the repository root and commit
the updated file:
julia --project=. juliafem.github.io/scripts/generate_quadrature_defaults_snippet.jl
git diff juliafem.github.io/docs/user-guide/_quadrature_defaults_snippet.md
SiteDocs.yml runs that generator and fails the job when the snippet is out
of date (git diff --exit-code on the snippet path). The same workflow runs
scripts/check_curated_doc_vocabulary.jl, which fails if obsolete API
strings appear under juliafem.github.io/docs/user-guide/ (for example
register_fields!).
check_website_docs.jl enforces a small denylist of obsolete example patterns,
scans relative *.md / *.qmd links under docs/, examples/, showcase/, and
articles/, and verifies that chapter links in book/index.qmd resolve to
real .qmd files.
Getting help
- Open a GitHub issue with a minimal reproducible example for bugs.
- Open a GitHub discussion or issue for design questions before doing large pieces of work.