HN user

dfabulich

10,272 karma

I'm Dan. I co-founded https://www.choiceofgames.com/

Choice of Games is the world’s largest publishing house for interactive novels. Our award-winning games are entirely text-based—hundreds of thousands of words and hundreds of choices, without graphics or sound effects—and fueled by the vast, unstoppable power of your imagination. Choose your path: your choices control the story.

dan@fabulich.com @dfabu

Posts99
Comments886
View on HN
news.ycombinator.com 6d ago

Chrome is prototyping HTML client-side includes

dfabulich
3pts0
danfabulich.medium.com 24d ago

You can export/import passkeys now, but only on iOS

dfabulich
3pts0
webkit.org 4mo ago

WebKit Features for Safari 26.4

dfabulich
2pts0
danfabulich.medium.com 5mo ago

Chrome will make popular scripts load faster (by picking winners)

dfabulich
7pts0
danfabulich.medium.com 8mo ago

Beautify Your RSS/Atom Feeds in Browsers Without XSLT

dfabulich
2pts0
github.com 8mo ago

Show HN: Style XML Feeds Without XSLT

dfabulich
2pts0
developers.facebook.com 8mo ago

Platform Evolution: Facebook Social Plugins to Be Discontinued February 2026

dfabulich
17pts5
danfabulich.medium.com 8mo ago

Google Play's new "discount offers" charges higher prices in older app versions

dfabulich
4pts0
survey.devographics.com 10mo ago

State of JavaScript 2025 Survey

dfabulich
1pts0
groups.google.com 10mo ago

Chrome Intent to Prototype: Email Verification Protocol

dfabulich
2pts2
www.filfre.net 10mo ago

Choose Your Own Adventure

dfabulich
6pts0
jakearchibald.com 10mo ago

Making XML human-readable without XSLT

dfabulich
8pts2
danfabulich.medium.com 11mo ago

LLMs generate slop because they avoid surprises by design

dfabulich
1pts0
danfabulich.medium.com 11mo ago

LLMs tell bad jokes because they avoid surprises

dfabulich
140pts145
danfabulich.medium.com 11mo ago

Surprising, but Inevitable: Stories, Jokes, Puzzles, and Proofs

dfabulich
1pts0
danfabulich.medium.com 11mo ago

Passkeys are just passwords that require a password manager

dfabulich
156pts219
danfabulich.medium.com 12mo ago

WebAssembly Won't Get Direct DOM Support Any Time Soon

dfabulich
4pts0
danfabulich.medium.com 1y ago

All four major web browsers are about to lose 80% of their funding

dfabulich
639pts633
store.steampowered.com 2y ago

Coming Soon: Security improvements for managing builds and Steamworks users

dfabulich
2pts1
www.wsj.com 3y ago

Google Violated Its Standards in Ad Deals, Research Finds

dfabulich
16pts2
survey.devographics.com 3y ago

Take the State of CSS 2023 Survey

dfabulich
2pts0
gizmodo.com 3y ago

Wizards of the Coast Breaks Silence on Dungeons and Dragons' Open Game License

dfabulich
6pts1
2022.stateofjs.com 3y ago

State of JavaScript 2022

dfabulich
78pts106
stateofcss.com 3y ago

State of CSS Survey 2022 Now Open

dfabulich
1pts1
github.com 3y ago

Isolated Web Apps

dfabulich
1pts0
techcrunch.com 4y ago

Microsoft rolls out access to the Amazon Appstore Preview in Windows 11

dfabulich
3pts0
daverupert.com 4y ago

When it comes to complaining about web browsers

dfabulich
2pts0
twitter.com 4y ago

Google shifts Material Design library for iOS into maintenance

dfabulich
1pts1
en.wikipedia.org 5y ago

Warnock's Dilemma

dfabulich
3pts1
danfabulich.medium.com 5y ago

Google can ban your Android app if they think you’ve clicked on your own ads

dfabulich
1049pts393

Yes, I did. When you set up a passkey on your phone in your password manager, you'll transfer it to your other device using your password manager.

Either your password manager will automatically synchronize for you, or you can transfer your passkey to another password manager that will do the synchronization, via the finicky app-to-app transfer system (Credential Exchange Protocol). You can transfer from Apple to Bitwarden and vice versa.

The family sharing question was added later, but the answer is: all of the major password managers have finicky family-sharing features for passwords and passkeys.

For passwords, most people don't bother with formal family-sharing features, and just share passwords via copy and paste. For passkeys, you have to use the family-sharing features, which means you and your family member have to use the same password-manager vendor to share those passkeys.

It’s up to you to decide whether protecting yourself from being tricked into exporting your passkeys is worth sacrificing your ability to read them.

All of the major operating systems and all of the major browsers are password managers. Apple, Google, Microsoft, and Mozilla are all password managers. They all have apps that let you access their password managers on other operating systems.

You're right that all of the major password managers like their lock in. The Credential Exchange Protocol is just barely good enough that OS vendors can say they "support" it, but tricky enough to find that ordinary users probably will never try it. (Not to mention that it doesn't even work yet on Windows or Android.)

As for attestation, the good news is that Apple always returns 0s for the attestation ID (because Apple, like you, opposes it as a side channel), and so any public site/app that insists on attestation would reject all Apple devices. This gives smaller password managers like Bitwarden sufficient cover to 0-out their attestation as well.

"Most" apps? So it works in some apps, but not others?

Setting your preferred password/passkey manager on Android 17 to 1Password works fine in Chrome and Firefox to log in to any site, presenting passkeys managed in 1Password. It also works in all of Meta's native apps. (I'm pretty sure it works the same in Bitwarden.)

Whatever issue you're having, it's not an inherent limitation of Android passkeys. It might be a bug in your passkey manager…?

Every single major password manager supports export.

They all support exporting passwords, but, check your CSV; you won't find any passkeys in the CSV export for Apple, Google, Microsoft, Mozilla, 1Password, or LastPass.

(Bitwarden, Proton Pass, and KeepassXC do support exporting passkeys to CSV, which undermines the phishing protections, at least somewhat. It’s possible to trick you into exporting your passkeys from Bitwarden and sending the file to an attacker. It’s up to you to decide whether protecting yourself from being tricked into exporting your passkeys is worth sacrificing your ability to read them.)

How useful is your firefox passwords on an iphone?

Did you try it? That's the primary feature of the Firefox app for iPhone.

(Especially since the Firefox app for iPhone is just Safari's WebKit wearing a Firefox disguise.)

Or Mac OS's keychain I use as a daily driver on my windows gaming desktop?

https://apps.microsoft.com/detail/9pktq5699m62?hl=en-US&gl=U...

With the iCloud for Windows app, you can access photos, files, passwords, and other important information from your iPhone or other Apple devices on your Windows PC.

When Apple's your password manager, you use Apple's password manager app to synchronize passwords and passkeys.

Sure, that's alarming, but if you set up a passkey on the "wrong" password manager, you've (temporarily) lost your passkey. You should probably be kinda alarmed about that.

You can click "try another way" and use your password, and then you'll have access to your bank. But then, you should try to resolve that problem. If you (or a trusted friend/family member) can figure out how to use settings to remove the passkey from your bank's account settings, you can do that, or you can ask a bank teller to help you, instead.

(And, luckily, you won't need a bank teller, because you'll still have access to your account.)

I don't think you're giving those seniors good advice. When the banks ask people to "switch" to passkeys, they're not removing the passwords; they're adding passkeys as an alternate login mechanism.

If you lose your bank passkey, (e.g. if you put it in the wrong password manager and you can't figure out where it is) you can just sign in with your bank password.

In the worst case, banks actually don't make it very hard for seniors to reset your password/passkey; just show up at a branch with photo ID, your bank card, and your PIN, and a teller will help you reset your credentials. They do it all the time.

And, remember, seniors could also put a randomly generated password into the wrong password manager. In that case, they'll either have to reset their password, or they'll have figure out what they did, retrieve their password from the OS password manager, and transfer that password to their preferred password manager.

The exact same story applies to passkeys, except, because passkeys can't be copied and pasted, you'd have to figure out how to use the finicky app-to-app transfer system ("Credential Exchange Protocol"). That's probably too complicated for most seniors, so falling back to a password is almost certainly their best bet.

Apple, Google, Microsoft, Mozilla, and 1Password don’t let you export passkeys to a file that you can read and backup, but Bitwarden, Proton Pass, and KeepassXC do.

I think Bitwarden is on HN's current happy list. (I just use Apple iCloud myself.)

Allowing passkeys to be exported to a plaintext file undermines the phishing protections, at least somewhat. It’s possible to trick you into exporting your passkeys from Bitwarden and sending the file to an attacker.

The major password managers say that this is the reason they don’t allow exporting passkeys, and it’s not false, but they’re also making it harder to switch password managers, which may be their ulterior motive. (You can’t even import those exported passkey files into any of the major password managers, which they would be incentivized to do, if those smaller players had significant marketshare.)

It’s up to you to decide whether protecting yourself from being tricked into exporting your passkeys is worth sacrificing your ability to read them.

Then you'll login to your Apple iCloud account using your password.

Passkeys are just passwords that require a password manager; you can't login to a password manager without something outside the password manager, usually a password. (That's why they call it "LassPass" and "1Password"; there's one last password you'll still have to maintain.)

No password manager tries to get you to login with a passkey without setting a password, for precisely that reason. Apple, Google, and Microsoft do invite you to login to their password managers via passkey, because it's convenient and unphishable, but they always also allow you to login via password (or "backup codes", which are just backup passwords).

This is much, much simpler than you think it is. Passkeys are just passwords that require a password manager. If you lose your passkey, you'll reset your passkey the same way you reset your password, probably with a "forgot my password" email.

(But you're not going to lose it, because you use a password manager, and the passkey will be stored there and synchronized to all of your other devices.)

The weird part is that password managers provide no way for you to copy and paste your passkeys. To present a passkey, you have to use a password manager. This makes it impossible to copy and paste your passkey to the wrong person (someone trying to trick you).

Major password managers don’t even allow you to export your passkeys to a file that you can read/backup yourself. Instead, the password managers each have their own finicky app-to-app mechanism for transferring passkeys from one password manager to another. (I think all the password managers kinda like that lock in.)

Finally, note that for logging into your password manager itself, you'll always require something outside your password manager to login, probably a password, but possibly a YubiKey; your choice. (It's your one "last password," as they call it.)

https://danfabulich.medium.com/passkeys-are-just-passwords-t...

P.S. It's past time to move off of LastPass. LastPass lost all of your passwords again last month, just like they did in 2022. The most similar service is 1Password. If you like LastPass, you'll like 1Password about the same, but 1Password hasn't had multiple terrible security breaches.

Wikipedia's traffic (and donations) are collapsing. https://diff.wikimedia.org/2025/10/17/new-user-trends-on-wik...

People don't like to think of it this way, but Wikipedia is funded by ads. Except, the ads only advertise one thing: requests for donations. If people don't visit Wikipedia, because the AI regurgitated Wikipedia's answers, they won't see Wikipedia's donation ads, and they won't donate.

Over time, if current trends continue, more and more people won't even know about Wikipedia. They won't have any "warm feeling" towards the project, because they never go there, they never use it, they never see what good it does them.

The graph proves the cause of their decline was AI, and not aggressive question moderation.

Ask yourself: in what year did it become difficult to ask questions on Stack Overflow? 2014? 2016? 2018? 2020? Aggressive question-closing was part of their design from the very beginning. Their high barriers to question-asking was the cause of their rise, as their primary user was never question writers: it was Google, and anonymous Google users. The whole thing was an SEO play from start to finish.

It's fun to imagine that their aggressive moderation was the "real" cause of their decline. It feels so gratifying, doesn't it? Finally those assholes got their comeuppance, because of their bad behavior!

But that's not why they failed. They failed because SEO businesses can't survive when AI answers the question directly, without referring you any traffic.

(The same thing is happening to Wikipedia, BTW, which is also aggressively moderated.)

https://sqlite.org/flextypegood.html explains why this isn't the default (and probably will never be the default).

rigid type enforcement can successfully prevent the customer name (text) from being inserted into the integer Customer.creditScore column. On the other hand, if that mistake occurs, it is very easy to spot the problem and find all affected rows.

That doesn't line up with my experience. (In particular, it may not be easy to fix those corrupted rows; the data may be entirely lost.)

By suppressing easy-to-detect errors and passing through only the hard-to-detect errors, rigid type enforcement can actually make it more difficult to find and fix bugs.

This doesn't line up with my experience at all.

This blog post further undermines my trust in Jarred.

He makes it sound like Claude did a fantastic Rust rewrite, and "the work continues."

But when the Rust port merged to main, the state of the code was very, very bad. There were 13,000 instances of `unsafe`, no Miri tests at all, and, sure enough, it exposed UB in safe Rust. https://github.com/oven-sh/bun/issues/30719

Observers could see this coming from a mile away, objected strongly to using AI to RIIR before the code merged. Rather than incorporate feedback and get the code ready for production, Jarred gaslit us all, right here on HN. https://news.ycombinator.com/item?id=48019226

Just 9 days before he merged the Rust rewrite to the main branch, Jarred wrote:

This whole thread is an overreaction. 302 comments about code that does not work. We haven’t committed to rewriting. There’s a very high chance all this code gets thrown out completely.

It's plausible that Bun's Rust rewrite is now in much better shape than it was in May. But a blog post like this would have been a place to apologize, to accept that it was a very bumpy rollout, to acknowledge that public messaging was extremely poor, and to earn back our trust.

As it stands, I guess I'll have to run my own tests to try to evaluate whether Bun 1.4 is ready for prime time, because I just can't trust Jarred to give us a straight answer.

98% isn't much 15 days ago

The inherent property of software is that the only way to be sure your software works on a particular platform is to test on that platform.

There is not a baseline target subset of HTML/CSS that reaches 100% coverage that can be statically verified. HTML tables usually work in old browsers, but there were subtle bugs in old versions of Internet Explorer, bugs that you're especially likely to hit if you're using tables for layout (because you can't use modern CSS layout features). The only way to be sure that you didn't trigger one of those subtle bugs is to test your web app on ancient browsers.

The cost of reaching the last 0.N% of users rises with each platform you add to your test matrix. It costs money to test your web app on Internet Explorer. It costs even more money to fix bugs that only affect Internet Explorer.

I think you can't deny that doing that work is expensive. The question then has to be whether that work will repay itself somehow. But the last 0.N% of users will only provide ~0.N% increases to your revenue. Unless your revenue is astronomical, you can't afford even one full-time engineer to test and fix bugs on 0.N% of browsers.

Read carefully. There's a big difference between developing a database and developing an app that uses a database.

If you're developing a database, you should use property-based tests to ensure that your database behaves as expected (ACID reliability, etc.). If you can formally verify parts of your database, you won't have to fuzz it, because it will have been proven correct. But if you're developing a CRUD app that uses a database, there may be no properties of your app at all that are worth fuzzing.

Similarly, if you write a library that parses Markdown, you should write property-based tests of it, and fuzz it. If you use a library that parses Markdown, you should pass it your Markdown, and let the library handle it.

E-commerce apps typically don't need to do any non-trivial parsing. Effect-free logic is likely to be ~1% of your code base, or less.

This is why we keep talking past each other: the techniques that make sense for real-time operating systems don't make sense for an e-commerce app, a line-of-business admin dashboard, or a single-player game.

Don't forget RFC 5321! But the RFCs are ignored in practice by all popular mail servers. There are email addresses that work in practice that don't comply with the RFCs, and there are email addresses that the RFCs permit that don't work in practice.

(This happens with a lot of standards; sometimes people just ignore them and do their own thing. Something similar has happened with SVGs.)

If you write a formal verification of a syntactical email validator that ensures that all/only RFC-compliant email addresses are valid, you'll have completely wasted your time. Don't do it. Just check for at least one @ sign, and email the address to test it.

(This is a perfect example of the trap of formal verification.)

"No crashes/panics/uncaught exceptions" should be worth it.

Surprisingly, no. Property-based testing and formal validation make it easy to spend tons of time and money "preventing" bugs that would never have occurred in production, especially uncaught exceptions.

There is code where strong guarantees can be worth it, (databases, platforms/operating systems, parsers accepting hostile input) but it's not most application-level code, and certainly not most e-commerce CRUD apps.

Remember, we're here to make users' lives better, not to write correct code for its own sake.

The rules of email validation are not remotely well defined! Syntactic email validation is an impossibly hard problem. https://www.netmeister.org/blog/email.html

IMO the industry consensus is never to "validate" email addresses syntactically, but simply to ensure that the email address contains at least one @ and to verify the email address by emailing it an activation code.

Proofs would not have uncovered these failures. The proofs would have proved that they rejected your email address as invalid, and the developers would have patted themselves on the back for a job well done.

Formal verification is a siren song. The siren sings, "bug-free code is possible in principle!" But it's a trap. Even with LLMs, bug-free code is impractical.

I argued that property-based testing is mostly unhelpful for e-commerce/CRUD apps, and that formal verification is a performance improvement on property-based tests.

In a property-based test, you identify some rule (an invariant) that you want to apply to your code. Then, you fuzz your app, testing it with autogenerated inputs, failing the test if the rule is broken at any point. In formal verification, you prove that the code always satisfies the rule, so you don't have to try millions of inputs.

Whether you're doing property-based testing or formal verification, it's extremely difficult to think of any non-trivial business logic properties that should apply to CRUD apps, even if they could be written in English, translated perfectly into code, and verified formally, instantly.

An actual rule that should always be followed, inflexibly, such that a mathematical proof would be useful (and that actually matters to your business) is so rare in CRUD apps that I'm not sure I've ever seen one.

Even with general-purpose rules (the app should never crash, the app should not leak memory), the property-based fuzzers tend to find bugs that have never happened in production, and probably never will. It's rarely economical for an e-commerce app developer to spend time fixing those bugs, even if finding them cost nothing at all (which is not remotely true, even with LLMs).

And what about UI? Maybe you'd want a rule like: "The title of the product for sale should never overflow its container rectangle in the UI."

OK, well, what if the title is one very long word? But… none of the products you sell happen to contain any words that are 500 characters with no spaces. I guess you could add code to prevent that product from ever being created? (And ensure that data in the database will never allow product titles that violate your business rules… how, exactly?)

Formal verification shines where property-based testing is already useful. It's already useful for many software platforms. It's useful for databases, where reliability is essential. It's useful for parsers, particularly when you expect the end user to be attempting to send you hostile code.

But e-commerce apps? CRUD apps? Not so much.

Formal verification is still too limited to be useful for most app developers. The article gives an example of an e-commerce platform using it to prove the correctness of managing refunds, but then acknowledges:

As of today, the formally verified core can handle most effect-free logic—invariants, transitions, conflict resolution. But the UI, network calls, and database interactions typically sit outside the verification boundary. Verification makes the core airtight but doesn’t guarantee end-to-end correctness.

So you can formally prove that your e-commerce refund management logic is correct, except for proving that you processed the refund. You can't even prove anything about recording the refund in your database, say nothing of proving anything about your interactions with your payment processor.

If your app is mostly tricky logic with just a bit of I/O, your app is very unusual, and it's almost certainly not an e-commerce app. E-commerce apps are mostly CRUD apps; I/O with the database, the UI, and third-party APIs (e.g. payment processors) is 99% of the code.

Even property-based testing is mostly unhelpful for e-commerce apps like these.

Instead, think of formal verification as a runtime performance improvement of property-based testing. If property-based testing is useful for your app (it probably isn't), then you may be able to convert some of your property-based tests into formal verifications.

But, honestly, you probably can't do it, not even with a high budget of tokens.

I'd love to be proven wrong, but the way to do it would be to formally prove the correctness of non-trivial open-source code with property tests. Perhaps you could formally verify significant chunks of Postgres! (But I doubt it.)

Deno Desktop 1 month ago

The platform webviews are significantly older/worse than typical web browser versions, especially on macOS and Linux.

On macOS, the only way to upgrade your WebView is to upgrade your OS, which requires rebooting. Lots of people just don't bother. You can upgrade to the latest Chrome or Firefox just by downloading it (assuming they support your macOS version), and they auto-upgrade themselves pretty aggressively.

On the web, very old versions of Safari (6+ years old) are a tiny fraction of a percent of your traffic; many web developers just ignore them. In a desktop app based on a WebView, ancient WebViews can be as high as 10-15% of your macOS user base. Ignoring them is not an option.

On Linux, it's common for the major version of WebKitGTK to not upgrade at all except during major OS upgrades. Anyone on Ubuntu LTS 20 is going to have a 2020-vintage WebKitGTK with security patches. (And Ubuntu LTS 20's WebKitGTK was buggier than macOS WebKit, even in 2020, because Apple has more dedicated full-time developers and testers making sure that macOS WebViews work end-to-end.) If you're shipping an app based on WebKitGTK, you can expect to see double-digit percentages of your Linux users running really old WebKitGTK.

Maybe you're such a great developer that your web app works great on ancient browsers, but, if so, it's probably because you didn't need/use much JS in the first place. (Maybe you used HTMX or something.) In that case, is there even any benefit in shipping a "desktop app"? What's your desktop app even for? Offline support? (But your app is all server side…?)

If you have a JS-intensive app that works great on ancient, buggy browsers, then platform WebView might work for you. It's not nobody, but it's hardly anybody.

One couldn't, because you'd need to standardize a JS-less DOM, which requires one to persuade Apple, Google, Microsoft, and Mozilla to agree on a new standard for a JS-less DOM API.

The DOM API is currently defined as a JS API, including JS strings, JS objects + properties, JS Exceptions, JS Promises, JS garbage collection, and on and on and on.

The effort to get all the browsers to agree to standardize a new JS-less DOM API would take years; none of the browser vendors even want to begin that conversation today.

It's the last line of the abstract.

As a consequence of this succinctness, we show that basic verification problems for transformers, such as emptiness and equivalence, are provably intractable: specifically, EXPSPACE-complete.

The last line of the abstract has the most important takeaway.

As a consequence of this succinctness, we show that basic verification problems for transformers, such as emptiness and equivalence, are provably intractable: specifically, EXPSPACE-complete.

If you were hoping to formally prove the correctness of a large transformer, it turns out that you're going to need an exponentially larger amount of space to do your verification, more than you could possibly afford.

Declarative partial updating "sets the stage for client-side includes." https://github.com/WICG/declarative-partial-updates

The linked article suggests a potential syntax:

  <template for="footer" patchsrc="/partials/footer.html">
That would transclude the content of /partials/footer.html in your HTML.

But the road ahead for this is still quite bumpy. Here's a good video from a year ago, talking through the obstacles. https://www.youtube.com/watch?v=t0NBcve0enY