Skip to content

Mono repo considerations and best practices #581

Description

@foundryserver

Hello,

I use a mono repo for my organization. So each app/website/api is a folder in the mono repo. The big picture is that they all use the same db structure as the glue that bind them together. However each app/api has a specific job to do. For example, kubernetes provisioning a work load, or sending an email.

I am wondering how do I use spec kit in this situation? Is there one spec for the whole repo or can there be a spec in each dir for each micro service. Here is the dir structure

repo
- main website
- kubernetes api
- email api
- stripe api
- admin website
- proxmox api

I hope this question makes sense. I tried separate repo's for each micro service and it was just too cumbersome when making global changes. I am the only dev so it seems to work for me.

The project is fantastic btw.

Brad

Activity

  1. outp1 commented on Sep 25, 2025

    @outp1
    Contributor

    I was thinking about this too. There is no native support for different project structures, but you can either:

    • Init spec-kit in each subproject, which will involve you more in the feature design process. Less "vibecoding" approach, and more predictable outcomes for large monorepos.
    • Init it in the root folder, which also works fine. With this approach, your agent will be able to work on a broader-scope features.

    Regrettably, the first choice forces you to code within the subproject's working directory.

  2. yeuem1vannam commented on Sep 26, 2025

    @yeuem1vannam

    In my case, we use a monorepo-within-monorepo structure because each sub-monorepo has a different tech stack. Ex:

    • repo
      • platform: web-based tech stack; nextjs
        • apps/web
        • apps/admin
      • functions: lambda functions for tasks; python
        • throttle-login
        • backup

    Each sub-monorepo comes with its own container setup. To support this, we use a spec-kit in each sub-monorepo and make small adjustments in the common.sh script, for example: platform/.specify/scripts/bash/common.sh

    # Get repository root, with fallback for non-git repositories
    get_repo_root() {
    +    # This repo was configured in non-git mode, so we need to use the script location
    +    # if git rev-parse --show-toplevel >/dev/null 2>&1; then
    +    #     git rev-parse --show-toplevel)
    +    # else
            # Fall back to script location for non-git repos
            local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
            (cd "$script_dir/../../.." && pwd)
    +    # fi
    }

    This setup works well for us, so I think get_repo_root should prioritize the --no-git config over git rev-parse.

  3. schnee commented on Sep 26, 2025

    @schnee

    I just had a situation in a mono-repo:

    repo-root
    └── project-root
        ├── .specify
    
    

    initially after running /specify, the specs directory was inserted into repo-root. I moved it to project-root. I'm hoping this doesn't mess things up.

    Should specs be parallel to where ever the .specify directory is (in general)? That way, the specifications are tied to the memory.

  4. outp1 commented on Sep 26, 2025

    @outp1
    Contributor

    initially after running /specify, the specs directory was inserted into repo-root. I moved it to project-root. I'm hoping this doesn't mess things up.
    It should not

    Should specs be parallel to where ever the .specify directory is (in general)? That way, the specifications are tied to the memory.
    They should be placed in the same dir.

    @schnee, you have initialized the spec-kit in the subproject directory. Now, you need to set it as the current working directory.

  5. schnee commented on Sep 26, 2025

    @schnee

    @outp1 thank you.

    When I initialized spec-kit, it was something like:

    cd repo-root
    mkdir project-root && cd project-root &&  uvx --from git+https://github.com/github/spec-kit.git specify init --here --ai opencode --script sh
    

    that apparently did not set the subproject directory (project-root) as the current working directory (which in this case should be project-root because of the --here correct?). How do I set spec-kit's current working directory? I doesn't seem to be a "cd" command.

  6. foundryserver commented on Sep 28, 2025

    @foundryserver
    Author

    Would the idea then to be, init the spec kit in the repo root. Then use spec kit to describe the project as a whole. Going through and defining what each application does and how they relate to one and other. Then when I want to work an app to add a feature, I could then do "/spec" making sure I refer to the correct app within the mono repo?

  7. ojalberts-mydata commented on Sep 30, 2025

    @ojalberts-mydata

    Experiencing similar frustration with location of the spec folder in the REPO_ROOT in a mono repo, working with worktrees almost exclusively. In my mind this should be located int the PROJECT_ROOT or WORKSPACE_ROOT? Especially for worktrees this would be preferred in our case.
    Having the specs folder in the REPO_ROOT causes confusion and does not support separation of concerns. The simplest solution might be to just allow the user to specify the root and record it in Spec Kit's memory for future use? Although that might complicated the scripts.
    For now, i have edited the scripts to look in the workspace root instead of REPO_ROOT. This works, but is far from an ideal long term fix. I subsequently rolled these changes back to avoid future headaches.
    Keep in mind that mono repos by their mere existence and definition means hosting multiple project "repos" in one git repo. The physical limitation of git's "limited" support for sub-repos made this a necessity.

  8. schnee commented on Sep 30, 2025

    @schnee

    I have found that I can "force" the behavior I want with commands such as:

    /tasks specs/001-feature/plan.md

    that is, being very explicit with the pathing (the above assumes I'm in PROJECT_ROOT).

    Thinking about mono-repos, one could envision a future where a repo-level constitution.md exists, as well as project-level constitutions. Spec-kit could assemble them as it processes, allowing for a cascade of governance.

  9. mlaass commented on Oct 4, 2025

    @mlaass

    I did this

    get_repo_root() {
    +    # This repo was configured in non-git mode, so we need to use the script location
    +    # if git rev-parse --show-toplevel >/dev/null 2>&1; then
    +    #     git rev-parse --show-toplevel)
    +    # else
            # Fall back to script location for non-git repos
            local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
            (cd "$script_dir/../../.." && pwd)
    +    # fi
    }
    

    and search replaced "repo root" with "project root" in the commands, so far seems to do the trick

  10. ojalberts-mydata commented on Oct 6, 2025

    @ojalberts-mydata

    I did this

    get_repo_root() {
    +    # This repo was configured in non-git mode, so we need to use the script location
    +    # if git rev-parse --show-toplevel >/dev/null 2>&1; then
    +    #     git rev-parse --show-toplevel)
    +    # else
            # Fall back to script location for non-git repos
            local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
            (cd "$script_dir/../../.." && pwd)
    +    # fi
    }
    

    and search replaced "repo root" with "project root" in the commands, so far seems to do the trick

    I did this too. The problem with this is that if you apply any updates from spec-kit to your repo/project then the scripts will be overwritten and you lose the change. So not ideal, but it works.

  11. fabiodouek commented on Oct 6, 2025

    @fabiodouek

    Same here, the workaround worked partially and it was trying to inspect the code in the root dir.

    Ideally whenever initializing in a subdir, the tool should bootstrap the script automatically to handle specifying a base directory

  12. voroshkov commented on Oct 13, 2025

    @voroshkov

    Strongly vote for changing all scripts to use project root instead of monorepo root as well.

  13. acgxv commented on Oct 23, 2025

    @acgxv

    Please support this. It becomes more and more important for managing big project with AI.


    My temporary fix is:

    mv .git .git.bak
    specify init --no-git --ai codex --script sh mono-repo-sub-project
    cd mono-repo-sub-project
    CODEX_HOME=.codex codex
    # run /specify.cmds
    # exit codex
    cd ..
    mv .git.bak .git
    
  14. brentarias commented on Oct 23, 2025

    @brentarias

    The idea of a feature enhancement to recursively locate Spec Kit config files sounds promising. See #536

    More broadly, there is a lot of demand for supporting mono repos. In particular, I'd like to use Spec Kit and Nx together.

    See also #769

  15. dvic commented on Nov 4, 2025

    @dvic

    I did this

    get_repo_root() {
    +    # This repo was configured in non-git mode, so we need to use the script location
    +    # if git rev-parse --show-toplevel >/dev/null 2>&1; then
    +    #     git rev-parse --show-toplevel)
    +    # else
            # Fall back to script location for non-git repos
            local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
            (cd "$script_dir/../../.." && pwd)
    +    # fi
    }
    

    and search replaced "repo root" with "project root" in the commands, so far seems to do the trick

    We could do a slightly more precise approach like this: qdentity@3c57223

    basically just check if there is a .specify in the cwd, otherwise use repo root. wdyt?

  16. aki-s commented on Jan 8, 2026

    @aki-s

    I tried spec-kit on mono-repo of Git.
    I encountered the issue when I run /speckit.implement .

    My another suggestion is making your LLM Agent to allow modify .specify/scripts/bash/common.sh
    to support mono repo at startup phase of LLM.

    My usecase is such as

    $ export CODEX_HOME=path-to-dot-codex/.codex codex "You can modify $PWD/.specify/scripts/bash/common.sh` If you had to support this mono repo. If you modified the script then tell me if you did."

    Then changes like below is to be made by LLM in common.sh. If you disallow LLM to modify the other non-related directory, you are safe!

    # Get repository root, with fallback for non-git repositories
    get_repo_root() {
        # Prefer the .specify root relative to this script to keep spec-kit scoped
        local script_dir="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
        local script_root="$(cd "$script_dir/../../.." && pwd)"
    
        if [ -d "$script_root/.specify" ]; then
            echo "$script_root"
        elif git rev-parse --show-toplevel >/dev/null 2>&1; then
            git rev-parse --show-toplevel
        else
            # Fall back to script location for non-git repos
            echo "$script_root"
        fi
    }
    
  17. cbaerikebc commented on Jan 30, 2026

    @cbaerikebc

    Gemini apparently got frustrated with not finding the files where the PS scripts were looking for them in my repo, so it patched the common.ps1 file itself:

    function Get-RepoRoot {
        # Check relative to script location first (handles monorepos/subdirs)
        $scriptRelativeRoot = (Resolve-Path (Join-Path $PSScriptRoot "../../..") -ErrorAction SilentlyContinue).Path
        if ($scriptRelativeRoot -and (Test-Path (Join-Path $scriptRelativeRoot ".specify"))) {
            return $scriptRelativeRoot
        }
    
        try {
            $result = git rev-parse --show-toplevel 2>$null
            if ($LASTEXITCODE -eq 0) {
                return $result
            }
        } catch {
            # Git command failed
        }
        
        # Fall back to script location for non-git repos
        return $scriptRelativeRoot
    }
    
  18. tkapin commented on Feb 21, 2026

    @tkapin

    +1 from me on this. My use case is a monorepo with tens of unrelated projects focused on learning, rapid prototyping and experimentation. It would be a huge improvement if SpecKit could treat the current working directory as the primary project root (with repo-root fallback), so each project could keep its specs fully independent and relevant only to that directory.

  19. mnriem commented on Sep 10, 2026

    @mnriem
    Collaborator

    Mono repo support has been delivered by disconnecting Git and features from each other. As such this issue can now be closed. If there is any more to be done please start a new discussion or open a new feature request with specifics

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions