Hacker Newsnew | past | comments | ask | show | jobs | submit | braden-lk's commentslogin

Nice! How did you go about finding a growth marketer that was a good fit with your business?


I found him and he originally told me to get lost ;)


The first sign of a good marketer :)


What attracted you so much to the project at that time?


I was a customer first. It was the product I had been searching for in my own financial planning, so I immediately saw the potential. When Kyle and I finally met, we hit it off right away. We aligned on the important things and shared a clear vision for where it could go. I’d always had the itch to bootstrap and help build something meaningful and sustainable, so I knew pretty quickly it was the right next move for me.


There's been this vein of advice from the past decade that's in the realm of "just work at FAANG". Always rubbed me the wrong way; they make it sound so easy, lol. The couple of interviews I managed to get after hundreds of ghostings, I was absolutely demolished in the interviews. It seems like if you get nervous doing math problems in front of people who really don't want to be there (and tell you to your face), you don't get to work at FAANG.

Just started my own business instead.


Theres a difference between something being easy, and something being achievable given a large investment of time and effort. FAANG is the second. Not for everyone but if you have anxiety then practice, therapy and possibly prescribed medications for anxiety. I’m sure there whole groups of people who mutually pair mock interview to get over anxiety like this. Or that you can pay to interview you.


Totally; and big respect to the people who put in hundreds of hours of prep. I did leetcode, practice interviews, 4.0 gpa, all that. I think the big hang up for me was, no matter how many practice interviews I did, there were only 4 real ones, with long waiting periods between attempts. And honestly... 3/4 my FAANG interviewers were really rude/late/apathetic. I actually did make it to second round at Google on the third try, but at that point I was so exhausted with the process, I took an offer from a company that at least pretended to give a shit whether I joined them or not. Had a wonderful 3 years there building green-field B2C products.

Getting some work experience and then starting my own thing was a better fit for me.


Clearly the advice can’t be for the literal 50th percentile HN reader in 2025… because nowadays there are hundreds of thousands of readers.

And all the FAANG combined probably don’t even have half that many positions, with negotiable salaries, in total worldwide.


Yes. If advice can't be followed, it's probably just bragging.


i mean, even if we only include Apple Microsoft and Google you're already up to more than half a million employees


Are you confused about the comment?

The majority of positions at any of these (except maybe Netflix) are not hired through negotiable salary packages of the types relevant to the post. I never said anything about overall employee count.


What do you mean? All standard engineering offers (and probably most non-engineering) roles at FAANG are negotiable; in fact, Netflix might be the least flexible - or at least used to be, because they tried to hit what they thought would be "top of market" for you, and would be much harder to budge unless you had an actual competing offer for more than they thought your market value was. (Might be less true today, since they've moved to having actual internal "levels", but idk.)


Because the total employee count as disclosed in annual reports are not limited to solely the typical engineering positions…?

Have you never read a report from any of the FAANGs?

e.g. Out of Google’s 183,000+ total headcount… maybe a quarter are engineering positions with negotiable salaries of any kind.


Big obsidian fan, but I will say: notes being “just markdown” is not entirely true depending on how you use obsidian. If you are a plug-in heavy user, and those plugins introduce new syntax and lots of JavaScript functionality, you are accumulating a bespoke custom syntax that only works on your copy of obsidian with your set of plugins. Obsidian and those plugins are still free and are a huge benefit, but just something to keep in mind regarding data hygiene and longevity.


True, but the format is still text. In a "catastrophe", you can always just a) ignore these, or b) write custom code to process them (e.g. port the plugin to VSCode or whatever).

Still far better than a proprietary format.


A proprietary format with an export function allows you the same inconvenience of having to write code for processing.


Not true for a variety of reasons:

1. You're relying on the external service to continue providing the export functionality, or else doing regular backups.

2. The format of the exports might be proprietary, so it might be orders of magnitude more difficult to parse.

3. The export might not contain all the data.

4. Even if the export isn't to a proprietary format, it might be to a format that's much harder to parse than Markdown. Markdown is not only a standard, it's fairly readable even without any parsing, as opposed to, say, exporting in HTML. Losing some functionality (often minor, depending on what you use Obsidian for) is better than losing more or all functionality.


1. No, the data is already local, the app is already local, you're not relying on anything.

2. Or it might be orders of magnitude easier to parse vs replicating all the plugins functionality. You're just arbitrarily making the alternative worse

3. That's again something you've made up that's not a generic feature of alternative proprietary format

4. It might also be export to markdown. Again, unless you make up artificial barriers

But you can also do it the other way, for example, anything non-trivial like some large table with in-cell formatting won't be readable in your primitive plain text-based proprietary format, so it will be much worse that the unreadable Excel xml or its binary alternative, but that would still be a much preferable export format since no, you're not going to develop a new spreadsheet parser that some obsidian plugin uses to make sense of it

> it's fairly readable even without any parsing, as opposed to, say, exporting in HTML.

that's true for primitive formatting needs, but in this case there are tools that can convert html to markdown that would easily do that


> 1. No, the data is already local, the app is already local, you're not relying on anything.

That's not necessarily true. Some apps keep only cached copies of the data and the rest on the cloud. Sometimes the local files are in a binary format that is unreadable without the export functionality, and newer releases of certain apps remove the export functionality.

> 2. Or it might be orders of magnitude easier to parse vs replicating all the plugins functionality. You're just arbitrarily making the alternative worse

Obviously this depends on the exact app.

But I don't think you can credibly claim that a textual format like markdown isn't easier to parse than... well, almost any other format.

> 3. That's again something you've made up that's not a generic feature of alternative proprietary format

I didn't make it up. It depends on the alternative app you're talking about. Some export full data including all metadata, some don't include all metadata, etc.

My point is that if all the data is actually just markdown files on your computer, there is no question of whether you have all the data.

> 4. It might also be export to markdown. Again, unless you make up artificial barriers

Once again, depends on the specific app. I was a long-term user of Evernote, and still have a subscription. I just checked, and it looks like you can export to a format called "enex", or to a single html page, or to pdf. That's awesome! And the chance that you won't be able to use this in another app is next to nothing, since everyone works to be able to import Evernote.

It's still a tradeoff between the extra functionality you get from Evernote, vs. the simplicity of the "export" files you have. In Obsidian, there's no separate export, the files are stored in simple-to-read Markdown. But you get less functionality.

It's a tradeoff. I'm not saying one is better than the other. But pretending there isn't a tradeoff is quite simply wrong.

> But you can also do it the other way, for example, anything non-trivial like some large table with in-cell formatting won't be readable in your primitive plain text-based proprietary format, so it will be much worse that the unreadable Excel xml or its binary alternative, but that would still be a much preferable export format since no, you're not going to develop a new spreadsheet parser that some obsidian plugin uses to make sense of it

Yes. I wouldn't use Obsidian to do anything that would require a spreadsheet. I'd simply use Excel, since it's a billion times better at it.

I'm certainly not against using the right tool for the job, nor am I against proprietary formats in general.


1. It true since the argument about formats. You can limit storage of open format to the cloud as well.

> and newer releases of certain apps remove the export functionality.

Then you'd just use the old release with the export functionality intact. You can also make up stuff like "Obsidian can release an app that deletes/encrypts all local files, retaining only the cloud copy, and start charging for it without having any export functionality"

> But I don't think you can credibly claim that a textual format like markdown isn't easier to parse than... well, almost any other format.

This isn't markdown, but markdown + dozens of extensions, so it's very easy to claim that it's much harder to write custom parsers for dozens of formats rather than use an existing parser for some more elaborate format that doesn't need those extensions.

> the files are stored in simple-to-read Markdown

they aren't, they're stored in an undefined format depending on which extensions you use. Part of it is markdown (which is not simple to read in the non-primitive case of richly formatted docs)

> there's no separate export

That's not a benefit! It means that you can't move outside of the Obsidian ecosystem because there is no well-defined format that you could use another app with! So it's (practically) even worse than Evernote since that one is already widely supported, though theoretically it's the same.

> But pretending there isn't a tradeoff is quite simply wrong.

Yet you've failed to identify it, turns out it all "depends on the specific app"! Fine, compare apps, but the general argument was about text-based proprietary format with a chance of data loss if the ecosystem dies (or a chance of requiring a lot of effort to convert), and a generic proprietary format that can be exported into a text-based format... with the same risks!


I don't really know what we're disagreeing on.

> This isn't markdown, but markdown + dozens of extensions,

Yes, if the way you use Obsidian includes dozens of extensions that each use a proprietary format, then it's similar to just using Evernote in many ways.

If you're mostly using plain markdown with only a few custom formats, then it's still easier.

If today, right now, Obsidian stopped working, I could literally open my Obsidian folder in VSCode and still be able to do 90% of the things that I do in Obsidian.

If today, right now, Evernote stopped working, it would take some effort to find a working version, export the files, convert them to markdown or whatever, etc.

I just don't know how you can claim that Obsidian is more effort to use outside of Obsidian than something proprietary.


> If today, right now, Evernote stopped working, it would take some effort to find a working version, export the files, convert them to markdown or whatever, etc.

No, at your accepted level of the loss of functionality that would be trivial.

  - Launch the app you already have, export
  - Launch another app, import. Could be Obsidian. Here is their guide. https://help.obsidian.md/import/evernote
  - Open results in VSCode and ignore the 10% lost in conversion
> I just don't know how you can claim that Obsidian is more effort to use outside of Obsidian than something proprietary.

Because at every step you trivialize one option and complicate the other. While they're generically equivalent. All the same things apply...

> If you're mostly using plain

If you're mostly using plain notes in Evernote, then your conversion to the same plain markdown will be trivial, so using another plain markdown isn't easier


No. You might not be able to load the program to get to the export button. They might paywall it away. Etc.


No, there is no paywall or etc. This is not an imaginary anything goes area, but simple note taking where you have local client with locally synced data which can always export, so this risk doesn't exist


Very much this. I cannot even fully agree with "plug-in heavy" remark: I mean, how heavy must it be, to be considered "plug-in heavy"? I consciously tried to limit plugin usage. But it really gets pretty wild soon. I was relatively lean for maybe the first 6 months, but when some patterns of how I use it become clear enough, it becomes pretty evident how inefficient many super-common situations are and how I can fix them just by installing a plugin.

Fast-forward a year, and all your vault structure implicitly relies on the quirks of Obsidian search behavior, the markdown you write is extremely obsidian-flavored markdown, and you don't even remember how to write LaTeX without LaTeX-Suite shortcuts.


I've been using Obsidian for years now and besides some experiments use zero plugins. What inefficient patterns are you running into?


If you're willing to reimplement them in your own obsidian-like editor anyway, I don't quite see the difference

I wouldn't so I keep to markdown and minimize plugins where aplicable, if I need to run for the hills, I don't expect to lose much


I've thought about this and I think Templater and Dataview are the two plugins I'd miss if Obsidian was sold to a VC tomorrow and enshittified.

And I'm pretty sure both will be forked and modified to run independently of Obsidian within a week of the theoretical enshittification.


Very cool overview and a great article—it’s fascinating to see how far web components have come. Data passing, interactivity, and state management still seem pretty tedious in vanilla, though!


Data passing seems inherently broken in web components, because all HTML attrs must have string keys and values. Such a model just can't be built on top of.


You can invoke custom methods and pass in any kind of data into them. As in

  class SomeElement extends HTMLElement {
    constructor() {
      super();
    }

    someMethod(x) {
      this.innerHTML = `<h1>${x}</h1>`;
    }
  }

  // ignore registry stuff

  const customElement = document.getElementById('custom-element-id');

  customElement.someMethod(42);

But you won't learn that from most mainstream custom element tutorials though, for whatever reason.


I'm late getting to this but someone emailed us to point out that your attempt at code formatting didn't quite work, so I fixed it, using the formatting markup documented here: https://news.ycombinator.com/formatdoc. Hope that's OK!


> <h1>${x}</h1>

Fine for x:string, but what about w:WebWorker?


Presumably I've defined a .toString() method on w that will behave as I wish when implicitly invoked to perform this coercion.

If I haven't, then presumably I'll be satisfied with the inherited default behavior, which will probably look something like "<h1>[object Worker]</h1>".

If I care about this extremely contrived example case, in other words, I'll do something to handle it. If I don't, I won't. If I do, it's been easy for at least 25 years now; iirc .toString() was specified in ES3, which was published in March 2000.


Yeah sorry I meant how would you pass it to another GUI component like we can in React.


If I want in the general case to append a child node to a parent (as here with the h1 as parent and the stringified interpolated value as child), I will in almost every case call parent.appendChild(child), where parent and child both implement Node, which is the parent class of Element. The result will correspond closely to the element tree which would be constructed by assigning a string like your example to some other element's innerHTML. (You are essentially using the browser DOM implementation as a templating engine. As sugar over a lot of createElement calls and piecewise tree construction, this isn't a terrible strategy! The JSX with which you're familiar is a more elaborate and more typesafe solution for essentially the same problem.)

Similarly, these references would be from the JS perspective a POJO with lots of seriously heavy implicit "render magic," so you can use them, as with any first-class Javascript value, as function arguments parallel to but a superset of what React does with its props. See the MDN documentation on Node.appendChild (and Node, Element, HTMLElement, etc) for more: https://developer.mozilla.org/en-US/docs/Web/API/Node

If I want to represent the state of a worker thread in the UI, a problem I first recall solving over a weekend in 2016, the way I do it will end up closely resembling the "MVC pattern," with the Worker instance as "model," the DOM element structure as "view," and a "controller" that takes a Worker and returns an element tree. Even if I'm using React to build the UI - which I have also been mostly doing for about as long - I am still going to handle this translation with a library function, even if my component actually does accept a Worker as a prop, which it actually very likely will since that will enable me to easily dispatch effects and update the UI on changes of worker state. I might define that "business logic" function alongside the component which uses it, in the same module. But React or vanilla, I won't put that logic in the UI rendering code, unless it is trivial property mapping and no more (unlikely in this case, since any interesting worker thread state updates will arrive via message events requiring the parent to keep track in some way.)

Does that help clear up what I'm getting at?


What would you expect that to do, in any framework?


In React, say, I might write

    <MyComponent worker={worker} />
and expect the worker instance to be passed as an object to `MyComponent` as a prop. But with webcomponents, I can't do something like that.

    this.innerHTML = `<my-component worker="${worker}">`
will just stringify the worker and pass that string to the `my-component`. To get the worker instance to be passed correctly, I'd need to do something like

    this.innerHTML = `<my-component>`
    this.firstChild.worker = worker;


With any web component you could assign the worker to a property, either imperatively:

    el.worker = worker
Or declaratively:

   html`<my-component .worker=${worker}></my-component>`
That's using lit-html syntax, but there are a lot of other rendering libraries that work similarly.


Every time I go back to give Web Components another 5 minutes, I hit this point where using lit or a lit-like would take a lot of the pain of the problems Web Components don't solve and have no planned solution for away.

But once I decide to cross the "no dependencies" line, using something like Preact + htm as a no-build solution would also take the most of the rest of the pain away, and solve many, many other problems Web Components have no solution and no planned solution for.


So this isn't even a question about web workers, it's a question about how to prop-drill non-string/number data through multiple layers of web-components.

Tbh, I'm not sure there's a way for that. But why not just define a method in your target child component and pass the worker in there?


Yeah, I think the original question was a bit weirdly worded which made people focus on web workers rather than complex data in general.

You can use properties (as opposed to attributes) as I demonstrated, and you can use methods like you suggest, but these are both verbose and limited, and add an extra "the component has been created but the props haven't been fully passed" state to the component you're writing. Imagine a component with maybe five different props, all of which are complex objects that need to be passed by property. That's a lot of boilerplate to work with.


In what way are properties verbose and limited in your view?

You can set them declaratively with a template binding in most template systems.


I showed earlier how it takes multiple lines and some fiddling with DOM to set a simple property with vanilla web components. Sure, if you're using a framework like lit, you have access to template binding, but at that point you might as well use an equivalent framework like SolidJS or Svelte which just skips the web component layer.


Bringing it back to the site, the author does describe implementations of context providers and signals:

https://plainvanillaweb.com/blog/articles/2024-10-07-needs-m... https://plainvanillaweb.com/blog/articles/2024-08-30-poor-ma...

I haven't tried signals yet, but I couldn't see why you could pass in an object with multiple values.


Skipping the web component later would skip then interoperable component part.


That doesn't look like it even has anything to do with custom components, that's just adding a method to a class. OOP 101.


>just adding a method to a class. OOP 101.

You're right, it is just a method call from a class. Nothing interesting or new. And that's exactly why I like it! I like me FE code as boring, unimpressive and as simple as possible.


And custom elements are just classes, so you can do that.


The "old ways" are relevant again here. Just like in the old Progressive Enhancement era (the jQuery/Knockout era) to pass objects/arrays as attributes you use the special data- attributes and the `dataset` property. As the old ways suggest you probably still want to account for strings and serialize/deserialize via JSON for the most compatibility with things like static rendering, but many a jQuery script "upgraded" such things in-place.


Imagine 50 years ago: “Data passing seems inherently broken in Unix, because all processes must use strings for input and output. Such a model just can't be built on top of.”


Show me a successful GUI made with bash.


Why is a GUI unsuited to stringly-typed data in a way that a CLI is not?


As a matter of fact, Tcl/Tk has been doing exactly that since the 1990s. Of course, Tk has been "borrowed" by other languages, Python's tkinter is well-known. Any language using Tk widgets still has to input options in text form. Obviously that's not particularly difficult to accomplish.


Just an intuition.


This is just a lie perpetuated by the React team 10 years ago

All HTML elements are JavaScript objects that have properties. You can pass arbitrary data to custom elements via those properties.

Look at any modern HTML template system and you'll see the ability to pass data to properties declaratively.


Well it's not a lie, it's how HTML and the DOM work. Attributes are strings, and what you write in HTML will be passed as attributes.

You do also have access to properties, but only in Javascript — you can't for example write something like `<my-custom-component date="new Date(2024, 02, 04)">`. That means that if you need to pass around complex data types, you need to either manipulate the DOM objects directly, or you need to include some sort of templating abstraction that will handle the property/attribute problem for you.

This is my main criticism of web components. At the simplest levels, they're not useful — you could build this website very easily without them, they aren't providing a particularly meaningful abstraction at this level of complexity. But at the more complex levels, they're not sufficient by themselves — there's no state management concept, there's no templating, there's not even much reactivity, other than the stuff you could do with native JS event emitters.

As far as I can tell, the best use-case for web components is microfrontends, which is a pretty useful use-case (much better than iframes), but it's very niche. Apart from that, I really don't see why you wouldn't just write normal Javascript without worrying about web components at all.


It is absolutely a lie, because web components can handle arbitrary data just at much as any framework.

You're holding web components to a higher standard here in expecting them to take arbitrary data in HTML when HTML itself doesn't support arbitrary data. Notably you can't assign arbitrary data to framework components from within HTML either, so how are web components any more limited?


The original comment was that "all HTML attrs must have string keys and values", which is completely true.

The point of web components is that they create normal HTML elements. So it makes sense to consider what the value of them being normal HTML elements is. You can write them directly in your HTML source code, for example. But if you do that, you only get access to attributes and not to properties, and therefore everything needs to be strings. Alternatively, you can treat them as DOM nodes in Javascript, at which point you get access to properties and can use non-string values, but now you've got to deal with the DOM API, which is verbose and imperative, and makes declarative templating difficult.

Yes, we could compare them to components from other frameworks, but that's honestly an absurd comparison. They're simply trying to do different things. Frameworks aren't trying to create HTML elements. They're trying to reactively template the DOM. It's just a completely different goal altogether. The comparison doesn't make sense.


Web Components can have properties too, and in fact this is the norm.


Can't put those in templates though. It's a serious pain and completely unnecessary.


You absolutely can put properties in templates. Web component authors do this all the time.

Here's a lit-html template that sets a property:

    html`<my-element .someProp=${x}></my-element>`


At that point you're not using HTML anymore, you're just calling html() in a fancy way, and that's the whole point of the complaint, that custom-elements are not good at being plain HTML even though that's like its whole thing.


Normal HTML elements don't exclusively use HTML attributes either. Surely you've used button.onclick or element.classList or element.innerHTML?


Being plain HTML is important for the user of the element.

That the element may use a library for its implementation is basically irrelevant.


Hi.


That's not web components, though that's lit-html. That's an additional library you need to pull in to manage your web components. Which kind of ruins a lot of the stated benefits of web components. If I need a framework to write my web components, why not just pull in a different framework that skips the web component level completely and just outputs HTML/CSS directly? What is this intermediate step actually bringing me?


How does using a library ruin the goals of the components at all?

The goal of web components is to enable interoperable, encapsulated, reusable components, where how they're built is an implementation detail.

You can use a web component that used lit-html without knowing anything about lit-html, it even that the component uses it.


In theory it is completely an implementation detail, I agree. In practice, it's bloat. If every web component I use in my project might pull in a completely different framework behind the scenes (and worse: if those web components depend transitively on other web components that pull in yet more frameworks), then I now have to deal with all of those different frameworks. Each of them will load more bytes and make my page's startup time slower. Each of them will have their own state management systems. Each of them will have their own approach to templating. Each of them will behave subtly differently in practice.

Why bother when I can just write everything in a single framework?


Not in <template>s, the vanilla HTML alternative to this.


some people cheat by using web components but with Lit Elements. https://lit.dev/ . I use it with raw JS without any bundling.


Same. Recreating a basic lit framework is like 300 lines of code


State management is arguably one of the most important problems to solve. That's why we use React and Vue. You can very easily build complex user interfaces at scale with those frameworks. And you can even take web components along for the ride if you want to. They are partially overlapping solutions for different problems.


Microsoft solved this with VIEWSTATE in ASP.NET it's perfect, then industry went with everything Ajax and other over engineered frameworks.


You don't know how much easier it was at that time (at least for web developers with little prior ASP experience) to:

- write a simple web service in C# on top of ASP.NET MVC v1

- build a web frontend on top of it using Prototype.js (or jQuery) and a library of components like ExtJS


Alternatively, you can keep using React and have access to a huge pool of experienced react developers and libraries.

React DevTools have gotten quite good; it’s not hard to catch 99% of perf issues anymore. Inexperienced devs will write bad code in any language; have your experienced devs teach them, or just don’t hire juniors.

I agree that closures in React are annoying though.


Yeah, how can you honestly review something associated with the world’s most powerful person? Who’s also shown they’re willing to swing their weight against any normies that annoy them?


Would love to see profiling to show where the React approach was falling short.


I run all of LegendKeeper's infrastructure on Render, save for a few serverless functions. It's been convenient; I rarely think about infra at all anymore.


This game is right up my alley but it’s so engrossing I always forget to save and lose hours of my progress.


it has auto-save?!


Though there are dead ends, thus needing to save earlier to undo decisions.


There are no dead ends, but it is possible to play yourself into a state that looks like one. Without spoiling anything I would wager you haven't discovered a mechanic that's in the game yet. Figuring out how to play the game is a part of the game. Source: I thought I hit a dead end, but found a different way to approach the problem after a few days of being stuck.


There is, as far as I can tell, one dead end: if you run out of money near the start of the game and have exhausted your options for getting more, then you'll have to revert to an earlier save. It's not particularly easy to do though, in my opinion.


Unless they've changed it recently, the auto-save seems to only bother firing off every few hours. All three attempts I've made at the game have ended with losing progress to the save system.


yes


Similar experience. I’ve never received much good advice, or found anything that feels like it “works”, just small, accumulating long-game actions that drive up traffic/conversions a hundredth of a percent at a time. Blog posts, paid ads, sponsorships, emails, affiliates, product improvements, etc. I’m B2C so most advice given to me by “thought leaders” is “stop doing B2c” which isn’t super helpful when I have a functioning, profitable B2C business.


Same.

I think much of the stuff that you need to do is common sense (put word out, write about it, encourage word of mouth). And it's usually obvious what will definitely kill your project (don't talk about it to anyone, don't listen to customer feedback etc.) so do the opposite of those.

My general experience has been that word of mouth is slow but very reliable and the customers you get from there are usually high value.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: