# Turning \`tuist/tuist\` into a monorepo

**URL:** <https://community.tuist.dev/t/turning-tuist-tuist-into-a-monorepo/614>\
**Category:** RFCs\
**Created:** [June 10, 2025, 9:51am UTC](https://community.tuist.dev/t/turning-tuist-tuist-into-a-monorepo/614 "2025-06-10T09:51:22Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![pepicrft](https://community.tuist.dev/user_avatar/community.tuist.dev/pepicrft/32/5_2.png) [@pepicrft](https://community.tuist.dev/u/pepicrft)\
**Post date:** [June 10, 2025, 9:51am UTC](https://community.tuist.dev/t/turning-tuist-tuist-into-a-monorepo/614/1 "2025-06-10T09:51:22Z")

</div>

## Need/problem

With our plans to make the server source code available, and also provide an SDK that developers can add to their apps to bring runtime capabilities, like _runtime intelligence_ (like [Tidewave](https://tidewave.ai/)), I think this presents us with an opportunity to start taking steps towards a monorepo setup under `tuist/tuist`.

## Motivation

Working across repositories worsens the developer experience. In cases where dependencies like [FileSystem](https://github.com/tuist/filesystem) or [Noora](https://github.com/tuist/noora) are standalone, mature projects, it makes sense for them to be in their own repository for discoverability reasons. Still, everything else should be in a monorepo, in my opinion.

## Detailed design

I propose that we make some changes to [GitHub - tuist/tuist: A virtual platform team for mobile devs who ship · GitHub](https://github.com/tuist/tuist) directory structure to accommodate new projects in the repo:

- Move the CLI code under `cli/`. That includes `Sources`, `Templates`, `Tests`, `fixtures`, `Project.swift`, `.xcode-version` files, `.swiftlint.yml` and `.swiftformat.yml`.
- Rename `.github/workflows/tuist.yml` to `cli.yml`.
- Adjust the `README.md` to reflect the new structure.
- Namespace the CLI Mise tasks under `cli` (e.g. `mise run cli:build`).

Long-term I expect the structure to be something along the lines of:

```bash
/
  app/
  cli/
  docs/
  server/
  sdk/
  README.md
  LICENSE.md
  ...

```

## Drawbacks

A monorepo comes with investment from our side in the tooling and pipelines to ensure we run the right tasks based on file changes. However, tooling is what we excel at, so we have the expertise to handle this kind of work, and we can iterate as we go.

## Alternatives

The alternative is to stay in a multi-repo setup, but as I stated earlier, the developer experience is not ideal. Moreover, changes span across repositories, making it harder to reason about feature contributions.

## Adoption strategy

With PRs opened, this scan will be a bit painful. We can focus on closing/merging all the existing PRs, but I don’t think that’s very realistic. We can at least try to close as many as we can, and for the remaining, there will have to be a rebase work that needs to happen. I’d say that we support there.

---

<div class="post-metadata">

**Author:** ![marekfort](https://community.tuist.dev/user_avatar/community.tuist.dev/marekfort/32/8_2.png) [@marekfort](https://community.tuist.dev/u/marekfort)\
**Post date:** [June 11, 2025, 7:42am UTC](https://community.tuist.dev/t/turning-tuist-tuist-into-a-monorepo/614/2 "2025-06-11T07:42:28Z")

</div>

Generally, definitely aligned in making `tuist/tuist` a monorepo, we’re technically there already.

> [@pepicrft](#):
>
> - Move the CLI code under `cli/`. That includes `Sources`, `Templates`, `Tests`, `fixtures`, `Project.swift`, `.xcode-version` files, `.swiftlint.yml` and `.swiftformat.yml`.

Where would you put code shared between different end products, like the CLI and the app sharing the `TuistServer` module? Would those modules stay in the root or would they be moved in the `cli` that is currently the “primary” consumer?

Additionally, configuration files like `.swiftlint.yml` are _also_ shared across the app and the CLI – I’d consider keeping those in the root.

I would also add that there are some gotchas we ran into when making `Noora` into a monorepo:

- The repository _must_ have a `Package.swift` in the root to ensure you can still consume `tuist` via SwiftPM
- You _can’t_ have multiple `Package.swift` manifests in a single repository that you want to use for distribution
- You _can’t_ have prefixed tags for code distributed via SwiftPM. Again, that means we’re limited to having a single package that we can distribute from the monorepo.

This is generally fine – for example, `server` can be distributed under its own prefixed tag – but I don’t think we can incorporate something like `sdk` in the monorepo. The SDK needs to be a lightweight dependency and due to SwiftPM limitations, I believe we’ll be forced to have it in its own repository. fwiw, the SDK would probably fall into the same bucket as `FileSystem` where it eventually matures and having it in a different repository won’t cause that much friction anymore.

> [@pepicrft](#):
>
> With PRs opened, this scan will be a bit painful. We can focus on closing/merging all the existing PRs, but I don’t think that’s very realistic. We can at least try to close as many as we can, and for the remaining, there will have to be a rebase work that needs to happen. I’d say that we support there.

Git usually deals with files that were only _moved_ quite gracefully, so I don’t think we need to rush to merge all opened PRs.

---

<div class="post-metadata">

**Author:** ![pepicrft](https://community.tuist.dev/user_avatar/community.tuist.dev/pepicrft/32/5_2.png) [@pepicrft](https://community.tuist.dev/u/pepicrft)\
**Post date:** [June 11, 2025, 10:14am UTC](https://community.tuist.dev/t/turning-tuist-tuist-into-a-monorepo/614/3 "2025-06-11T10:14:12Z")

</div>

> [@marekfort](#):
>
> Where would you put code shared between different end products, like the CLI and the app sharing the `TuistServer` module? Would those modules stay in the root or would they be moved in the `cli` that is currently the “primary” consumer?

I’d say we can place these under `/swift`, `/swift-shared`, or just `/shared`

> [@marekfort](#):
>
> Additionally, configuration files like `.swiftlint.yml` are _also_ shared across the app and the CLI – I’d consider keeping those in the root.

We can keep them at the root, or have a `config/` directory where we place those to keep the root as lean as possible, such that users coming across the GitHub repository don’t have to scroll a lot to start reading the README.

> [@marekfort](#):
>
> I would also add that there are some gotchas we ran into when making `Noora` into a monorepo:

This is a bit annoying. I think having the SDK elsewhere makes sense. Alternatively, we can distribute an `.xcframework` for this one? Since this one will be integrated by Xcode through SwiftPM, I think it’s a nice distribution bundle.

---

<div class="post-metadata">

**Author:** ![marekfort](https://community.tuist.dev/user_avatar/community.tuist.dev/marekfort/32/8_2.png) [@marekfort](https://community.tuist.dev/u/marekfort)\
**Post date:** [June 11, 2025, 4:23pm UTC](https://community.tuist.dev/t/turning-tuist-tuist-into-a-monorepo/614/4 "2025-06-11T16:23:38Z")

</div>

> [@pepicrft](#):
>
> I’d say we can place these under `/swift`, `/swift-shared`, or just `/shared`

`swift-shared` or `swift-common` sounds like the most descriptive, but I’m good with either of the suggestions.

> [@pepicrft](#):
>
> We can keep them at the root, or have a `config/` directory where we place those to keep the root as lean as possible, such that users coming across the GitHub repository don’t have to scroll a lot to start reading the README.

Not sure I would optimize for that and having config files in the root is quite common – but no strong opinion on that.

> [@pepicrft](#):
>
> This is a bit annoying. I think having the SDK elsewhere makes sense. Alternatively, we can distribute an `.xcframework` for this one? Since this one will be integrated by Xcode through SwiftPM, I think it’s a nice distribution bundle.

Let’s make the decision on that when we get closer to publishing the SDK.
