Contributing to MaplibreX

Copy Markdown View Source

Thanks for taking the time to contribute. Bug reports, documentation fixes and pull requests are all welcome.

Getting set up

git clone https://github.com/CountlinkX-Solutions/maplibrex.git
cd maplibrex
mix setup      # fetches Elixir deps and runs npm install in assets/
mix test       # should print "405 tests, 0 failures"

You need Elixir 1.15+, Erlang/OTP 26+ and Node 18+.

Before you open a pull request

mix ci         # format check, warnings-as-errors, credo --strict, tests
mix typecheck  # tsc --noEmit over the TypeScript hooks

Both must pass. CI runs the same commands.

Working on a component

A MaplibreX component is two halves that have to agree:

  1. The Elixir component in lib/maplibrex/components/. It validates its attributes, serialises a config map to JSON, and renders a <div> carrying phx-hook and data-config.
  2. The TypeScript hook in assets/js/maplibrex/hooks/. It reads data-config, talks to MapLibre GL JS, and implements mounted, updated and destroyed.

When adding one, please also:

  • Register it in lib/maplibrex/components.ex and assets/js/maplibrex/hooks/index.ts
  • Export its hook from assets/js/maplibrex.ts
  • Add it to the right group in docs/ in mix.exs
  • Write tests in test/maplibrex/components/ — cover the rendered output, attribute validation and edge cases
  • Document attributes, events and at least one example in the @moduledoc
  • Add a CHANGELOG entry under ## [Unreleased]

The committed bundle

priv/static/assets/js/maplibrex.js is a build artifact that is checked in on purpose. Applications that depend on MaplibreX through git have no build step for it, so the file has to exist in the repository — the same reason phoenix and phoenix_live_view commit theirs.

If you touch anything under assets/js/, rebuild it and commit the result:

mix assets.deploy

CI fails if you forget.

Conventions

  • Language: all code, comments, documentation and commit messages are in English.
  • Naming: Elixir attributes are snake_case; they are converted to MapLibre's camelCase when building the config map.
  • Cleanup: every hook must remove its layers, sources, listeners and controls in destroyed. Leaks show up immediately under LiveView navigation.
  • Logging: use logger.debug from core/logger for lifecycle output — it is silent unless debugging is enabled. Reserve console.warn/console.error for genuine problems.
  • No new bundled dependencies: anything large enough to matter belongs in peerDependencies and gets marked external in config/config.exs.

Commit messages

Conventional Commits, e.g. feat: add ContourLayer component, fix(marker): clear drag listeners on destroy, docs: ....

Reporting bugs

Please include your Elixir, LiveView, MapLibre GL and MaplibreX versions, a minimal LiveView that reproduces the issue, and anything the browser console printed with window.__MAPLIBREX_DEBUG__ = true.

Code of conduct

This project follows the Contributor Covenant.