Skip to content

Instantly share code, notes, and snippets.

@kylecordes
Last active August 30, 2022 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylecordes/b864919083304b8e155187b646e03357 to your computer and use it in GitHub Desktop.
Save kylecordes/b864919083304b8e155187b646e03357 to your computer and use it in GitHub Desktop.

Add Nx to the Qwik repo?

Kyle Cordes, August 30 2022.

(I have used Nx a lot. With my team at work, we adopted it a couple months after it shipped, both for various internal projects and on several large customer projects.)

Nx, broadly

A note on naming: Nx thinks of the world as a Nx “workspace” containing many “projects”. Which I think is mostly a great naming convention. Except that it does not match Yarn’s naming convention.

Nx began life as a tool for Angular monorepos - its creator(s) came from the Angular team. After a few years incubating in this environment, Nx expanded its scope substantially and effectively as a monorepo tool tool for the npm ecosystem and (to a limited extent) beyond.

Nx understands an interproject dependency build graph, and uses that to cache intermediates and artifacts. It's a big improvement to developer experience as a project grows. That's why we use it where I work, extensively.

Nx without Yarn workspaces/etc

When running without aid of Yarn Workspaces or similar technology, one of the more notable characteristics of Nx is that it enables/enforces the "single version policy", such that many projects sharing an Nx workspace all rely on just one package.json, and therefore just one version of every dependency and transitive dependency. This has worked very well for groups of related projects; and it's a great default. Until somewhat recently, this would also exclude Nx from projects which are not suitable for such a dependency policy.

Nx defines a manner separate from package.json, to describe each individual project, the various operations (build steps) applicable to that project, their inputs and outputs, etc.

For projects within those constraints, Nx provides some nice benefits, around caching, parallelization, etc. That constraint became annoying though, so…

Nx with Yarn Workspaces

Many users noticed that some of Nx’s most important features, like understanding a bill dependency graph and caching artifacts, don't rely on the single version principal, nor on moving build step logic into Nx-specific plug-ins.

So nowadays, Nx can be used in projects that don't care about the Nx way of defining build steps, and which don't care about a single-version policy; you can treat it as a caching-and-building addon to (for example) Yarn Workspaces. That is documented here:

https://nx.dev/recipe/adding-to-monorepo

The unknown (to Kyle, writing this)

Here is the point where my experience reaches its edge, not having done this specific thing in a nontrivial project yet. There is a boundary between Nx working to cache/etc. the build operations of a project that doesn't have Nx-level configuration for each build/etc step, i.e. which doesn’t use (or write) Nx plugins to support each kind of artifict to be built. At that boundary, I do not know how well or easily Nx handles builds in partly-Nx-ified projects. It would be prudent to assume that, if Nx is adopted, the logical endpoint would be increasingly complete adoption over time, to where the logic to build each part of an overall system moves away from package.json files and standalone scripts, and into Nx-specific JSON config files, and Nx-specific Typescript plugins.

Comparison to Bazel

I am also quite familiar with other build systems, especially Bazel. I'm a big fan of Bazel for big things; but it is tough to recommend Bazel for projects that work entirely in the Node ecosystem, with contributors, evaluators, etc. concentrated in that ecosystem. A Nx project might feel very slightly weird to some contributors, but a project requiring Bazel to build can feel notably alien. On the other hand, the Rust code in Qwik would be on even footing with TypeScript/Node, if they coexist in a Bazel workspace, which is nice but probably not especially vital, as the Rust code is likely to have fewer contributors than the other parts of the Qwik repo.

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