TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Ask HN: Best Tools for Monorepo?

37 点作者 bradhe10 个月前
I&#x27;ve got a monorepo I&#x27;m working in that has a Golang backend with a couple services and a Next.js front-end. Everything lives in a monorepo together. My tooling is super weak, though! For instance, for process management in development I&#x27;m using Goreman, which is a Foreman alternative in Goalng.<p>Wondering what&#x27;s the state of the art for managing the processes in local dev in monorepos in 2024? Or other tools for managing a monorepo I might be missing in general!

23 条评论

theozero10 个月前
I&#x27;ve recently released a comprehensive tool for managing config &#x2F; env vars - <a href="https:&#x2F;&#x2F;dmno.dev" rel="nofollow">https:&#x2F;&#x2F;dmno.dev</a>. It is the only tool I&#x27;ve seen that natively understands monorepos. This means you can reuse config from the root or other services (See <a href="https:&#x2F;&#x2F;dmno.dev&#x2F;docs&#x2F;guides&#x2F;schema&#x2F;#sharing-config-between-services" rel="nofollow">https:&#x2F;&#x2F;dmno.dev&#x2F;docs&#x2F;guides&#x2F;schema&#x2F;#sharing-config-between-...</a>)<p>It is admittedly geared towards JS&#x2F;TS stacks, but supports other languages by running commands via `dmno run -- yourcommand` which will inject the resolved config into your command as env vars. Generating types and adding helpers for other languages should not be too tough. We&#x27;ll follow user demand as to which to implement first.<p>We are currently working on a tool that will help you run and manage your local dev services as well, but it is not ready yet. In the meantime, you can check out <a href="https:&#x2F;&#x2F;tilt.dev" rel="nofollow">https:&#x2F;&#x2F;tilt.dev</a> which is oriented around docker and k8s but does have some ability to just run arbitrary scripts. As for running scripts in general, I&#x27;ve had some success hacking together pnpm and turborepo, even to run scripts in non js&#x2F;ts services. Lastly, I&#x27;ll mention <a href="https:&#x2F;&#x2F;moonrepo.dev&#x2F;">https:&#x2F;&#x2F;moonrepo.dev&#x2F;</a> as it has more native support for polyglot repos, and its notion of task inheritance keep things fairly clean, especially in a larger repo with many services.
评论 #41123032 未加载
beepbooptheory10 个月前
Have just reorganized my personal monorepo to be totally based around nix: each package just has a default.nix and .envrc, with latter containing something like: &quot;use flake .#package&quot;. The default.nix can be a regular package, npm package, python, common lisp, etc, and can reference anything else in the repo. The only housekeeping in flake.nix is adding lines like:<p><pre><code> packages.foo = pkgs.callPackages { }; devShells.foo = pkgs.mkShell { inputsFrom = [ packages.foo ]; </code></pre> There are some special considerations around devShells: I don&#x27;t need inputs on an npm package, for example, or that I want to include the asdf package itself within its own devShell for lisp. Have made a few wrapper funcs like &quot;mkLispDevShell&quot; and &quot;mkNpmDevShell&quot; to handle this.<p>This isnt perfect I know with all the housekeeping, but it balances itself out in terms of flexibility. For example, I can trivially create a relatively simply &quot;assets&quot; package&#x2F;derivation that is both just a folder a files assured to be somewhere during a build that needs it, as well as be a simple lisp package that interfaces with those files. And prod builds can become almost entirely nix derivations that have inputs from across the repo and are defined by simple inline scripts: &quot;nix run .#prod-server&quot;.
lbhdc10 个月前
I&#x27;ve worked in a few monorepos, and organize my personal projects into a monorepo. The most common tool I have seen to manage them (and what I use for my personal stuff) has been bazel.<p>The first monorepo I worked in was a python&#x2F;typescript monorepo. It largely grew organically, and was heavily iterated on. We had no tooling to manage the complexity, and constant bumped into sharp edges that made life difficult.<p><pre><code> - Dependencies change and silently break applications or developer environments. - Figuring out how to start up applications you didn&#x27;t work on could be difficult because you needed to figure out the tool chains and how to invoke them. This painpoint came up everytime toolchains changed. - Figuring out where dependencies were used was really hard. This lead to lots of zombie code, we weren&#x27;t sure if it was alive or dead. </code></pre> There are a bunch of &#x27;meta&#x27; tools for this, bazel, pants, buck, gradle, etc. Professionally I have only seen bazel used. I suspect its less to do with the tools themselves, but more to do with the ecosystem.<p>With that being said, bazel does seem to solve most of the sharp edges we had with our ad-hoc&#x2F;no tooling, but it comes at a cost. Bazel is not trivial, and won&#x27;t allow you to do some things that the underlying toolchain might have been okay with. So that may leave you making code changes to fit inside bazels constraints.<p>Bazel tooling also isn&#x27;t equally mature across all languages. The go tooling is pretty mature, and there are great generators that &#x27;make things work&#x27;, the situation for frontend is less mature, but getting better. It will add additional friction that webdevs might not love.<p>At the end of the day though, I would choose to use something like bazel (or one of the alternates), and the friction it brings over not having it.<p>Example bazel frontend. <a href="https:&#x2F;&#x2F;github.com&#x2F;bazelbuild&#x2F;examples&#x2F;tree&#x2F;main&#x2F;frontend&#x2F;next.js">https:&#x2F;&#x2F;github.com&#x2F;bazelbuild&#x2F;examples&#x2F;tree&#x2F;main&#x2F;frontend&#x2F;ne...</a>
zokier10 个月前
buck2 is arguably the state of the art currently, it is developed by meta based on the learnings from their own buck tool and bazel(&#x2F;blaze), and others:<p>&gt; The retroactively named Buck1 was a capable build system and is still in use today at Meta (although many users have migrated). Buck2 is a rewrite that aims to keep the best bits of Buck1 (with a high degree of target compatibility) but also borrows ideas from academic research and build systems, including Bazel, Pants, Shake, Tup, and more.<p><a href="https:&#x2F;&#x2F;buck2.build&#x2F;docs&#x2F;about&#x2F;why&#x2F;" rel="nofollow">https:&#x2F;&#x2F;buck2.build&#x2F;docs&#x2F;about&#x2F;why&#x2F;</a><p>I&#x27;d say the two main tradeoffs to consider is do you want something very general-purpose, or is something more specific to certain language(s) appropriate? and do you want mature ecosystem, or bleeding edge solution?<p>Bazel&#x2F;buck2 are very general and language agnostic, while something like nx is more focused on JS with some support for other languages. Bazel is pretty mature at this point, while with buck2 you might need to do more trailblazing yourself.
评论 #41123003 未加载
zactato10 个月前
I worked on tooling for a fairly large JDK based monorepo using vanilla gradle + some custom tooling. It worked well until we acquired companies and became more polyglot. If I were doing it again today I&#x27;d probably go with Bazel
bbor10 个月前
Hmm I’ve always just done monorepos for organizational reasons, like forcing synchronicity between backend and frontend versions. The actual apps themselves have always been the same ol’ folders with the same ol’ build tools, deployed via individual commands (I personally use Dokku but I imagine all PaaS is similar). Can someone vaguely gesture at what I might be missing out on?
the102410 个月前
There&#x27;s a decent (if fairly biased) comparison on monorepo tooling here: <a href="https:&#x2F;&#x2F;monorepo.tools&#x2F;" rel="nofollow">https:&#x2F;&#x2F;monorepo.tools&#x2F;</a><p>Note that it&#x27;s written by nx.dev (TS monorepo tool), so well worth taking the specific comparisons with a large grain of salt. Useful to understand what is out there though!
0x63_Problems10 个月前
This might be helpful: <a href="https:&#x2F;&#x2F;monorepo.tools&#x2F;" rel="nofollow">https:&#x2F;&#x2F;monorepo.tools&#x2F;</a><p>Although I&#x27;m not sure process management is touched on specifically. I&#x27;ve used docker compose for a similar purpose in the past, with source code in a volume to support live reloading.
LocalPCGuy10 个月前
I&#x27;ve been using Nx (<a href="https:&#x2F;&#x2F;nx.dev&#x2F;" rel="nofollow">https:&#x2F;&#x2F;nx.dev&#x2F;</a>) for a while now, but primarily on a front end set of apps currently. While it started as a TS&#x2F;JS monorepo tool, it has evolved into something that (they claim) can be used for just about any language. You will probably still see it&#x27;s roots as a TS&#x2F;JS based tool though. It&#x27;s not been without it&#x27;s challenges, but overall I&#x27;m fairly happy with it.
评论 #41123577 未加载
UmWhatever10 个月前
As someone who had never used a monorepo before and wanted to set one up for the first time, <a href="https:&#x2F;&#x2F;www.pantsbuild.org&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.pantsbuild.org&#x2F;</a> seemed intuitive to me and of an apparently good provenance. Their Slack community also answered every question I had and righted my wrongs 100% of the time, which went a long way.
elliotbnvl10 个月前
We have a very similar setup (except s&#x2F;Next.js&#x2F;Remix) and went with npm workspaces + Task [1], and it&#x27;s working really, really well so far. This is our second iteration of a monorepo (first one was a straight React SPA bundled with Vite instead of Remix).<p>We have a root Taskfile that references our JS and Go taskfiles and wraps &#x2F; abstracts all tasks. It&#x27;s good for dependency management and task orchestration (`task lint` will run lint in both JS and Go for example, and `task test` does the same).<p>TypeScript sharing between packages can be a lil&#x27; funky, but so far it&#x27;s super solid. Happy to share more if it would be helpful.<p>The nice thing is that this just relies on npm, which means setup is simple and straightforward, and we benefit from all of the stability and continual improvements npm brings to the table.<p>[1]: <a href="https:&#x2F;&#x2F;taskfile.dev&#x2F;" rel="nofollow">https:&#x2F;&#x2F;taskfile.dev&#x2F;</a>
withinboredom10 个月前
Probably my best experience was when I was given a vm running somewhere. I could sync the remote folders to my own computer, but any change I made on that machine would trigger a build. I could also request ops to send traffic to that machine, and I&#x27;d get some mirrored production traffic.<p>I just used git in my home folder and it &quot;just worked.&quot; Code reviews were pretty simple; the folder&#x2F;file in the code review matched what was in your home folder.<p>It was pretty nice with a good .gitignore setup, so you could have your own dotfiles on the vm. There were also some really good scripts (you shared them by branch `git checkout jims-scripts -- .&#x2F;scripts` or by commit—you didn&#x27;t need review to commit new script files, but it was encouraged).
cjr10 个月前
This might be more suited to monorepos where all projects are in JS&#x2F;TS, but check out <a href="https:&#x2F;&#x2F;onerepo.tools" rel="nofollow">https:&#x2F;&#x2F;onerepo.tools</a>
kalib_tweli10 个月前
Makefile and docopt. No muss, no fuss. No &quot;works on my machine&quot; issues.<p>I&#x27;m running a hand-rolled monorepo with ansible, terraform, and several language projects (JS&#x2F;TS, Swift, Ruby) that each have a makefile to standardize entrypoints for CI&#x2F;CD. Docopt is nice because it&#x27;s self documenting so you can better understand how all your apps are deployed.
no_way10 个月前
In our projects we use Moon <a href="https:&#x2F;&#x2F;moonrepo.dev&#x2F;moon">https:&#x2F;&#x2F;moonrepo.dev&#x2F;moon</a> extensively, it supports multiple languages and quite a few features.<p>For me personally I like that it updates Typescript references automatically and makes docker image setup far easier.
评论 #41124390 未加载
bhouston10 个月前
I have this template project for Node.js&#x2F;NPM monorepostories: <a href="https:&#x2F;&#x2F;github.com&#x2F;bhouston&#x2F;template-typescript-monorepo">https:&#x2F;&#x2F;github.com&#x2F;bhouston&#x2F;template-typescript-monorepo</a>
thesardorbek10 个月前
This one I used a few times, might be useful for your case.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;simplesurance&#x2F;baur">https:&#x2F;&#x2F;github.com&#x2F;simplesurance&#x2F;baur</a>
_lucc10 个月前
IMO it’s language dependent.<p>Thinking back on my work experience I’ve worked on:<p>1. Pure JS&#x2F;TS 2. JVM&#x2F;Kotlin&#x2F;Java 3. Polyglot Kotlin+Python 4. Polyglot JVM+Cpp+TS+Python<p>I’ll address each one and what I used at the time.<p>But first I’ll address my dev flow for a greenfield project. Initially after some cursory documentation I build a scaffold. Over the years my scaffold has pretty much boiled down to two main directories, packages and services. Packages expose functionality, services consume functionality from packages and distribute it over RPC. It’s served me well.As for service standup, it goes: local host to incubate it, docker compose to integrate it and develop , kubernetes to deploy it.<p>For the pure TS code base, at the time I used yarn workspaces and lerna. This worked well at the time and I had no complaints from what I can remember. I think I remember having to volume mount my whole repo into each individual service to get hot reloading working, which was no fun.<p>For Pure JVM stacks, I found gradle was the way to go. It seems like a pain in the ass at first but once you grok it, and stay on a stable version it rocks. You can orchestrate whole workflows in it.<p>Polyglot Kotlin and Python. So I went about this a couple ways until I settled on something I liked. First I said, ahh yeah gradle can do everything, so I wrote a poetry wrapper and had my python services pretend they were like JVM services. This ended up not working so well in the long term. Especially because python library sharing is a lot different than JVM. The I went for a hybrid approach where there were multiple layers. Gradle for JVM code, poetry for python code. This was good but switching context kinda sucked and there were too many commands to remember, and ctrl+r history and tab only gets you so far.<p>For the last one, Polyglot JVM, Cpp, Python, JS&#x2F;TS… I think I finally have something I’m happy with (for now at least), like I feel productive and I don’t dread having to do like anything in the codebase. The final touch was, take the gradle for JVM, poetry for Python, use turbo repo with pnpm in a web directory for all your JS&#x2F;TS code. I then tie everything together in a combination of gradle scripts but more importantly, a python tooling package that uses click cli and poetry. The python tooling package has logic for anything I want to script, and I expose a CLI for it. Then I have one of my modular make files expose the functionality by calling into the python package.<p>Seems like quite the contraption but it works.<p>Judging from other comments I might want to check out bazel.
评论 #41122533 未加载
gigatexal10 个月前
<a href="https:&#x2F;&#x2F;github.com&#x2F;korfuri&#x2F;awesome-monorepo">https:&#x2F;&#x2F;github.com&#x2F;korfuri&#x2F;awesome-monorepo</a>
aseipp10 个月前
The build system is a key component. If you are working primarily in one language with one set of consistent tools that work together, then you can likely get by with just using whatever tools your language offers. Apparently, people have great success in the JS&#x2F;TS world with tools like pnpm&#x2F;turborepo. It&#x27;s totally fine and common to just put everything in one place with one build tool if that&#x27;s all you really need.<p>Even if you only have like, 2 languages, often it is possible to stitch the tools together, if you don&#x27;t go too far off the trodden path, and you understand the two well.<p>But that leads to the two most important questions: &quot;Do you need to support multiple languages&quot; (N = 3 or more I&#x27;d say) and &quot;Do you need to support incremental caching&quot; (including test results.) Once that happens, it becomes very difficult to properly express dependencies and cache artifacts, and it becomes increasingly difficult to expect every developer to consider all the possible interactions between the tools. That means builds take longer (no big cache), and it&#x27;s easier to break them (missing dependencies) or make them slow (overly conservative dependencies).<p>If the answer to both of these questions is &quot;Yes&quot;, then you need to take serious looks into solutions like Nix, Bazel, or Buck2 to manage your dependencies accurately and cache the results of your builds incrementally. All of these are, quite frankly, going to be difficult to adopt if you are not familiar with them. All of them can save you an incredible amount of pain and effort, too. It&#x27;s sort of inherent to the problem space; building software is often more complex than we think -- part of the reason why simple single-language tools have so much appeal! -- and has a wide array of nuanced requirements.<p>Note that the common wisdom is that Nix&#x2F;Buck&#x2F;Bazel are often only needed at very large scale. That&#x27;s true in the sense they are nearly mandatory, but there&#x27;s a flip side, which is that it&#x27;s often easiest to adopt those tools <i>early on</i> at a small scale, when there is the least amount of technical debt and smallest amount of impedance mismatch, and you can sort out those problems proactively. It&#x27;s much easier than solving them all after the fact.<p>All of these tools will require some amount of dedicated engineering to keep them well maintained and oiled with all the modern conveniences (LSP support, packaging end-result artifacts, etc.)
评论 #41123368 未加载
tracker110 个月前
docker-compose and shell scripts are my general go-to. I tend to push for the use of WSL for Windows environments, which helps with these kinds of tools. I&#x27;ve also used deno+shebang for shell scripting as well, which can work fine with the msys tooling (git-bash installed with git for windows).
taejavu10 个月前
For JS&#x2F;TS, you can get a surprisingly capable monorepo with nothing more than pnpm + changesets.
AbuAssar10 个月前
Could you please elaborate on the tangible advantages of adopting a monorepo structure?