@lvgl/mdx-lint
v0.2.1
Published
Three-pass MDX linter used by LVGL CI: @mdx-js/mdx syntax check, allowlist check against the Fumadocs + @lvgl/mdx-components registry, and per-component prop validation driven by zod schemas generated from the component source.
Downloads
718
Readme
@lvgl/mdx-lint
MDX linter for LVGL documentation contributors. Catches malformed MDX, unknown components, and misused component props before the Fumadocs build pipeline runs — so broken MDX never lands on the docs site.
This package is LVGL-specific. It ships with the component registry and prop schemas hardcoded to match the LVGL docs stack.
Writing docs
The canonical reference for LVGL's MDX writing conventions — which components exist, what props they take, and how to structure a page — lives at:
https://lvgl.io/docs/open/contributing/writing_docs
Every lint error links back to that guide.
Install
npm install --save-dev @lvgl/mdx-lint
# or
pnpm add -D @lvgl/mdx-lintRun
npx lvgl-mdx-lint "docs/**/*.{md,mdx}"CI (GitHub Actions):
- run: npx --yes @lvgl/mdx-lint@latest "docs/**/*.{md,mdx}" --reporter github--reporter github emits ::error file=…,line=…:: annotations so
failures surface inline on the PR diff.
CLI options
lvgl-mdx-lint [globs...] [--reporter <pretty|github|json>] [--fail-on-warning]Exit codes: 0 clean · 1 lint errors · 2 usage error.
What it checks
The linter runs three passes. Later passes are skipped on files that already have a fatal error from an earlier pass.
Syntax — unclosed JSX, malformed expressions, bad frontmatter, invalid GFM tables. Powered by
@mdx-js/mdx.Allowlist —
<Foo>tags andimportstatements are checked against the registry baked into this package. Anything that isn't a known component or an allowed module fails.Props — for every known component, the linter validates:
- Every attribute name is declared on the component.
- Every required attribute is present.
- Every literal-valued attribute matches the declared type (string, number, boolean, enum, array of primitives).
Expression-valued attributes (
foo={someVar}) count as "present" but their values are not inspected — the linter can't evaluate arbitrary JS.
Rule codes
| Rule | What it means | How to fix |
|---|---|---|
| mdx-lint:syntax | The MDX parser rejected your file. | Fix the formatting or syntax error at the reported line. |
| mdx-lint:unknown-component | A <JsxTag> in your file isn't a registered component. | Check the spelling. If you expected it to exist, run pnpm update @lvgl/mdx-lint. |
| mdx-lint:disallowed-import | An import statement points at a module the linter doesn't allow. | Use components via @lvgl/mdx-components rather than importing from source. |
| mdx-lint:unknown-prop | A prop on a JSX tag isn't declared on that component. | Check the spelling, or run pnpm update @lvgl/mdx-lint if you expect a newer prop. |
| mdx-lint:missing-required-prop | A required prop is missing from a JSX tag. | Add the prop. If the requirement is new to you, run pnpm update @lvgl/mdx-lint. |
| mdx-lint:invalid-prop-value | A prop value doesn't match the declared type. | See the writing guide for the correct values. |
Every error message includes a link to the writing guide: https://lvgl.io/docs/open/contributing/writing_docs
Inspecting the registry
To see what components and module prefixes the installed version allows:
npx lvgl-mdx-print-allowlist
# or JSON
npx lvgl-mdx-print-allowlist --format jsonLicense
MIT
