I've used it but recently moved back to plain claude code. We use claude at the company and weirdly the experience has become less and less productive using opencode. I'm a bit sad about it as it was the first experience that really clicked and got great results out of. I'm actually curious if Anthropic knows which client is used and if they negatively influence the experience on purpose. It's very difficult to prove because nothing about this is exact science.
For node applications, startup time is impacted by IO a many files is less nice for IO wait times. So bundling does make a material impact for non-bundled backend applications and large libraries. I do agree, most impact is had when using bundling at a moment closer to the deployment.
I use it to compile backend code. For those use-cases, IMO, vite itself is not so interesting (although I do use vitest). Using tsdown gives me a simplified API to compile my BE code so I can publish it to NPM. Nothing more nothing less. It’s faster and less work to orchestrate using TSC for CJS and ESM output, so very high ROI for me.
I’m using tsdown for a collection of packages and am switching a current project (https://flystorage.dev)over to it. I use it in “unbundle” mode, which doesn’t bundle but does file for file transpilation. To me, it’s an opinionated rolldown configuration with a simplified API. You can script up in a couple of lines of code which packages in a monorepo to compile and what formats to compile for. An example of that can be found here: https://github.com/duna-oss/deltic/blob/main/tsdown.config.t...
Compared to using plain tsc to compile the code, is that it’s a lot quicker. The compiled code has some odd conventions, like using void 0 instead of undefined, but … whatever works!
So far, it has been an easy-entry high-ROI tool that helps me publish TS/JS tools quite easily.
Resolving by hash is a half solution at best. Not having automated dependency upgrades also has severe security downsides. Apart from that, lock files basically already do what you describe, they contain the hashes and the resolution is based off the name while the hash ensures for the integrity of the resolved package. The problem is upgrade automation and supply chain scanning. The biggest issue there is that scanning is not done where the vulnerability is introduced because there is no money for it.
While you might see them as parasites, their community reputation may be very different. To fit into your scenario, you may need to get work from the other bums.
This I would strongly dispute. I’ve seen it first hand many times that developers who ignore such things are definitely finding the negative consequences of it. It takes very careful maneuvering not to get burned, either by reputation damage or to burn out.
I’ve given up on hopes of having funding on open source. My open source packages account for about 1.2% of all PHP code downloaded from Packagist (package manager) but unless there is a commercial effort behind it, I do not see it happening. A couple devs in highly hyped companies is able to generate a following big enough to solicit some non trivial amount of funding but the majority just doesn’t care enough about it to fund it. In the end, is open source maintainers are stupid enough to give our code away for free, so who’s really to blame for this. Perhaps it’s an overly pessimistic view, but not a view that has historically been disproven.
A bit unfortunate they used the term domain model here. Domain models here are purely data-centric, whereas domain modeling focuses mainly on behavior, not underlying data structures. The data that is used in domain models is used to facilitate the behavior, but the behavior it the code focus.
From a modeling perspective, there is certainly inherent complexity in representing data from domain models in different ways. One can argue though that this is a feature and not a big. Not the same level of nuance and complexity is needed in all of the use-cases. And representational models usually are optimized for particular read scenarios, this seems to mandate argue against that, favoring uniformity over contextual handling of information. It will most likely scale better in places where the level of understanding needed from the domain model is quite uniform, though I have seen most often that use-cases are often complicated when they do not simplify concepts that in their code domain model is very complex and nuanced.
Saying “hire good people and give them room to do good work” is bad advice is the same as judging a dish while using half a recipe. It’s execution centric and execution alone is never enough, you need direction. A strategy, a vision, a need. Without a need from a customer it’s nothing.
One thing that consistently bugs me is how upgrading from the lowest type of runners to _literally_ anything else renders your paid for included minutes useless. I do not understand who those wouldn't just be multiples of the base runner, much like how Mac and Windows runners are. Seems like the crediting logic is there, but knowing software, there is probably some accidental complexity causing this part not to leverage it. That said, it's very frustrating from a paying customer perspective.
The same goes for minute crediting, where splitting things up to run concurrently is actively discouraged because they individually all round up to the next minute. For example; have 3 concurrent tasks that run 1m10s? You're billed 6 minutes. I get that a run would be rounded up, but come on.
As somebody who's spent over a decade making interactions with filesystem easier, I really understand why somebody would be tired. I originally made Flysystem for PHP to reduce the consumer-end complexity of using many types of filesystems (S3, FTP, SFTP, GCS, GridFS). I've recently made the move towards the TypeScript ecosystem, for which I've built https://flystorage.dev (a TS equivalent of Flysystem). Looks like this could be an easy adapter to include. Will put it on my research list, thanks for sharing!
I look more towards optionality myself. Take for example the encapsulation of randomness. Depending on an abstract notion of randomness (an interface) that decouples you from the implementation is both useful for testing as it is for maintenance of a system. For tests, removing randomness entirely makes it deterministic, allowing you to tests for exact matches instead of approximations. For systems, at a smaller scale get away with a reduced amount of randomness, while systems at scale require more sophisticated code for this. You don't want to replace all of that code in all instances, but rather leverage the capability and replace the implementation.
Another angle is the encapsulation of storage. Using in-memory storage for tests makes Ci pipelines very quick and production storage might evolve over time to accommodate scaling requirements (sharding and such).
I must add that it's mostly mocking libraries that auto-generate mocks that are the culprit here. They're quick to introduce, but once introduced make it harder to change the implementation as the implementation logic is now replicated in N instances of tests. More surface area, more friction for change. Many mocking libraries also allow you to fixate behaviour that is incompatible with the actual implementation, especially in dynamically types languages.
Mocking, when it is a large part of your test setup, makes your test focus on the blueprint of the implementation rather than the outcome of a unit of behaviour. This causes the tests to break relatively soon when the implementation changes. When a test does not use mocking and rather treats the code as a sealed box, the tests are more stable. Stable tests yield better guarantees for stable outcomes even when the underlying code is (radically) changed/refactored. Using mocking frameworks usually makes refactoring harder, as changing the underlying code immediately invalidates the test. Changing the tests and code in unison makes changes less safe.
Most solutions on their own don't improve things a whole lot. Yet, in a system of supporting practices, it can be very powerful. The primary thing is you need a system, not just the individual parts. Testing without changing the design of your code is a horrible experience. Applying techniques like dependency inversion/injection has a positive effect on isolating behaviour which makes testing easier. Making code more deterministic makes tests easier. Pushing out side-effect from your core logic makes testing easier. All of those things add up to more than the sum of it's part, which is the an indication of dealing with a system.
If you fall into the case where every team is forced to work around the platform and create their own solution, the problem is not enforcement, it's offering. The thing that is offered is not working for the teams and there is a negative impact because of it. Teams building their own solutions, for a while, after which they are consolidated into a platform offering is a healthy cycle. What is IMO unhealthy is a dysfunctional platform where product people are forced to endure it. I'd much rather empower teams to take on their own impediments then to suck away their motivation by not letting them fix whatever is holding them back.
Sorry in advanced if I state this a little bluntly, but this rhetoric of teams going off and building the same tools all over the place is in my experience not a fault of any team, it's that of the context/organisation they operate in. Framing it as such is IMO destructive for company culture. As if product teams, left to their own, will just degrade into building sub-par platform-esk tools that ruin the org. I don't buy it. Trying to make one thing do two things (the single source of tech complexity) is a trap often catching platform engineers who try to tailor to an audience that is not unified in their needs, still platform teams are incentivised to create just that.
I recognise the friction points very well. It's very frustrating and limits product team velocity. That said, in my experience this is mainly due to a misinterpretation and mis-implementation of platform teams. Too often, platform teams are forced upon product teams. This misses an essential element of a platform, optionality. A platform should be a jumping board, that people can choose to accelerate development. When a platform is made mandatory it misses essential feedback mechanisms, such as rate of adoption, for it to steer in the right direction. While the rate of adoption is still often seen as a metric for a platform team's success, the mandate to enforce the platform onto product teams is fundamentally corrupting. In addition, the tools to truly accelerate development are not the same as time progresses. Without optionality, there is never the incentive to sunset anything the platform provides. Deviations of technology/pattern/solution use are often seen as negative aspects of the product team's performance, but rarely reflect back on the platform team's output.
TLDR; platform teams without product team's freedom to deviate (optionality) is corrupt and can destroy a large chunk of engineering velocity.