Thoughts on Running Multiple Side Projects That Are Similar but Not Quite the Same
GitHub Templates, Feature Flags and Web Components
2025-06-30Recently, I keep hitting cases where I want to develop several diverging versions of a single project, for example a language learning app for different languages. This is not merely a question of data labeling or switching from LTR to RTL but often goes deeper: Different marketing, different UIs, different onboarding.
The question is, then, on how to manage such an undertaking. Here is what I tried, and what I found:
-
GitHub Templates: With this feature, you can kickstart a GitHub repo from another repo, instead of starting from scratch. In my example, you'd create a base language learning app, set that as a repo template, and then derive language-specific versions from it. In practice, I've not found it very useful — finding the correct, future-proof abstractions for the template project is extremely hard. In any case, this really only boosts development speed at project speed, which is pretty swift anyways, thanks to meta frameworks like Vite and LLM tools like Cursor.
-
Web Components: You build reusable HTML+CSS+JS widgets that you can plug into your projects. This is theoretically rather neat, but web components seem rather immature (too much discussion about basic best practices still open for my taste), they have some really weird foot guns, and having to define that hard line where you switch from refactor-able project code to black box web component is rather strange — and difficult. Most of all, I find that having two repositories (one with your web components, one with your consuming projects) really slows your development loops.
-
Your own libraries: Of course, you run a similar approach without using web components — by simply factoring logic or components (as in, Vue components, React components, Django includes) into some kind of library and pushing it to npm or pip. Similar to the approach above, I find that this rather slows development loops. Additionally complexity explodes in some areas, for example when you define types (where do they live? do you extend a type? do you force usage of the library type?...)
-
Feature Flags: Build both projects as one thing in one repository, and have a "feature flag" that makes it version a or version b. For example, define a
.env
var calledLANGUAGE_TO_LEARN
and set the copy on the landing page accordingly. Works fine, is rather pragmatic, but does make projects feel unwieldy. -
Do Nothing: Simply build both projects in two separate repos, share no code, and simply mutually enhance each by the lessons learned in the other. Works rather well, until you hit a motivational low where you have to re-implement a large piece of logic that you already got in project a in project b as well.