Migrating v4 → v5

v5 is a ground-up rewrite: it server-renders every page, emits a companion .md for each, ships built-in search and a source viewer, and adds an opts.docs prose pipeline. The configuration surface changed a lot — but the move is mechanical, and this page (plus the migration skill below) walks you through it.

You can hand this whole job to your AI assistant. There's a dedicated migration skill — point your agent at it and it will lift your options, rename what carries over, drop what's gone, and verify the build. See Let an agent do it at the bottom.

The one thing to know

v4 nested theme options under opts.theme_opts.*. v5 reads them directly from opts.* — there is no theme_opts block in v5. So migration is, in essence: lift your options up out of theme_opts, rename the few that carry over, drop the rest, then optionally adopt v5's new features.

CODE
// v4 — nested under opts.theme_opts
{ opts: { template: "node_modules/clean-jsdoc-theme",
          theme_opts: { default_theme: "dark", title: "My Library" } } }

// v5 — directly under opts (no theme_opts)
{ opts: { template: "node_modules/clean-jsdoc-theme",
          siteName: "My Library" } }

Steps

  1. 1
    Check compatibility

    v5 needs JSDoc ≥ 4 and Node ≥ 20. The plugins/markdown plugin is no longer required by the theme (v5 renders Markdown itself), though keeping it is harmless. Prefer to stay on v4 for now? Pin "clean-jsdoc-theme": "^4" — v5 prereleases publish under the npm next tag, so ^4 won't pull them.

  2. 2
    Upgrade the package
    CODE
    npm i -D clean-jsdoc-theme@latest   # or @next during the v5 prerelease
  3. 3
    Lift and rename options

    Move every key out of theme_opts up to opts, applying the mapping table, then delete the empty theme_opts block. The options that carry over (everything else is removed):

    • base_urlbasePath
    • titlesiteName
    • sectionssectionOrder
    • create_stylecustomCss, include_css / add_style_pathcustomCssFile
    • add_scriptscustomJs, include_js / add_script_pathcustomJsFile
    • menumenu (reshaped — see below)
  4. 4
    Build and verify
    CODE
    npx jsdoc -c jsdoc.json
    npx serve <destination>   # Pagefind full-text search needs HTTP

    v5 warns (with a "did you mean?" hint) on any leftover theme_opts key or v4 option name and keeps building — read the output and fix what it flags. Set strict: true to turn those warnings into hard errors while you migrate, then relax it.

Option mapping

opts.theme_opts.<v4>opts.<v5>.

v4 (theme_opts.*)v5 (opts.*)StatusNote
default_themeremovedLight/dark token sets + runtime toggle; no picker.
base_urlbasePathrenamedSite root prefixed onto links.
titlesiteNamechangedString or a logo set { default, dark, light, alt }.
menumenuchangedReshaped: { id?, title?, link/href?, icon?, target?, class? } — adds icon + id built-ins.
sectionssectionOrderrenamedFilter + order sidebar sections.
create_stylecustomCssrenamedInline CSS (loads after the theme stylesheet).
include_css / add_style_pathcustomCssFilerenamed/changedCSS file → content-hashed asset link.
add_scriptscustomJsrenamedInline JS (runs last).
include_js / add_script_pathcustomJsFilerenamed/changedJS file → content-hashed asset.
homepageTitleremovedHome <title> derives from README / docs/index.md + siteName.
includeFilesListInHomepageremovedThe Source Files section lists files.
metametachangedSupported again — an array of attribute maps → <meta> tags in <head>. See meta.
searchremovedAlways-on fuzzy search + optional Pagefind.
codepenplaygroundchangedv4 prefilled a CodePen from @example; v5 generalizes it to playground — open an example in CodePen, JSFiddle, or CodeSandbox via opts.playground + the @playground tag. (To embed an existing pen by URL, use @iframe.)
static_dirremovedUse JSDoc's own static-file config.
footerfooterchangedSupported again — an inline HTML string or { file: "./footer.html" }. Style it with customCss / customCssFile. See footer.
exclude_inherited, displayModuleHeader, sort, shouldRemoveScrollbarStyleremovedNo equivalent.

The menu reshaped: a v4 entry { title, link, target, class, id } becomes a v5 { id?, title?, link (or href)?, icon?, target?, class? } — you add an icon (lucide:<name> / simpleicons:<name>). In v5, id also selects built-ins ({ id: "home" }, { id: "source" }), and a menu takes precedence over sectionOrder. See menu and Structure your sidebar.

Before / after

CODE
{
  plugins: ["plugins/markdown"],
  opts: {
    template: "./node_modules/clean-jsdoc-theme",
    theme_opts: {
      default_theme: "dark",
      base_url: "https://example.com/docs/",
      title: "My Library",
      menu: [{ title: "GitHub", link: "https://github.com/me/lib", target: "_blank" }],
      sections: ["Classes", "Modules", "Global"],
      search: true,
      footer: "© My Library",
      include_css: ["./static/custom.css"],
    },
  },
}

What you unlock in v5

Migration is also an upgrade. Once you're on v5, reach for:

Let an agent do it

Don't want to do this by hand? Point your AI assistant at the migration skill. It's a focused, source-verified procedure that detects your v4 config, applies the mapping above, reshapes the menu, removes what's gone, and verifies the build — then hands you the umbrella skill so the assistant can help you adopt the new v5 features.

  • Migration skill: SKILLS/migrate-v4-to-v5/SKILL.md — download it the same way as the umbrella skill:

    CODE
    curl -O https://raw.githubusercontent.com/ankitskvmdam/clean-jsdoc-theme/master/SKILLS/migrate-v4-to-v5/SKILL.md

    Then attach it to your assistant (or drop it into .claude/skills/) and say "migrate my project from clean-jsdoc-theme v4 to v5."

  • Canonical reference: the exhaustive MIGRATION.md and the machine-readable migration-map.json back the skill — useful for codemods.

See also