Methods to install and upgrade themes

Many themes provide their own guidance for installation and updating, often through step-by-step instructions in README files.

What are your tips and tricks for theme installation and upgrades?

To get the discussion started, I created a one-step install script for After Dark which creates a new Hugo site, downloads theme from CDN, copies custom archetypes, creates a sample post with next steps for the user and serves the site up in a terminal browser:

curl -s | sh

Working on a theme, this scenario hasn’t occurred to me. I figured a person would by and large ignore theme updates unless they noticed something interesting that had been added, and depending on the theme would replace their theme directory and/or replace their site’s overrides. I’d appreciate if you discuss when a person would want to run your script. :slight_smile:

Also, if I read that “Getting Started” section in your theme I would immediately skip over it. I don’t curl scripts without reading them, and given that all the other themes are git clone installs, that seems excessive. So I have the discussion here can find a better way to accommodate the use case you are solving!

My only use of themes is as a base theme for my own work (starter files), and I use git submodule. That works for me, because I make changes as well as pull in changes. Not sure if that’s the right approach generally though.

Thanks for sharing, Bud. And I love your Anake theme.

IIRC some theme README files suggest installing using the Git submodule approach while most use the standard git clone technique suggested in It wasn’t until yesterday I realized that a massive binary I had in my git history was slowing down installs because I wasn’t using --depth 1 with the clone. I’m not sure if grafted histories are possible when a theme is added as a submodule.

1 Like

Excellent. I wanted to bring the Customizing section of the README higher in the document so visitors didn’t have to scroll down as far to get to it. The customizing is where most of the value lies, and I’ve been trying to put it front and center without creating a TOC.

Don’t you think theme inheritance would help? In that case, you run a shell script to either git-clone or git-pull the base theme, and all your modifications overwrite the base theme files – just like for a wordpress theme.

I personally create scripts like the following:

For production I use scripts like this:


hugo && rsync -avz --delete public/ ${USER}@${HOST}:~/${DIR}

exit 0

And you can mix both scripts if you want to update the theme’s code too. But this would not work if you update a base code.

In this case you can gather your modifications in a patch, reset the theme git tree to upstream, and apply your patch… If updates don’t break your changes.

$ git format-patch -1 HEAD 
$ git fetch upstream master
$ git branch dev
$ git checkout dev
$ git reset --hard upstream/master
$ git am -3 the_generated_patch_file.patch

and here it [would be]! But note that this is a workaround for the current situation. I guess theme inheritance would solve that.

1 Like

I also opened this thread to discuss that overall theme management:

Out of curiosity @maiki, what do you feel is the preferred approach to helping users determine when they might want to upgrade, regardless of approach (be it scripted or not)?

Right now I maintain a, the contents of which are populated automatically whenever I run my release script, which also tags the GitHub repo and, optionally, deploys the theme to NPM. One thing I’ve been thinking about though, has been to provide an exampleSite utilizing each feature of the theme and have it maintain its own CHANGELOG page which could be consumed as a Web Feed (e.g. RSS). Thoughts?

1 Like

Hey, @jhabdas I’d be interested to know how you run that script, and why you’re using NPM. Are users implementing the theme through NPM?

Script runs using a single dev dependency (highlighted below) using an NPM script specified on line 17 of the package manifest (also shown). To use it I run npm run release from the command line, which automatically generates and git tags based on conventional commits.

When complete, the script generates a one-liner bash script which can be run to push tags to a git remote and then publish the package to the NPM package registry.

No clue. But I figured they might want to based on the number of boilerplates I’ve seen utilizing NPM to supply a build pipeline to simplify common tasks. Plus I couldn’t resist registering after-dark on NPM after reading what happened to individual who had the kik module unlawfully taken from them early last year. After all, who doesn’t love a good controversy?

Please note, however, After Dark does not intend to lean heavily into NPM as a central design goal of the theme is Deceptive Simplicity. I’d just assume use Composer if it made more sense for the use case and enabled me to manage theme dependencies semantically. And, in fact, many users will carry about using the theme unaware it’s even masquerading as an NPM package at all thanks to current design.

You may also be interested in:

1 Like

Thank you. Good information!

1 Like

I think that is going to depend on who is using it, and given that Hugo is still fairly young and basically requires commandline interaction, a lot of folks won’t want to upgrade unless your theme is aligning tightly to their vision for their site. Just as a major benefit for Hugo is that a static binary that will continue working without updating it, themes are as “fire and forget”.

So, it comes down to marketing: how much do you want to work to keep folks up-to-date on what you are building? Enough to keep a mailing list or post in these forums when you have a major update? A changlog based feed?

If I were running paid support or marketing a theme as being an ongoing project where they will always get the best practices if they keep upgrading, I would put more effort into it. I don’t know of anyone doing that, aside from your proposal.

Neat stuff, though! I make my bread and butter customizing WordPress, including themes. In a database-driven CMS updating themes are obviously very important, since they can themselves be secure, but may have deprecated functionality due to the CMS itself being a moving target. The aforementioned static binary nature of Hugo relieves that tension, which makes me mentally wipe the board and see what best practices develop with Hugo. :slight_smile:

I think it would be helpful for your project to have a blurb explaining that your theme has special methods for installing, and ensuring that it doesn’t change how most folks expect to install it, name git clone.

For my part, I don’t keep themes in my site repo, and instead I clone it on my CI runner at build time. If I am using someone else’s theme I mirror it so I always have a copy (a callback to that npm controversy you mentioned). It also means that my package.json for my themes are not interacting with my content at all. So from a docs POV, it would be useful to know I don’t need to run a package manager to install your theme.

1 Like

FYI GVM is a thing. Who knew?

Reflecting on the OP, After Dark has received very few issues from the community since its release. I’ve been tracking what installations I could easily find via referral traffic sent back to the theme site and have compiled a list of sites using it.

Curious why more issues weren’t being introduced I opened an issue to start collecting feedback and discovered without the automated installation added and described in the OP some users weren’t following instructions anyway, which could become a support issue for some themes and a point of user frustration as attention is limited in this world.

Given the growing number of After Dark sites (current 616 NPM package downloads and ~1500 clones per month) I’m feeling pretty good about the automated installation script simplifying theme setup I’m feeling it may be worth considering blessed themes (those in the theme gallery) should start normalizing and minimizing certain installation steps and the hugo new site subcommand receive update to provide more streamlined Hugo installation theme selection capability. /cc @digitalcraftsman

Yesterday I moved After Dark to the WTFPL and published a new version to NPM. Following are the download stats from NPM and GitHub:

My take away here is that a package manager helps individuals upgrade at a faster rate, which makes sense.

Note that the automatic install script mentioned earlier uses git clone and works on Linux whereas NPM is not mentioned whatsoever in the docs except for by badge placement and presence on NPM.

1 Like

I think I disagree, but to clarify: are you suggesting the criteria for inclusion in the theme showcase standardize Node.js as a dependency for theme installation?

The auto install script is bash which uses git to automate the getting started steps into a single command for After Dark. That’s part of the installation side of this thread. You can try it in the OP if you like.

I don’t believe I ever mentioned Node specifically. I’m simply using their package management system along with SemVer to as a means of theme distribution in addition to Git. After Dark does not require Node to run. Just the hugo binary.

As for the Hugo theme site. It already supports automated theme installation given it’s already scripted for demos, whether they be custom or the theme stock demo. It’s just that most users don’t know how to leverage that fact.

An generic installation script leveraged by theme site and possibly as a subcommand in hugo could help with the leveraging. And possibly be used to help tighten up the install process and long-term make it easier to try out different themes locally, which some users have been trying to do.

My issue with using git clone to get the theme is that my theme has a LOT of extra junk in it that you don’t need in order to run the theme.

For example, the entire exampleSite directory would come down in a git clone. You don’t need that. You also don’t need the bower_components files or the SASS files that create the CSS.

My process for release is tagging a version, pushing that to Travis, and using Travis’s release process to push the release to GitHub as a GH release (in a zip file that doesn’t contain the stuff that people don’t need). The local bash script that I have to update my theme also runs the github_changelog_generator rubygem to keep the changelog updated (and TBH I copy-paste that into the description of the GH release when it’s done). I also have a mailing list which I update when there are minor (non-patch) releases of the theme.

Right now, my theme is under pretty active development, so there’s probably desire to keep updated with the features, as most of the stuff I’m adding is coming from requests from the users of the theme. Once it feature-stabilizes, it should be much more infrequent releases (maybe just compatibility fixes with newer versions of Hugo, etc).

It’s worked out fairly well for the couple of podcasts I’ve been helping out - they just whack the existing directory, pull down the zip file, and put that in.