Suggested workflow for theme developers

I’m getting close to finishing my first theme and would like to hear how other Hugo theme devs manage their workflows.

I started the project with the new theme command and initialized a git repo under mysite/themes/mytheme. I’ve been making all my commits and pushing from there to github. I’m using a skeleton site that sits on top of the theme to play around with different config options and content variations for testing purposes (that doesn’t get committed).

Normally when I use a theme I would create a new site and add it as a submodule. Since this is my own theme, I am trying to think ahead about how I would develop new features and push those changes.

Ideally I would like to do this in the theme folder of my actual site, not this test one I’ve built on top of the repo. Most of my ideas will come as a result of toying with my own site. But I’m not sure if you can do that with a submodule.

If that’s not possible, I guess the best way would be continuing to develop in my current repo with test site and then once a feature is live, update the submodule and see how it looks on my own site?

Is that what most of you other theme devs do?

Edit: Also, any other suggestions you have would be great. Like how to include an example site, etc. The documentation for theme devs is somewhat lacking unless I’m missing some hidden page on github.

I don’t have the feeling I understand your specific “felt” predicament, but maybe my following notes might help:

  • stop using Git submodules.
  • add your theme as a Gohugo Module. Read about Modules. Then read again and “get” the difference between submodules (very old method) and Hugo Modules (the way to go).
  • “toying around” = putting your changes into the layouts folder of your website, that uses the module. Those files override the module files. The same name in the root overrides file with the same name in the module.
  • “releasing updates to your module” = copying your changed files into your module and releasing it.
  • Expert mode: read about “replacements” in your go module setup and link your local module to your local development website that uses that module, then work in the module and have changes applied instantly on “replaced” modules.

Additional Tips:

  • re-read the whole documentation on hugo from top to bottom. twice. after that, you will have a feeling of all the features. The docs are chaotic but everything is noted at least once in there (in my opinion often at unexpected places) and there are so many hidden gems (aka features) in Hugo…
  • in all your research take into account that 1 year in Hugo development is a lifetime. Don’t even try things you read in years-old posts. They will probably have much better solutions today. Use the Google Tools where you set the age of the results. Don’t accept anything as canon that is older than 6 months.
  • whenever a “super cool layout tip” involves .Scratch check the date of the post. think about if it’s possible without a scratch. It probably is. One of my hobbies is re-writing a scratched layout with present Hugo features.
  • have a look at standard version to create tagged versions of your theme. Or any other tool you feel confident with to create versioned releases. Then update your sites via hugo mod get -u ./.... This will enable you to commit changes that are not available to all users because with a semver-sioned release Hugo will prefer that tagged version to the latest commit when installing the theme. Good for testing on multiple sites.
  • stay consistent with your versioning. either vMajor.Minor.Patch or Major.Minor.Patch - Github or Hugo has sorting issues if you use both tag names for releases (talking about the little v in the front). The best is to always use a v (IMHO), so you can tag other stuff (not releases, but maybe stuff like a specific testing branch) too without breaking your live websites.
  • documentation. if you ever intend to have people that are “not you” use your theme then have documentation on everything. even the things you think are easily understandable. Have a sample configuration where every config value you create is explained verbaciously. Don’t assume your users understand everything by looking at the layout files.
  • keep SEO, site speed, usability, accessibility, internationalisation and any characterNUMBERcharacter thingy you can think of (like the named a11y, i18n) in the back of your mind. If your theme looks nice but throws me back to the last century I will not use it :wink:

This is pretty much along the lines of what I was looking for. I really appreciate you taking the time to write that out.

Submodules are outdated? That’s news to me considering the quick start docs suggest using them. Unless you just mean for theme development. All my existing sites use submodules for pulling in themes.

I feel that the docs should be updated to include more guidance like this for theme devs. Or at the very least the README. I know a lot of the advice isn’t Hugo specific necessarily. But as someone without a Go background I’ve found it difficult to piece together how modules work in the context of theme development.

1 Like

You may already do this, but if not:

Keep an exampleSite dir in your theme repo. Here you can put content to test out your theme.

Then you can serve it with something like this: cupper-hugo-theme/ at master · zwbetz-gh/cupper-hugo-theme · GitHub


I disagree. Git submodules are alive and well. I use them often in my day job, so am already familiar. (Useful for grouping micro services under a “main” repo).

I know folks love hugo modules around here. Reckon it’s just preference at the end of the day.


For new users in particular, I think adding a theme as a Git submodule is a better choice. They can see the templates in the theme folder, and pretty quickly figure out who is doing what to whom. And when they need to override theme/foo/layouts/partials/head/css.html the file is right there, ready for Ctrl+C Ctrl+V.

Yes, you can do the same thing with Hugo modules with hugo mod vendor, but a new user would have to know to do this.

I’ve also seen experienced users unable to troubleshoot an error message when the theme has been added as a Hugo module. “I am not using that function anywhere in my project. I have searched my source and it’s just not in there.” Well, yeah, actually it is. You just can’t see it.


I think I’m going to stick with submodules to start to make it accessible for more people. The consensus seems to be that submodules are easier to wrap your head around. Then later on add support for Hugo modules if I feel like learning them.

Quick update on my theme development workflow for anyone that’s interested…

I have my theme added to my personal site as a submodule. I’ve basically just been making changes to the theme from the submodule and testing them locally by cding up two levels and running my project. Then I commit and push my changes from the submodule. Seems to work just fine.

On a somewhat related note: Does anyone know the best way to streamline the creation of content for someone adding my theme as a submodule?

Currently I have an exampleSite directory with a content subdirectory and my docs instruct the user to copy that over to their project’s content directory. I’m curious if there’s a way to streamline this without adding a content directory to the theme…because in my mind that would require the user to either modify theme files or be stuck with that sample content. Please correct me if that’s not accurate.

Whereas I simply want something for the user to modify and build off of based on their own needs. I would also like to support Netlify one-click deploy button but currently my site will not look complete using it because certain features depend on that sample content…