Developing plug-ins for plug-ins extend your blog with additional features or customization for themes. Read Manton’s blog post for an introduction.

Plug-ins are like lightweight Hugo themes. They can provide all the templates needed for a custom theme, or they can provide just a couple templates, overriding any templates in a built-in design on applies the plug-in templates after the blog’s theme has been set up.

A plug-in needs to have at least one file — plugin.json — and it can have other files as needed. The plugin.json file describes the plug-in and what parameters or include files it needs.

If a plug-in has a config.json file, that file can have only the parameters a plug-in cares about. will first set up any default parameters, then apply the blog’s theme parameters, and then apply any extra parameters in the plug-ins configured for that blog.

The basic structure of plugin.json looks like this:

  "version": "1.0",
  "title": "My plug-in",
  "description": "1-2 sentences about what this plug-in offers.",
  "includes": [
  "fields": [
      "field": "params.photos_use_category",
      "label": "Use category",
      "placeholder": "Enter the category name to include photos from"
      "field": "params.photos_only_microblog",
      "label": "Only include short microblog posts (without a title)",
      "type": "boolean"

Only version, title, and description are required. uses the version number to tell the user that a newer version of the plug-in is available. Version numbers usually start at “1.0” and are incremented like “1.0.1” and “1.0.2” for small bug fixes, “1.1” for new features, and “2.0” for major upgrades.

The includes field is optional. If present, automatically adds link(CSS) or script (JavaScript) tags to the blog. The files references in includes should also be in the plug-in. You can add them as static files under the “static” folder in the plug-in.

For example, if you want to include a CSS file named “hello.css” in your plug-in, it would be stored at “static/hello.css” and referenced in includes with the path “/hello.css”.

If you include an html file, will load it as a Hugo partial. You can add those files in the “layouts/partials” folder in the plug-in. These partials are included inside the head tag of the blog, so they are useful for adding metatags or inline styles and JavaScript.

The fields field is also optional. If present, will build a settings screen for the plug-in. Fields can be of type “string”, “boolean”, “integer”, “color”, “markdown”, “css”, or “json”. For booleans, will use a checkbox. If you need to provide default values, set them in the config.json file.

Fields can override some Hugo variables, or add new parameters that are accessible from the plug-in or any other theme. To add your own parameters, use “params.” as the prefix for your field name.

Plug-ins can be developed and edited inside with the theme editor, so that you can test them before making them available in the plug-in directory for other users. On the Edit Custom Themes screen, click the “New Plug-in” button to get started.

Plug-ins that provide a full theme should include a “theme.toml” file. It can be empty or include theme info for using in Hugo outside of This will let be smarter about managing multiple themes so that they don’t conflict.

When you’re ready to share your plug-in with the world, register it here: