Best Practices for TypeScript Monorepo

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

SurveyJS - Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App
With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
surveyjs.io
featured
InfluxDB - Power Real-Time Data Analytics at Scale
Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
www.influxdata.com
featured
  • eslint-plugin-import

    ESLint plugin with rules that help validate proper imports.

  • The exit code is set like that so that the CI will fail on cycles, since we run this in our CI build.

    I also hear people use ESLint, probably this: https://github.com/import-js/eslint-plugin-import/blob/main/...

    The fact that the compiler itself doesn't error on cycle imports, and that the errors caused by those imports are so opaque, seems like an oversight to me.

  • yanice

    Changedetection-Tool for monorepositories

  • I'm dabbling in the monorepo-tool-space for quite a while already and somehow managed to never hear about Turborepo, seems very interesting!

    Just a few years back, the monorepo-tooling-landscape left much to be desired, there were a lot of opinionated 'zero-config' tools out there that always seemed to fall apart the moment you strayed from their happy path. I even went so far to create my own tool (https://github.com/abuob/yanice), in parts because it was fun and taught me a lot and in parts because I simply didn't find something fitting our usecase.

    It's cool that the tooling in this area is getting better and better, monorepos solve a lot of very annoying enterprise problems but require solid tooling to make it work, even when way smaller than google-scale.

  • SurveyJS

    Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.

    SurveyJS logo
  • dependency-cruiser

    Validate and visualize dependencies. Your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.

  • Dependency Cruiser works great, can even render visuals:

    https://github.com/sverweij/dependency-cruiser

    NX[0] also has logic for handling this issue

    [0]: https://nx.dev/

  • nx

    Smart Monorepos · Fast CI

  • Dependency Cruiser works great, can even render visuals:

    https://github.com/sverweij/dependency-cruiser

    NX[0] also has logic for handling this issue

    [0]: https://nx.dev/

  • dpdm

    Detect circular dependencies in your TypeScript projects.

  • I've been using DPDM: https://github.com/acrazing/dpdm

    These are my package.json scripts for detecting cycles:

      "cycles": "run-p cycles:client cycles:server",

  • meta-updater

  • Yes, use pnpm ! I should mention meta-updater [1], which is a pnpm tool which allows to keep your various Json config files in sync across the workspace. Pnpm's own mono repo is a good exemple config of meta-updater which keeps TS project references automatically in sync with the actual dependency tree [2]

    [1] https://github.com/pnpm/meta-updater

    [2] https://github.com/pnpm/pnpm/blob/main/.meta-updater/src/ind...

  • pnpm

    Fast, disk space efficient package manager

  • Yes, use pnpm ! I should mention meta-updater [1], which is a pnpm tool which allows to keep your various Json config files in sync across the workspace. Pnpm's own mono repo is a good exemple config of meta-updater which keeps TS project references automatically in sync with the actual dependency tree [2]

    [1] https://github.com/pnpm/meta-updater

    [2] https://github.com/pnpm/pnpm/blob/main/.meta-updater/src/ind...

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • wireit

    Wireit upgrades your npm/pnpm/yarn scripts to make them smarter and more efficient.

  • etc.

    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.

    In each package'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.

    This provides two benefits:

    1. Iterating across packages is faster, because I don't have to worry about making sure each package rebuilds in the right order if I make a change in a library.

    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.

    (Using TypeScript and Rollup together is kind of a pain in the ass because you have to fiddle with picking the right TS plugin and configuring it. This is also often the long pole on doing a Rollup version upgrade. Decoupling the two makes Rollup way simpler/easier/nicer to use, which makes wireit awesome even if you don't have multiple packages.)

    Here's a snippet from one of my package.jsons. They basically all look like this. (start is complicated because of https://github.com/google/wireit/issues/33. When that's resolved, it will be as simple as the others.)

        "scripts": {

  • turbo-racer

    High-performance distributed remote cache for Turborepo.

  • I am also using turborepo and it has been fantastic! Being able to skip builds from packages that have already been built either in CI or in other developers machines is really amazing.

    If you are not using Vercel caching, I’ve built my own open-source turbo cache backend[1] that can be self-hosted

    [1] https://github.com/brunojppb/turbo-racer

  • joiner

    Multi/Mono-Machine Task Runner

  • The best™ way I found was the dumb way: at emit time (./build, ./dist in package "one") simply copy the new build to all the required dependencies across the local file system (two/node_modules/one/build, three/node_modules/one/build, etc.). It's just dumb enough to be good enough. I stress tested with around 100 packages and it works rather decent, especially when all the packages are using esbuild/nodemon for development and restart on node_modules update. To automate this I have added a "develop"[1] feature in a tool, joiner, I made for running tasks over multi-repos.

    [1] https://github.com/plurid/joiner#development

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts

  • Automating Data Collection with Apify: From Script to Deployment

    4 projects | dev.to | 17 Mar 2024
  • TypeORM - remove children with orphanedRowAction

    3 projects | dev.to | 6 Nov 2023
  • 10 Issues That Will Help You Grow as a top contributor in Opensource 🏅🏅

    12 projects | dev.to | 16 Oct 2023
  • Hacktoberfest 2023 with Ghostfolio

    9 projects | dev.to | 26 Sep 2023
  • How to Write a Great Readme

    14 projects | news.ycombinator.com | 18 Jul 2023