Best way to manage "lite" vs. "pro" codebases?

(Leland Fiegel) #1

So let’s say you have a free “Lite” version of a WordPress theme, and sell a paid “Pro” version of the same WordPress theme.

The “Pro” theme is basically exactly the same as the “Lite” theme, except it as a few extra functions, maybe a few extra template files, and a few extra CSS styles. I’d imagine over 90% of the code would be the same.

What would be the ideal way to manage both codebases?

If I were setting this up today, I’d probably set up one git repo for the Lite version, probably in a public GitHub repository, and manually copy over any Lite updates to the Pro version, stored in a totally separate repo.

While it would work, I can imagine it getting messy. For example, what if I forgot to copy an update to the “Lite” theme to the “Pro” theme, leaving Pro customers without something that all the Lite users had?

I’m thinking there must be a better way to handle this in git, like with branches, submodules, merges, and such, but I’m just well-versed enough in git to really devise a better way myself. Is there? How would you handle it?

Are you a theme developer who sells a “Pro” version of a “Lite” theme? I’d also love to hear how you manage the codebases currently (even if it’s not all automated like).

(Daniel Iser) #2

Pinging @vovafeldman. Founder of Freemius. Check it out, it can handle everything you need including sales.

Essentially you develop the Pro Version. You include their snippet of code and then wrap pro only features in some if statements. When you upload it to their platform it will automatically strip out the pro code giving you a free and pro zip.

Includes in dashboard payments/upgrades to pro etc

I think its still in closed beta, but @vovafeldman could tell you all about it.

(Daniel Iser) #3

Also I don’t know of a way without 3rd party integrations that you could do it with git.

You could probably use an integrated service for final merge and packaging but I don’t think it would be nearly as simple as something like freemius.

(Ben) #4

I used to maintain 2 code bases for the themes I sell for and the themes I sell for - but that was a pain - so I merged them. I wouldn’t want to maintain 2 sets of code.

What I would do - is have a regular free theme - that is well coded, with strategic actions and filters for adding additional content. And then release a paid plugin that adds any ‘pro’ features. This will mean no duplication of code, and a much simpler process for maintaining the product.

(Leland Fiegel) #5

Ah, totally didn’t think of Freemius even though it sounds like it was designed to solve this very problem! I was thinking of more of a “roll your own” solution but would consider Freemius if it would save time, comply with standards and all that. Would love to hear more about that from @vovafeldman. :smiley:

(Leland Fiegel) #6

Interesting. A “Pro theme plugin” crossed my mind as well. This seems to be a pretty straightforward way to go. Since I’d have additional page templates, I just found this method to include them via a plugin which seems doable.

If you had additional pro CSS code, would you enqueue an additional stylesheet, or dequeue the original and enqueue a new stylesheet with the “Lite” CSS and “Pro” CSS combined?

(Ben) #7

I guess you could go either way. For me - I use LESS for my stylesheets so can create a second stylesheet containing the old styles quite easily with no code duplication. Minimizing requests is good - so I’d probably go for the dequeue old and enqueue new option.

I don’t think a second stylesheet makes much difference these days so either option could work.

Thinking about it some more - you could also go down the child theme route for the pro version. There’s no reason a child theme has to look totally different - it could just be extra functionality - and it would make custom page templates even easier to implement. I still prefer the plugin option though since then a user can create a child theme on top of the theme & plugin combo.

(Rhys Wynne) #8

I would probably go the same route as @BinaryMoon. Another reason I’d go down that route is because whenever you want a new feature you may have to add an extra hook. Boom another release, which generally I find I get most sales after I release a free version.

Alternatively, could you make the pro a child theme of the free one?

(Nicolas Lecocq) #9

Hello @leland, a lite version of the theme is a great idea but you have to push people who have downloaded the free version to buy the pro version.
For example, I am creating a free version of one of my themes, I will remove the premium plugins, I will remove most of the widgets and I’ll put one style of blog, header and shop, in the pro version there has several styles, like that if a customer love the lite version, there is going to love the pro version which will have many more features.

(Daniel Iser) #10

This is potentially another reason to check out freemius, the upgrade path for users is built in, they don’t have to leave their own dashboards. Make the payment, upgrade the code base and get support from their own site. They have a solid product.

But if you want to roll your own either option is great ( plugin / child theme ).

The thing there to consider is what your adding.

If it is theme specific go child theme, if it is feature specific and may be needed even after changing to a new theme then go plugin. Or do a combination of both.

(Vova Feldman) #11

Hey guys!

@danieliser thanks for CC-ing me and mentioning Freemius. Since this topic is relevant both for themes and plugins, I’ll only use the word plugins to make my answer readable.

Free + Premium vs. Free + Premium Add-on

Handling freemium (“lite” / “pro”) plugin code base is a pain. There are two freemium approaches used by developers:

  1. Free and Premium (two separate plugin versions). When the user purchases the plugin, he is required to download the Premium version, deactivate the free plugin, install the Premium version and activate it.
  2. Free plugin + Premium Add-On (in case of themes - a premium child theme). When the user purchases the plugin, he is required to download the extra plugin (add-on) and install it as an extension to the free core plugin.

The 1st approach makes the development and debugging process easier since you can simply code anywhere in your plugin. Having said that it’s more complex to maintain it. There are two ways to manage your code base with that approach:

  1. Two code projects - Free and Premium: Any change in the free logic will require duplication of that same logic to the Premium Project.
  2. One code project - Premium: Every time you’ll want to deploy an update to the free version, you’ll need to strip out all the premium logic from the plugin.

The 2nd approach with the Premium Add-on slows down the development since it requires using the hooks mechanism. But, this method forces you to write more modular code (which I think is much better). And the maintenance of the code projects is straight forward. All the free logic located at the free core plugin project while all the premium logic is located at the add-on project. This approach is great though it adds complexity to the upgrade process. In cases where new premium changes are based on new hooks from the core plugin, an upgrade of the add-on won’t activate this new premium logic until the user upgrades the core free plugin as well.

How Freemius solves that once and for all?

With ***Freemius***, plugin developers only have to develop and maintain ONE code project with all the logic (free and paid). Our WordPress SDK provides a license related methods which can be leveraged in order to “tell” Freemius what’s the premium logic. For example:

if ( freemius()->is_paying() ) {
    if ( freemius()->is_plan( 'professional' ) ) {

        // Logic related to Professional plan.

    } else if ( freemius()->is_plan( 'business' ) ) {

        // Logic related to Business plan.


Then, when the plugin is ready for release, instead of deploying it directly to the SVN, first it should be uploaded through Freemius management dashboard. Our sophisticated PHP pre-processor will automatically process all the plugin files and will generate two plugin versions:

  • Premium version: Identical to your uploaded version, including all code. Will be enabled for download ONLY for your paying customers.
  • Free version: The same code base stripped from all your paid features (based on the license related logic). That’s the version you can upload to the

Afterward Freemius handles all the conversion, checkout and upgrade process transparently.

Currently the PHP pre-processor is bound to the Freemius SDK. BUT, if there will be a big demand we might open-source that part to make it flexible so developers can set their own license related syntax and run the pre-processor independently from Freemius. Who is interested?

(Eric Daams) #12

I managed to pull this off last year with Grunt. Took quite a while to figure out exactly how to pull it off, but in the end it worked quite well. It helps if you’re using SASS, so that you generate create different stylesheets for each version.

(Leland Fiegel) #13

Just wondering, do you have any examples of this on GitHub that I could take a peek at? Super curious.

(Leland Fiegel) #14


Thanks @vovafeldman for stopping by and explaining that! Freemius sounds super promising. I was curious, are there any Freemius-powered “lite” themes or plugins currently in the repository?

(Eric Daams) #15

I don’t have the whole project on GitHub, but just dropped the Gruntfile into a gist:

My setup basically works like this:

  1. I have a src directory under wp-content, with the full theme in there. It builds two themes out to wp-content/themes – the lite and pro version.

  2. Inside of the theme, I have a directory called crafted-pro, which contains classes & functions that are only used within the pro version. This directory is stripped out when building the lite version.

  3. Also inside of the theme, there is a directory called src_lite, which has an assortment of classes and files that are used instead of the defaults when building the lite version. For example, this contains a style.css that replaces the root-level style.css. I also have a header.php and footer.php that do the same thing, plus a couple other bits and pieces. This directory is really the only part of the project where duplication is happening (i.e. I’m maintaining two versions of header.php and footer.php). style.css is auto-generated by compass (you could easily use SASS instead).

  4. In the Gruntfile I have defined a few main tasks. The default just uses watch to sync between the src and Pro theme. Updating the lite version requires running grunt updateLite.

It took a while to figure out how everything should piece together, and it does require structuring your theme in a way that enables this, but once you have it working it’s a pretty good solution. You could even go a step further with Grunt and set up a task to build the themes and then deploy them to your repo (for the lite version) or your Pro repo.


(Vova Feldman) #16

@ericnicolaas thanks for sharing! I’ve checked your grunt script but couldn’t understand where / how the PHP files are being processed. Can you elaborate on that? How do you clear the “lite” version from any premium PHP logic / features?

(Ante Sepic) #17

I don’t think he does that, he probably keeps “premium” logic in separate files.

(Eric Daams) #18

Inside the watch task is one task called syncPro (lines 30-54) – this is what is responsible for updating the Pro version as I develop. You can see that it has a big long list of files & filename patterns that it excludes, include the src_lite directory. So that’s how the lite files are kept out of the premium version.

Further down, there is also a task under copy called liteCss (lines 59-94). The naming is a bit confusing here, since it’s not just about CSS, but basically what it does is copy files from the src_lite directory into the build of the lite theme.

Then there is a task under sync called lite (lines 99-144) which is responsible for syncing files between the lite theme and src directory. This also has a big list of files that are not synced – everything starting with a ! is excluded from the sync.

The main reason for using both sync and copy is that sync works if the location of the file in relation to the root directory is the same between the build and the source. With the files living in src_lite, they are all copied into different locations.

i.e. src_lite/style.css is copied to style.css.

Hope that clarifies things. As @OriginalEXE says, what I am doing is keeping premium functionality in its own files (and mostly in its own directories). Personally I think that’s a better way to organize things anyway, but obviously depends on how you like to structure your project.