Skip to content

Add documentation for 16.0 usermod system#312

Open
willmmiles wants to merge 5 commits intomainfrom
16-usermod-docs
Open

Add documentation for 16.0 usermod system#312
willmmiles wants to merge 5 commits intomainfrom
16-usermod-docs

Conversation

@willmmiles
Copy link
Copy Markdown
Member

@willmmiles willmmiles commented May 3, 2026

Update the documentation to provide details on the 16.0 usermod system, and add a new page to collect links to available external usermods.

Includes a number of small correctness fixes to the "custom features" page to bring the documentation in line with the current sources.

Summary by CodeRabbit

  • Documentation
    • Added a community-maintained usermods index with submission guidelines.
    • Added instructions for enabling custom usermods in PlatformIO builds.
    • Rewrote custom-features guide for v2 class-based usermods: registration, lifecycle hooks, persistence, custom-effect guidance, and Web UI build/regeneration steps.
    • Updated site navigation to include the Community Usermods page.

willmmiles and others added 4 commits May 2, 2026 20:11
Also clean up other small details in the Custom Features page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adding new fx by usermod is the best way forward -- we don't want to
confuse people by suggesting two different approaches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a place for showing off external usermod contributions!

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 3, 2026

Walkthrough

Adds and restructures documentation for WLED usermods: a rewritten custom-features guide describing v2 class-based usermods, a compiling-wled subsection for custom_usermods, a new community-maintained usermods index page, and a nav entry in mkdocs.yml.

Changes

Usermod docs, compilation, and site navigation

Layer / File(s) Summary
Core usermod guide (rewrite)
docs/advanced/custom-features.md
Rewrites guide to document v2 class-based usermods (REGISTER_USERMOD()), lifecycle hooks, persistence (addToConfig/readFromConfig), custom-effect patterns (user_fx, strip.addEffect()), legacy v1 notes, direct-modification workflow using colorUpdated(CALL_MODE_...), and Node-based Web UI regeneration steps.
Compilation wiring
docs/advanced/compiling-wled.md
Adds "Adding usermods" subsection documenting custom_usermods in platformio_override.ini, example extends env, and that listed names map to folders under usermods/ which self-register at compile time.
Community index (new content)
docs/advanced/community-usermods.md
New community-maintained index page with contribution instructions (required markdown table-row format), allowed platform tags (esp32, esp8266, both), and two initial entries (wled-usermod-example, user_fx) including links, author handles, platforms, and notes.
Site navigation
mkdocs.yml
Adds Community Usermods: advanced/community-usermods.md to the Advanced nav section.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • netmindz
  • DedeHai

Poem

🐰 I hopped through docs with a twitch and a cheer,
New usermods listed for far and for near.
Register, build, and extend with delight—
Community glow in the soft evening light.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: it adds documentation for the 16.0 usermod system across multiple files (community-usermods.md, compiling-wled.md, custom-features.md, and mkdocs.yml).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/advanced/community-usermods.md`:
- Around line 15-17: The fenced code block containing the example table is
missing a language identifier which triggers MD040; update the opening fence for
that snippet (the triple backticks before the table row that includes
"[Name](https://github.com/you/your-usermod) | Short description | `@yourname` |
esp32 |  |") to use a language tag (e.g., ```markdown) so the block is correctly
recognized as Markdown.

In `@docs/advanced/custom-features.md`:
- Around line 58-64: Add a language identifier to the fenced code block
containing the directory tree (the triple-backtick block showing "~/projects/ 
WLED/  my-wled-usermod/ ...") by changing the opening fence from ``` to ```text
(or ```plaintext) so the markdownlint MD040 rule is satisfied and the snippet is
treated as plain text.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 61c1db3a-0fb2-430f-88bb-87f7e4ae61f5

📥 Commits

Reviewing files that changed from the base of the PR and between b31475d and 0bd576d.

📒 Files selected for processing (4)
  • docs/advanced/community-usermods.md
  • docs/advanced/compiling-wled.md
  • docs/advanced/custom-features.md
  • mkdocs.yml

Comment thread docs/advanced/community-usermods.md Outdated
Comment thread docs/advanced/custom-features.md Outdated
Comment thread docs/advanced/custom-features.md Outdated
```cpp
long lastTime = 0;
int delayMs = 2000; //we want to do something every 2 seconds
Each line is a usermod name corresponding to a folder under `usermods/` (or a short alias — see the folder for exact names). Restart the PlatformIO build and the usermods are automatically included, no other file edits needed.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should mention the actual name is defined in the json file

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. Maybe I should update load_usermods.py to scan library names for in-tree usermods instead of just accepting folder names. It'd be a little more work to index the folder, but it'd get rid of all the usermod_v2 handling crap.

Comment thread docs/advanced/custom-features.md Outdated
Writing effects as usermods is the recommended way to add new LED effects to a WLED build — no core source files need changing, and the effect can live in its own repository and be shared like any other usermod.

Here is a step-by-step guide on how to make your effect:
The `user_fx` usermod (`usermods/user_fx`) is the mainline example of this pattern and a convenient starting point. It bundles multiple effects in a single usermod and can be enabled with `custom_usermods = user_fx`. Fork it or use it as a template for your own effects usermod.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also mention it has a readme explaining in detail how to write WLED effects

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

Should we pull user_fx out to a separate example repo?

Pro - easy to fork for people who just want to add a new effect
Con - harder to keep in sync with core code, should the API change. Could play games with git submodules but that creates its own frictions

Copy link
Copy Markdown
Collaborator

@DedeHai DedeHai May 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep it as it is, if a user wants to invest the time to write user FX, deleting the existing ones and renaming a few things is the least of the work. I personally do not like "examples" that only give you one single easy case, using the existing user effects as a look-up on how to do things is a good thing.
You could mention the other example we have: PS meteor or something, a UM with a single FX.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I wasn't suggesting changing the code in user_fx - I agree that having many examples is good. The question is where is the best place to keep that code, either in-tree or out-of-tree.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I get it now, I would keep it in the WLED repo, at least for the time being: it is a collection of FX that others may find useful to have compiled in. Having an example repo to fork for OOT is a good idea though.

@DedeHai
Copy link
Copy Markdown
Collaborator

DedeHai commented May 4, 2026

good writeup

Comment thread docs/advanced/compiling-wled.md Outdated
To include one or more usermods in your build, add a `custom_usermods` line to your environment in `platformio_override.ini`:

```ini
[env:esp32dev]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely you need a new name if you are trying to extend env:esp32dev rather than override?

Comment thread docs/advanced/custom-features.md Outdated

### Timing
```ini
[env:esp32dev]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New name

The forked example file contains a fully annotated version of this covering persistent settings (`addToConfig` / `readFromConfig`), JSON state, MQTT, and more.


#### Useful lifecycle methods
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the new UDP reception?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also how to add pallets @DedeHai

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point about the palettes, I will add that after this is merged in

@softhack007
Copy link
Copy Markdown
Member

softhack007 commented May 4, 2026

About the muddy waters of licenses - I think we should add a statement somewhere about what EUPL-1.2 expects.

The case for in-tree seems clear: EUPL-1.2.
For out-of-tree, I think that "share-alike" applies. It means that an out-of-tree UM needs to be open-sourced (if not "strictly private"), and published under a compatible "strong copyleft" license. Reason: UMs are "derivative work", UMs can only be installed by creating a binary that includes the WLED core.

@netmindz
Copy link
Copy Markdown
Member

netmindz commented May 4, 2026

About the muddy waters of licenses - I think we should add a statement somewhere about what EUPL-1.2 expects.

The case for in-tree seems clear: EUPL-1.2. For out-of-tree, I think that "share-alike" applies. It means that an out-of-tree UM needs to be open-sourced (if not "strictly private"), and published under a compatible "strong copyleft" license. Reason: UMs are "derivative work", UMs can only be installed by creating a binary that includes the WLED core.

EUPL-1.2 and Library Licensing
Short answer: the library itself does not have to be EUPL-1.2 licensed, but there are practical constraints depending on how it's distributed and combined.
Key points

  1. The EUPL is a copyleft licence (Article 5)
    If you distribute a "Derivative Work" of EUPL-licensed code, that derivative must be licensed under the EUPL (or a compatible licence). The question is whether your library counts as a derivative work.
  2. "Mere aggregation" / linking
    The EUPL doesn't explicitly resolve the static-vs-dynamic linking debate, but generally:
  • A library that is independently authored (not derived from EUPL source code) is its own work.
  • Combining/linking it with an EUPL application at install or runtime is typically considered aggregation, not derivation.
  • So your independent library can be released under any licence you choose — MIT, Apache-2.0, BSD, proprietary, GPL, etc.
  1. If the library contains code copied/adapted from an EUPL work
    Then it is a derivative and must be EUPL-1.2 or a compatible licence listed in the EUPL Appendix (https://joinup.ec.europa.eu/collection/eupl/matrix-eupl-compatible-open-source-licences):
  • GPL-2.0/3.0, AGPL-3.0, LGPL-2.1/3.0
  • MPL-2.0, EPL-1.0
  • CeCILL-2.0/2.1, OSL-2.1/3.0
  • CPL, Apache-2.0 (added in EUPL-1.2)
  • LiLiQ-R/R+
  1. The "only usable with EUPL app" framing doesn't matter legally
    Technical dependency ≠ derivative work under copyright. What matters is whether the library's source code incorporates EUPL-licensed code.

@willmmiles
Copy link
Copy Markdown
Member Author

About the muddy waters of licenses - I think we should add a statement somewhere about what EUPL-1.2 expects.
The case for in-tree seems clear: EUPL-1.2. For out-of-tree, I think that "share-alike" applies. It means that an out-of-tree UM needs to be open-sourced (if not "strictly private"), and published under a compatible "strong copyleft" license. Reason: UMs are "derivative work", UMs can only be installed by creating a binary that includes the WLED core.

EUPL-1.2 and Library Licensing Short answer: the library itself does not have to be EUPL-1.2 licensed, but there are practical constraints depending on how it's distributed and combined.

That was my understanding as well: copyleft license clauses add requirements to distributing the binaries (or products containing the binaries), but as long as you don't share anything containing the build products with anyone else, you haven't broken any terms of the license -- even if your usermod is proprietary. Library components such as usermods are usually themselves individual works and can have their own licenses, it's only the linked binary that constitutes a derivative work.

@softhack007
Copy link
Copy Markdown
Member

@willmmiles @netmindz good points, thanks. I'm not sure if we should just keep the new docs strictly technical (nothing about open source or not), or maybe add a minimal statement "for orientation"? Need to sleep over it 😴.

What's your preference?

coderabbitai[bot]

This comment was marked as outdated.

@willmmiles
Copy link
Copy Markdown
Member Author

@willmmiles @netmindz good points, thanks. I'm not sure if we should just keep the new docs strictly technical (nothing about open source or not), or maybe add a minimal statement "for orientation"? Need to sleep over it 😴.

What's your preference?

I'd say "that's out of scope for this PR" ;) Licensing of user customizations isn't a new issue to the 16.0 usermod system. There's no legal difference between linking an out-of-tree repo vs. forking the base and adding your own in-tree folders. In both cases you can license the new code you wrote however you want; our license applies only to our code and the build products.

That said, a PR on top of this one that adds some encouragement for open source licensing is a good idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants