Best practices for TypeScript monorepo
I really like <a href="https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;wireit&#x2F;" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;wireit&#x2F;</a> for this purpose!<p>My monorepo looks like this:<p><pre><code>    project-1&#x2F;packages&#x2F;core
    project-1&#x2F;packages&#x2F;preact
    project-2&#x2F;packages&#x2F;core
    project-2&#x2F;packages&#x2F;demos
    etc.
</code></pre>
where a bunch of related projects live top-level in a repo.  Each project has a packages folder that includes the core implementation, as well as demos, framework-specific adaptors, etc.<p>In each package&#x27;s package.json, I have a series of commands (convert the TS to JS, make a bundle, deploy to Firebase, etc.).  Each command can depend on another, either in the same project or anywhere else in the file hierarchy.<p>This provides two benefits:<p>1. Iterating across packages is faster, because I don&#x27;t have to worry about making sure each package rebuilds in the right order if I make a change in a library.<p>2. Filesystem concerns are separated: rollup only needs to worry about bundling, and it only needs to bundle web-facing projects.  The only tool my libraries need is tsc.<p>(Before wireit, using TypeScript and Rollup together was a pain in the ass because you&#x27;d have to fiddle with picking the right TS plugin and configuring it.  This was also often the long pole on doing a Rollup version upgrade.  Decoupling the two makes Rollup way simpler&#x2F;easier&#x2F;nicer to use, which makes wireit awesome even if you don&#x27;t have multiple packages.)<p>It&#x27;s also a good replacement for lerna.  Each of my packages has a publish command that runs `gitpkg publish`.  My root package.json has a publish command that depends on all the packages&#x27; publish commands.  Thus, I can run `yarn run publish` in the root of my monorepo and trust that all of my packages have been published to our git host appropriately.  (gitpkg lets you turn a git host into a private registry, so you can share modules without setting up an NPM registry.)<p>Here&#x27;s a snippet from one of my package.jsons.  They basically all look like this.  (start is complicated because of <a href="https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;wireit&#x2F;issues&#x2F;33" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;wireit&#x2F;issues&#x2F;33</a>.  When that&#x27;s resolved, it will be as simple as the others.)<p><pre><code>    &quot;scripts&quot;: {
      &quot;start&quot;: &quot;yarn run -TB concurrently \&quot;yarn run build:tsc --watch\&quot; \&quot;rollup --config .&#x2F;rollup.config.js --watch\&quot; \&quot;dhost site --bind-all\&quot;&quot;,
      &quot;build&quot;: &quot;yarn run -TB wireit&quot;,
      &quot;build:tsc&quot;: &quot;yarn run -TB wireit&quot;,
      &quot;build:bundle&quot;: &quot;yarn run -TB wireit&quot;,
      &quot;deploy&quot;: &quot;yarn run -TB wireit&quot;
    },
    &quot;wireit&quot;: {
      &quot;build&quot;: {
        &quot;dependencies&quot;: [
          &quot;build:tsc&quot;,
          &quot;build:bundle&quot;
        ]
      },
      &quot;build:tsc&quot;: {
        &quot;command&quot;: &quot;tsc --build --pretty&quot;,
        &quot;clean&quot;: &quot;if-file-deleted&quot;,
        &quot;files&quot;: [
          &quot;src&#x2F;**&#x2F;*.{ts,tsx}&quot;,
          &quot;tsconfig.json&quot;,
          &quot;..&#x2F;..&#x2F;tsconfig.common.json&quot;
        ],
        &quot;output&quot;: [
          &quot;dist&#x2F;**&quot;,
          &quot;.tsbuildinfo&quot;
        ],
        &quot;packageLocks&quot;: [
          &quot;yarn.lock&quot;
        ],
        &quot;dependencies&quot;: [
          &quot;..&#x2F;core:build&quot;,
          &quot;..&#x2F;preact:build&quot;
        ]
      },
      &quot;build:bundle&quot;: {
        &quot;command&quot;: &quot;rollup --config .&#x2F;rollup.config.js&quot;,
        &quot;clean&quot;: true,
        &quot;files&quot;: [
          &quot;dist&#x2F;**&#x2F;*.js&quot;,
          &quot;rollup.config.js&quot;
        ],
        &quot;output&quot;: [
          &quot;site&#x2F;mount.js&quot;,
          &quot;.tsbuildinfo&quot;
        ],
        &quot;packageLocks&quot;: [
          &quot;yarn.lock&quot;
        ],
        &quot;dependencies&quot;: [
          &quot;build:tsc&quot;
        ]
      },
      &quot;deploy&quot;: {
        &quot;command&quot;: &quot;firebase deploy&quot;,
        &quot;dependencies&quot;: [
          &quot;build:bundle&quot;
        ]
      }
    },</code></pre>