nadai ecosystem: running multiple micro SaaS as one person
How nadai runs gpdf, gsql, and renma in parallel as a side project: what to share, what to separate, and why the author hub absorbs marketing flow.
Plan for what stays constant when you add a third product
I'm a tech lead at a contract-development shop by day, and outside that I'm running three products in parallel: gpdf, gsql, and renma. The hours I can put toward OSS and SaaS work each week sit around twenty. That's enough for one product. Split three ways, it's six or seven hours each — which is not enough to make real progress on anything.
So when I say I'm running three products, I have to be honest about what that means. The actual budget isn't "six hours times three." It's more like "five hours on shared infrastructure plus twelve to fifteen hours rotating through one product's core work each week." I decided up front what to share across products and templated that layer, so adding a third product doesn't triple the overhead.
The claim is simple: if you run multiple micro SaaS as one person and treat each new product as fully independent overhead, you stall on the third. Decide what to share and what to keep separate before you ship the second one, so fixed cost stays close to constant as you add more. This post is the current shape of how I do that for nadai.
What I run today: two lineages, three products, one author hub
Honestly, the time split across the three is uneven — the gpdf ecosystem takes most of what I have. Still, the structural layout is this:
| Lineage | Product | Stack | Status | Audience |
|---|---|---|---|---|
| Developer tools | gpdf (core + api/app/cloud) | Pure Go + Tauri + Nuxt | gpdf v1.0.0 shipped, derivatives unreleased | B2B developers |
| Developer tools | gsql | Pure Go | shipped (no marketing yet) | B2B developers |
| B2C-leaning | renma | Flutter + Go API + Astro | in development | B2C end users |
| Author hub | nadai.dev | Nuxt 3 + Cloudflare Pages | building | aggregator across products |
The developer-tools lineage (gpdf ecosystem and gsql) sits on the same Pure Go base, libraries underneath and SaaS layers above. renma is a different lineage entirely — the only thing it shares is the API language being Go.
I've been told: "Two of your products are similar, and the third one is a totally different genre. Isn't that a design mistake?" It isn't. It's a deliberate split, and I think it's the right call. The reasoning is in a later section.
The cost of running multiple products is mostly context switching
Time multiplies when you run multiple products, but the multiplier sits in switching, not in the per-product code time.
Concretely:
- Stack switching: Going Go (gpdf/gsql) → Dart (renma app) → TypeScript (renma web, nadai.dev) takes thirty to sixty minutes of warmup compared to staying in one language. If that happens several times a day, twenty to thirty percent of usable hours go to warmup.
- Operations switching: gpdf's intake is GitHub issues; renma will be RevenueCat plus App Store Connect; nadai.dev is Cloudflare analytics. More intake surfaces means more daily check-ins.
- Voice switching: gpdf.dev/blog talks to B2B developers in English. nadai.dev/blog is the author's voice in Japanese and English. The renma site speaks B2C in Japanese. Moving between three tones inside a writing session quietly drags.
Each of these is a few minutes' cost in isolation. They stack across days and weeks. With one product you don't notice. By the third you spend a weekend and can't say what you actually built. That, I think, is the real overhead.
Layers I share, layers I refuse to merge
The most important call when running things in parallel is which layers belong on shared infrastructure and which ones stay isolated. Decide this before you start, because if you try to consolidate later you'll find product-specific edge cases have grown into the layer you wanted to share — and they don't peel out cleanly.
Here's where I draw the line right now.
Shared (kept to a constant cost):
- The marketing entry point (
nadai.devauthor hub) - The author entity (one Person
@idreferenced by all products) - Primary language (Go first; Dart and TypeScript only where required)
- Dotfiles and dev environment (Claude Code config, editor, CI templates)
- Domain management (every product on Cloudflare)
- Deployment pattern (static + Cloudflare Pages, or single binary)
Separated on purpose (so per-product nuance doesn't leak in):
- Licenses (gpdf and gsql are MIT License, renma is closed, gpdf-api is considering AGPL)
- Billing surface (Stripe for gpdf-api eventually, RevenueCat for renma)
- Support email addresses (per product)
- Launch timing (one at a time, so attention isn't diluted)
- GitHub organizations (one per product — see next section)
"Primary language is Go" is the most consequential of the shared decisions. renma's mobile app has to be Flutter — Dart is unavoidable there. But I picked Go for renma's API specifically because that lets me work on the API in the same head state I write gpdf in. From a pure technology standpoint Node.js would have been fine too. I think of this as compressing cognitive cost, not as a story about performance or ecosystem.
There's a small cost to this, too. Picking Go pulls renma's API away from the Node.js solo-dev ecosystem where backend starter templates are denser. I don't get to grab a Next.js + Drizzle starter and have a working API in an afternoon. That's the tax of language consolidation across genres, and I'm paying it on purpose to keep the head-state shared.
The marketing flow funnels into the author hub
If you run multiple products, the right move is to funnel the marketing flow into the author hub, not the product sites. Each product site (gpdf.dev and so on) speaks to buyers. The author voice goes to nadai.dev. This isn't an SEO trick — it's how credibility compounds.
| Product site (gpdf.dev) | Author hub (nadai.dev) | |
|---|---|---|
| Subject | Product | The maker |
| Search intent | Features, FAQ, benchmarks, evaluation | Design decisions, narrative, background |
| Languages | English-first | JA + EN side by side |
| Examples | "How to embed Japanese fonts in gpdf" | Where I stand on Pure Go micro SaaS / Why I went Pure Go |
The compounding works like this. AI overviews (Perplexity, ChatGPT search, Claude, Gemini) cite consistently when a single Person @id accumulates first-party material across topics. If the author entity is fragmented across product sites, credit collects under each product separately, and the fact that one person is running multiple things doesn't show up in citations. Pinning the label "nadai = runs multiple Pure Go micro SaaS in parallel" to one location means trust accumulated from product one carries into product four when I ship it.
This isn't a thought experiment. I've wired it into nadai.dev's JSON-LD: the Person @id is fixed at https://nadai.dev/#person, and every product page references it as the author. The GitHub organization nd-forge is bound by sameAs. From an AI's perspective the entity hierarchy resolves to one node.
The opposite — fragmented entities across product sites — is a state where you ship multiple products but get scored point by point. Each product is judged on its own star count and issue volume. Running multiple products in parallel stops being a credibility signal. You leave that on the table.
One GitHub org per product
A less obvious lever is how GitHub organizations are partitioned. I run one organization per product:
nd-forge(author hub org): cross-cutting libraries and tools (errx,stream, etc.)gpdf-dev: gpdf core, landing site, surrounding toolsgsql-dev: gsql and relatedtaiki-nd(personal): personal experiments and dotfiles only — no working repos
Three reasons.
First, transfer flexibility. If you sell an OSS project on Acquire.com someday, transferring an entire org keeps history, stars, issues, and PRs intact in one move. Repo-level transfers add work for the buyer. I'm nowhere near considering a sale today, but three years from now one of these might land in a place where transfer matters. Having orgs already split simplifies the decision when it arrives — the call is about a future timeline, not the current one.
Second, permission isolation. Collaborators and contractors can be invited to one product's org rather than across all your repos. Mixing everything under your personal account is how access mistakes happen.
Third, alignment with the entity hierarchy. gpdf.dev ↔ github.com/gpdf-dev is easy for both humans and AI to recognize. The schema's parentOrganization and the physical GitHub layout match, which makes the knowledge graph hold together.
GitHub Free orgs are unlimited, so the cost is zero. Private repo Action minutes and Packages quotas are counted per org, which actually helps an Open Core layout (public core plus minimal private) — the free quota is enough.
The org name nd-forge keeps the hyphen because Go module paths like github.com/nd-forge/errx are import-path-load-bearing for downstream users. Renaming would be a breaking change. The marketing brand is nadai.dev (memorable, ties to the maker); the technical identifier stays nd-forge. They're tied together via schema sameAs and alternateName.
Lineages should be split on purpose
There's one piece of the structure that "efficiency" doesn't justify: renma. If I just ran the gpdf ecosystem, the stack and audience would be aligned, and cognitive cost would be lower. I keep renma in a separate lineage on purpose, for risk reasons.
When a solo developer concentrates everything in one lineage, a miss in that lineage leaves very little behind. Go OSS and developer tooling is a "narrow and deep" market — technically strong but high variance on outcomes. A B2C fitness-tracker app is a "wide and shallow" market — capped upside if it works, a softer floor if it doesn't. Splitting across markets with different shapes means each lineage's volatility is partly absorbed by the other.
This isn't "diversify and double your hits." It's a survival design — even if one lineage goes to zero, the other stays. I think of it that way. The gpdf lineage might plateau at zero MRR after four months. If that happens, having renma accumulating a different kind of experience preserves an option I wouldn't otherwise have.
More concretely: a small but healthy renma user base — say five hundred Pro users at five dollars per month — is a different shape of asset than two thousand GitHub stars on gpdf with no paying customers. They translate into different decisions at the next branch point: one supports doubling down on B2C polish, the other supports a B2B commercial-license push. Concentrating everything in one lineage means I only get one of those branches, regardless of how it lands.
The flip side is that splitting too far costs more in cognitive overhead than it returns in diversification. From my own experience, two lineages is the cap for one person — three feels impossible (a third one starts and one of the first two dries up). I'm sitting at the cap right now, and when the urge to add a fourth thing comes, I'll probably resist it.
A concrete example: the gpdf-api pricing decision
Less abstract — here's a recent one.
When I started designing pricing for gpdf-api, I spent two weeks on plan structure. The default move is "Free / Pro / Enterprise," straight out of the GitLab tier model. renma already has "Free / Pro / Cloud" wired up on Flutter plus RevenueCat, except it's B2C so the Cloud tier means something different.
That created a choice: align plan names across products or keep them separate. Aligning would let nadai.dev's product page show a clean side-by-side comparison. Keeping them separate could confuse anyone comparing pricing tables.
I started writing it as "align nadai-wide on Free / Pro / Cloud." The unified version did look clean. Halfway through, the realization landed. The same word Pro carries totally different content in a developer SaaS and a B2C app. B2B Pro means commercial use plus authentication plus an SLA. B2C Pro means no ads and advanced calculation features. Forcing the names to match means both audiences get an expectation mismatch.
So I didn't align them. Plan names follow each market's convention. What I did align was the layout template — the names differ, but the pricing tables look visually consistent. What those two weeks gave me, when I wrote it down, was an embarrassingly plain conclusion: the temptation to consolidate has to be relitigated for every concrete case. That's it. Nothing cleaner.
What kept this decision from getting away from me was that "shared layers" and "separated layers" had been split in advance. Plan names had been on the separated side from the start, so when I caught myself trying to align them I knew I was breaking my own rule. Without the upfront split I would probably have aligned them.
Pushback I've heard
"Running things in parallel is just diversified fatigue with a nicer name, isn't it?"
Half right — cognitive cost goes up. That's why I said three lineages is impossible. But putting everything on one lineage carries a bigger long-term risk than the cost increase. If the one lineage doesn't work, all you have left is a single retreat. Two lineages give you the option of folding one and continuing the other. It's not investing — it's optionality.
"You're pouring all your hours into gpdf and renma isn't moving. So you're not actually parallel-running."
True at the moment. The gpdf ecosystem currently takes seventy to eighty percent of my time. renma gets a few weekend hours; I'm not planning to ship it inside 2026. So "running things in parallel" is, more accurately, "the parallel structure exists, and right now I'm leaning into one branch of it." renma's priority comes up after gpdf-api ships. Until then I'm just keeping it from drying out.
"Couldn't you share more by going all-in on Go?"
renma's app layer has to be Flutter — single-binary Go can't reach a B2C smartphone audience. Picking Go for the API was the practical compromise. Going all-in on Go would defeat the cross-genre split. Sharing and splitting are a trade-off; I weighted toward splitting.
Next
That's the shape of nadai's operations as of May 2026. The detail posts:
- Where I stand on this whole thing: Building Pure Go micro SaaS on the side
- Time mechanics: Time design for a day-job tech lead also building OSS
- gpdf design narrative: Building a Pure Go zero-dependency PDF library
- gsql design: gsql API design: how it differs from GORM, sqlx, and squirrel
- License axis: Why I'm considering AGPL for the next derived SaaS, after shipping MIT first
Whether to push to a third lineage is something I might revisit in six months. I'm leaving this post here partly so that, when the urge to add a fourth thing arrives, I can re-read what I told myself this time around.