I also tend to advise people not to write so many services -- a generation of developers has entered the workforce thinking "cloud native microservices" are the only way to factor software of any kind -- but I also caution people not to make everything a library either. Libraries have maintenance costs that have to pay off overall, and I consistently see people underestimate those costs when first making a library.
Any library used by more than one project faces friction making almost any kind of changes, especially if the ideal form of the change breaks backwards compatibility even a little bit. Even if it's used by only one project (an unfortunate antipattern some teams fall into), it still introduces friction to individual changes, which is worse in some languages than others because even just testing against a WIP version of the library might be a whole tangle that everyone seems to reinvent "workspaces" to try to mitigate even a little.
I now urge people to keep closely related projects in a single repo with purely internal libraries, so you can make backwards incompatible changes because you fix them for all consumers within the same commit that made them. This is like a monorepo but only for closely related projects.
It cuts out a lot of the friction of updating shared code, so it's a good way to avoid tech debt and keep both the library and its users evolving. This was inspired by working in an actual monorepo for years, but avoiding the size of repo where you can no longer make every related change in the same commit.
When an internal library's API surface has proven to work well for several projects and for long enough to be considered stable, then it can be spun off as a standalone library, and whatever warts slowly form there are probably acceptable in return for the wider reuse.