Migrating from markdownlint
crackdown ships a built-in migration tool that reads your .markdownlintrc and generates a ready-to-use crackdown.config.ts with all supported rules pre-wired.
Automatic migration
crackdown migrate .markdownlintrcThis command:
- Reads your existing config file.
- Maps each enabled rule to its crackdown equivalent.
- Writes
crackdown.config.tsalongside the config file. - Prints a report with
✓ supportedand✗ unsupportedrules.
Rule mapping reference
18 markdownlint rules are supported. crackdown migrate maps all of them automatically.
| markdownlint rule | Status | crackdown equivalent | Package |
|---|---|---|---|
| MD001 (heading-increment) | ✅ | md001Rule | @crackdown/compat-markdownlint |
| MD005 (list-indent) | ✅ | md005Rule | @crackdown/compat-markdownlint |
| MD007 (unordered-list-indent) | ✅ | md007Rule (configurable indent, default 2) | @crackdown/compat-markdownlint |
| MD009 (trailing-spaces) | ✅ | md009Rule + md009Fixer | @crackdown/core |
| MD010 (no-hard-tabs) | ✅ | md010Rule + md010Fixer | @crackdown/core |
| MD012 (multiple-blank-lines) | ✅ | md012Rule + md012Fixer | @crackdown/compat-markdownlint |
| MD013 (line-length) | ✅ | md013Rule (configurable lineLength, default 80) | @crackdown/compat-markdownlint |
| MD022 (blanks-around-headings) | ✅ | md022Rule | @crackdown/compat-markdownlint |
| MD024 (no-duplicate-headings) | ✅ | md024Rule | @crackdown/compat-markdownlint |
| MD025 (single-top-level-heading) | ✅ | md025Rule | @crackdown/compat-markdownlint |
| MD026 (trailing-punctuation) | ✅ | md026Rule | @crackdown/compat-markdownlint |
| MD031 (blanks-around-fences) | ✅ | md031Rule | @crackdown/compat-markdownlint |
| MD032 (blanks-around-lists) | ✅ | md032Rule | @crackdown/compat-markdownlint |
| MD033 (no-inline-html) | ✅ | md033Rule | @crackdown/compat-markdownlint |
| MD034 (no-bare-urls) | ✅ | md034Rule | @crackdown/compat-markdownlint |
| MD040 (fenced-code-language) | ✅ | md040Rule | @crackdown/compat-markdownlint |
| MD041 (first-line-heading) | ✅ | md041Rule | @crackdown/compat-markdownlint |
| MD047 (single-trailing-newline) | ✅ | md047Rule + md047Fixer | @crackdown/compat-markdownlint |
| MD003 (heading-style) | ❌ Not yet implemented | — | — |
| MD036 (no-emphasis-as-heading) | ❌ Not yet implemented | — | — |
Manual migration
If you prefer to set up manually:
pnpm add -D @crackdown/core @crackdown/cli @crackdown/compat-markdownlintCreate crackdown.config.ts:
import { md001Rule, md012Rule, md012Fixer, md013Rule, md022Rule, md024Rule, md025Rule, md031Rule, md040Rule, md041Rule, md047Rule, md047Fixer,} from '@crackdown/compat-markdownlint'import { md009Rule, md009Fixer, md010Rule, md010Fixer } from '@crackdown/core'import type { MarkyConfig } from '@crackdown/core'
const config: MarkyConfig = { plugins: [ md001Rule, // heading levels increment by 1 md009Rule, // no trailing spaces md010Rule, // no hard tabs md012Rule, // no multiple consecutive blank lines md013Rule, // line length ≤ 80 md022Rule, // blank lines around headings md024Rule, // no duplicate heading text md025Rule, // single top-level heading md031Rule, // blank lines around fenced code blocks md040Rule, // fenced code blocks have a language md041Rule, // first line must be a heading md047Rule, // file ends with a newline ], fixers: [ md009Fixer, // strip trailing spaces md010Fixer, // replace tabs with spaces md012Fixer, // collapse multiple blank lines // (c) => md010Fixer(c, { tabSize: 2 }), // custom tab size md047Fixer, // append trailing newline ],}
export default configConfiguring line length (MD013)
The default line length is 80 characters. Use the [rule, options] tuple to configure it:
import { md013Rule } from '@crackdown/compat-markdownlint'
const config: MarkyConfig = { plugins: [ [md013Rule, { lineLength: 120 }], ],}Configuring rule severity
Use config.rules to override severity per rule ID:
const config: MarkyConfig = { plugins: [md013Rule], rules: { 'remark-lint:maximum-line-length': 'error', // upgrade to error 'crackdown:no-trailing-spaces': 'off', // disable entirely },}Rule IDs follow the pattern <source>:<rule-name> as shown in crackdown lint output.
Loading .markdownlintrc at runtime
You can also load an existing .markdownlintrc programmatically:
import { loadMarkdownlintConfig } from '@crackdown/compat-markdownlint'import { lint } from '@crackdown/core'
const config = await loadMarkdownlintConfig(process.cwd())const results = await lint(['README.md'], config)This is useful for tools that wrap crackdown and want to respect an existing markdownlint config.