The most important decision in IosShell isn't a screen or a feature. It's a plumbing question: how do you assemble an app from reusable parts, and then take a part back out cleanly.
I wrote the decision down before building it, including the seven options I rejected. One of them was cheaper than what I picked, and it was close. Here's how I got there.
The requirement that forces the question
IosShell is a set of components: branding, sign-in, push notifications, settings, a backend, a loyalty module and a small admin view. The promise is that a new app starts from the shell with only the parts it needs.
I made that promise testable. A project created with only branding, settings and sign-in has to build with zero errors and launch to the sign-in screen. It must contain no push, admin, backend or loyalty code, and no file that refers to any of them. And each component should be droppable on its own, where the others allow it.
That sounds simple until you ask what "no file refers to them" means in practice.
The option that almost won
The cheapest approach is one app with a folder per component. When you don't need a component, you delete its folder.
It needs no tooling at all. It lost for two reasons.
First, nothing stops one component from quietly reaching into another. You only find out when you delete a folder and the build breaks. That's exactly the combination nobody builds day to day, like sign-in and branding with nothing else, so the break would surface in the middle of a real project, on someone else's clock.
Second, every new project means hand-editing the root view and the settings rows to match what's left.
I want to be honest that it was a close call. For a project with no proven demand, cheap and simple has a lot going for it.
What I chose
Each component becomes its own local Swift package. A package can only import what it declares as a dependency, so an illegal reference between components is a compile error in the shell itself, not a surprise in a copy.
Each project gets a small manifest listing its name, bundle ID and the components it uses. A dependency table lives in one place, and a selection that breaks it is refused. Picking a component adds whatever it needs and tells you so.

A small command-line generator then copies in only the chosen packages and writes the project file. I don't hand-edit Xcode project files. It's one rule I never break, and a generator that writes them removes the temptation.
Two choices here are deliberate. A client app is a copy of the shell at a tagged release, not a remote reference to it, because I don't want future clients coupled to my repository, and because reuse is measured as unmodified lines from that release. And there's no shared "core" package yet. A shared contract lives in the lower package of the pair that uses it, because a fourth layer is too much for a problem with two uses.
What it costs me
The table, the wiring fragments and the generator are real, ongoing work. Every new dependency has to be reflected in all three. Copies drift, so a bug fixed in the shell has to be backported by hand to anything already shipped. And the generator makes XcodeGen a tool dependency. I'm relying on my memory that it supports local package references well. The first build will tell me whether that memory is right.
The part I care about most: build the hard piece last
I haven't validated demand for any of this. The test I set in the first post, three paid engagements in 90 days, hasn't started. So the generator, the most expensive piece, gets built last.
The order is: write the packages, assemble a full app by hand from them, and get a branded demo working. Only then build the generator, kept to a manifest and file copying with nothing extra.
If the test fails, I haven't wasted much on the part the cheap option would have avoided. The packages still work as plain copy-and-edit starting code. That's the hedge. When the evidence is thin, spend least where the cost would be the hardest to recover.
What I haven't checked
This decision is still marked proposed. It depends on one thing I haven't confirmed: whether my earlier apps already contain a project-generation or packaging mechanism I could reuse. If they do, I'll revise this before building anything.
Next I'll write about accessibility: what I've committed the shell to, and what I've decided never to claim.


