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.
HN user
frankdejonge
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.
I believe that why they said "if not revenue growth". Those successful, yet unprofitable companies do have revenue growth, or market share growth.
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!
Seeing that Washington granny smith apples are not the cheapest in Washington is pretty odd.
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.
You had me until Lisp.
Correct me if I’m wrong, but I don’t think RedPanda is a database. I see it as a streaming data solution, which the novelty factor can be discussed as well, since it’s basically Kafka.
I don't mean to beat down on this article, but the bar set here seems pretty low. Many of the aspects detailed in the article, to me, fall under the responsibility of engineers well below principal level. Suggesting to use, and using, best practices should be expected from people at senior level. Leading initiatives that span multiple teams is a common expectation for staff level engineers. For me, the distinguishing factor between pre staff and staff and above is strategy. Ensuring the technical decisions are made strategically (in alignment with or acknowledgement of longer term business goals), where before the focus is largely tactical (how you execute). That said, I think the shift described is an essential shift for many engineers going up the ladder, although for some the titles don't match the point where this becomes relevant.
In the Netherlands, countersteering is part of any motorbike practical exam. This is not standard in a lot of companies, but it is such an essential skill. It literally saves lives.
Back up in The Netherlands
Any intention to implement Redis Streams?
Any exposed information should be exposed deliberately. Although I didn't cover it in this post. In my event-driven setups, events are always wrapped in a message envelope data structure. Where a message is contains 1) the event/payload and 2) a set of headers to carry more "system-y" data, like time of recording, system of origin, and other observability related information. The event ID is one of those values.
I've worked on a real-time dashboard for operational insights for an airport once where they initially used eventstore to do effectively the same thing. We ended up replacing eventstore with a similar setup using typescript and kafka, instead of storing the projections into a new topic we used a mysql and redis as a storage backend. Worked quite well, especially in the cases where there was some more interaction needed with external systems. I haven't worked with Kafka Streams yet, but sure sounds like a worthwhile investment to spend some time with.
For anyone who's interested in the outbox pattern, I also blogged about that: https://blog.frankdejonge.nl/reliable-event-dispatching-usin...
If I understand your forth type correctly, it's like snapshotting in an event-sourced system. For me those are only internal and not meant to be communicated, rather they are there to speed up reconstitution of an event-sourced aggregate. I might be misunderstanding your point tho.
With regard to your first point, in terms of communication, they serve very similar integration patterns. I imagine you've standardised the consumption of these events, making it transparent if the event is linked or attached. Is that correct? In such cases, there's one difference, which is the out of sync state; the situation where the state has been altered after the signal was dispatched but before it was consumed. Is that something you deal with?