[HN Gopher] How I Build Web Apps As A Freelancer
       ___________________________________________________________________
        
       How I Build Web Apps As A Freelancer
        
       Author : timdaub
       Score  : 105 points
       Date   : 2021-01-18 19:22 UTC (3 hours ago)
        
 (HTM) web link (timdaub.github.io)
 (TXT) w3m dump (timdaub.github.io)
        
       | wildpeaks wrote:
       | Even if you don't want to write Typescript, not even using TS as
       | JS Intellisense is an odd choice, it already catches so much
       | without requiring any build step.
        
       | franklyt wrote:
       | JSDoc doesn't require any transpilation. It runs as native
       | JavaScript code by using comments as type-hints. I can understand
       | not wanting to use TypeScript, kind of, but not using JSDoc as
       | well is honestly mildly negligent, especially when simply
       | inferring types, i.e. being more strict about type coercion, is a
       | massive boon to productivity.
        
       | pupppet wrote:
       | I'm grateful tools like webpack/babel exist but I find it a bit
       | depressing we still need them, their use-case are for problems
       | that should have been long-solved.
        
       | dewey wrote:
       | Might want to edit the title, this is not a Show
       | HN.(https://news.ycombinator.com/showhn.html)
        
         | timdaub wrote:
         | Done. Thanks for letting me know.
        
       | [deleted]
        
       | gm wrote:
       | Something was bothering me about this whole thing. I think I
       | found what it is:
       | 
       | 1) This is an entirely self-centered approach. "These are the
       | tools that I like, and I code the way I'm productive, with the
       | specific knowledge I've acquired, tailored to how I best work."
       | That's a lot of "I" in there.
       | 
       | The idea of programming this way really bothers me because as
       | someone who's hired freelancers, the best interests of your
       | clients are nowhere in your calculus. Now, if you gave them the
       | choice between lower cost code and code that anyone else can work
       | on, it's your client's decision. But you are making that decision
       | for them. If your clients are non-tech people who don't
       | understand the ramifications of each choice, then you are doing
       | them a disservice.
       | 
       | Nowhere in your article do you mention documentation or making
       | your source easily understood by anyone else, so I rest my case.
       | 
       | It looks like if you are ever hit by a train, your client is
       | screwed, and you've not thought about that.
       | 
       | 2) I know that we, as engineers, love to reinvent the wheel, but
       | when you start implementing stuff readily available you introduce
       | bugs and security weaknesses. Maybe you trust yourself not to do
       | that, but do your clients know you're not using industry standard
       | code?
       | 
       | Anyway, your life, your choices. I'm not sure you've been on the
       | client side inheriting code written like this that no new
       | programmer can understand right away. Whoever inherits your code
       | is going to have a lot of head scratching to do, and the only
       | saving grace is that they will have your tests to validate any
       | changes, and they will hope that your test coverage is
       | appropriate.
       | 
       | But from the point of view of your own interests, everything you
       | wrote is very beneficial.
        
       | e12e wrote:
       | > I avoid the new and the shiny
       | 
       | > (...)
       | 
       | > import { h, Component, render } from
       | 'https://unpkg.com/preact?module'
       | 
       | Will break on breaking changes in upstream, as no version is
       | specified? Or am I missing something?
       | 
       | Ed: not to mention when unpkg goes away...
        
         | timdaub wrote:
         | Good point, I think pinning a version would make sense here.
         | 
         | import { h, Component, render } from
         | 'https://unpkg.com/preact@10.5.10?module'
        
       | mikeryan wrote:
       | So I'm not against these rules, but I do run an agency that
       | builds bespoke JS Apps for folks and a few notes. My biggest
       | feedback was to ensure you're communicating with your client and
       | telling them _why_ you make these types of decisions and point
       | out some of the tradeoffs and later costs they might accrue.
       | 
       | 1. Using some sort of typed JavaScript via Typescript or Flow
       | makes for much more resilient and stable code. Particularly if
       | you're developing re-usable APIs. You're doing the right thing
       | with automated tests but missing an opportunity by avoiding a
       | type system. We had a much fewer runtime issues once switching to
       | a type system.
       | 
       | 2. The above sort of necessitates a transpiler.
       | 
       | 3. With respect to using your own code, most freelancers (I
       | assume) are delivering code to third party teams to later
       | maintain. Using common, shared libraries is a benefit for later
       | developers, so this rule should be tempered with later benefits.
        
         | timdaub wrote:
         | 1. and 2. nice reasoning. I have been considering adding
         | Typescript recently. Mainly as I sometimes encounter bugs on
         | e.g. an options object where a property is named incorrectly.
         | That tends to lead to hours of debugging, so it'd be reasonable
         | to start using it.
         | 
         | Re: third party code: I'm not against third-party libs. But
         | what I tend to prefer is having control over my code. This
         | makes me faster in building and maintaining. I'm a solo
         | freelancer. I can't afford to wait three days for a PR upstream
         | to be merged.
         | 
         | Also, I like to create my own little dependency. That way I
         | have a way to create separate and loosely coupled APIs
         | (shareable) and control.
        
           | mikeryan wrote:
           | Of note, Typescript is a heavy lift to add to, really port,
           | an existing codebase. Flow can be sprinkled into an existing
           | codebase easier if that's your goal. Once you understand the
           | way the types work (in particular Generics) they're somewhat
           | interchangeable.
           | 
           | New codebases for us use Typescript, extending existing work
           | we use Flow that can be backported in easier.
        
             | polishdude20 wrote:
             | On the other side of this point, I've used typescript and
             | converted a major project to use it and it was fairly
             | simple. The main thing you should start with for low
             | hanging fruit is database queries. Make sure your database
             | query functions are typed and it'll make the rest of your
             | code much easier to write even if the rest isn't in
             | typescript. Start getting types into the places where the
             | data is coming from. The source of the data.
        
       | Chris_Newton wrote:
       | I have a _lot_ of sympathy for the arguments made here.
       | 
       | I strongly agree with avoiding overcomplicated processes and
       | tools. When you start spending noticeable amounts of time trying
       | to figure out your build process or how to manage your hosting
       | infrastructure, to pick two repeat offenders, something is wrong.
       | The overwhelming majority of web apps simply aren't that
       | complicated, and building and deploying them shouldn't be
       | complicated either.
       | 
       | Like the author, I am a big fan of tools like Parcel that have
       | one job, do it well, and mostly "just work". Virtual hat tip to
       | Caddy as a web server for similar reasons. I think some of the
       | more recent build tools like Snowpack and esbuild are worth
       | watching too. All of these tools share the common theme that they
       | attempt to make routine jobs simple, automatic and fast, so
       | developers can get on with developing useful software.
       | 
       | In some ways, I take almost the opposite view when it comes to
       | writing code. I tend to start almost everything from a clean
       | slate, and usually I end up using a relatively small set of
       | libraries, carefully chosen for each project, for productivity. I
       | rarely use a heavyweight framework, as I think the benefits they
       | offer are much more limited than their popularity would suggest
       | and the potential long-term costs they come with are often
       | underestimated. I almost never use scaffolding tools, for similar
       | reasons.
       | 
       | I suspect this apparent dichotomy is a bit like what you build
       | and what you outsource in a startup. There is the core idea,
       | which is where you're creating value, and you want to be as
       | flexible and productive as possible in that area. For everything
       | else that is necessary but not the unique part of what you're
       | doing, you want to be involved as little as possible. Outsourcing
       | that stuff is good, but outsourcing 80% of something and still
       | having to do the other 20% but on someone else's terms is often
       | the worst position of all.
        
       | lampe3 wrote:
       | Why not use Vue-cli or react-create-app?
       | 
       | I also don't like to setup webpack but by doing that you learn a
       | lot about how things work.
       | 
       | This is for example why I started to write my own component
       | framework in vue. Just to learn the underling stuff. It is also
       | open sourced ;) https://github.com/lampewebdev/lcs-components-yt
        
       | mtlynch wrote:
       | I agree with the points here.
       | 
       | I came from backend development, writing mostly in C++ and Python
       | for most of my career. I've always found modern JavaScript
       | frameworks so difficult to reason about because it feels like I'm
       | always working through nine layers of abstraction.
       | 
       | Last year, I read Julia Evans's article "A little bit of plain
       | Javascript can do a lot," and it inspired me to try to push
       | regular JS as far as it would go in my next project. It's now 8
       | months later, I have thousands of users, and I'm still using
       | plain JavaScript.[1] No babel/webpack or anything. I do use Flask
       | to aggregate source files together, but I purposely avoid any
       | cleverness there. Overall, I find the code much easier to debug
       | than any of my other web apps.
       | 
       | One nice advantage of using only vanilla JS is that it's easier
       | to find contributors. If you're a React project, then only React
       | developers can contribute. But if you're a vanilla JS project,
       | you're not bound to developers of any particular religion. Vue,
       | React, Angular, Svelte developers can all work in a vanilla JS
       | codebase.
       | 
       | [0] https://jvns.ca/blog/2020/06/19/a-little-bit-of-plain-
       | javasc...
       | 
       | [1] https://github.com/mtlynch/tinypilot
        
         | mrfusion wrote:
         | Don't you lose the value of cross browser compatibility?
        
           | mtlynch wrote:
           | No, I haven't encountered that yet. All of the JavaScript
           | APIs I use seem to work consistently across browsers.
           | 
           | But I should mention that I ignore support for legacy
           | browsers. I assume users have a version of Chrome, Firefox,
           | Edge, or Safari from the last year or two.
        
         | timdaub wrote:
         | Hey mtlynch!
         | 
         | Glad you like the post! Your blog inspired me to get better at
         | writing and to take blogging more seriously. So I guess I want
         | to say thanks! Keep up the amazing work!
        
           | mtlynch wrote:
           | Oh wow, thank you! It's so nice to hear that my blog had that
           | kind of impact.
        
       | mirkodrummer wrote:
       | What about security? I'd like to know author's opinion on that.
       | Very often this job requires you doing tradeoffs between
       | performance and security, productivity and low hanging fruits,
       | manteinability and team or future team composition, or maybe
       | avoid choosing the coolest and performant technology around
       | because there might be a scarsicity of developers knowing that
       | technology etc. etc.
        
       | antihero wrote:
       | Man, I hope I don't have to work on their code ever (edit: to
       | clarify, I am not knocking their actual code!)
       | 
       | Being so against using any sort of transpilation you avoid even
       | TypeScript and JSX? Even though Parcel gives you these things
       | completely for free, out of the box?
       | 
       | I do not think this approach would scale to a team in any good
       | way.
       | 
       | Also with regards to using something like unpkg URLs in built
       | code, whilst I a not completely against using urls for
       | dependencies (ala deno), isn't there the huge risk that without
       | pulling dependencies in at build time, those URLs will break or
       | become overloaded or compromised?
        
         | xupybd wrote:
         | I've worked on a team that was quagmired with tooling. I would
         | love to work with this code base.
        
         | timdaub wrote:
         | As I said, I freelance. So don't worry, because I'm not
         | planning to hire you ( deg [?]? deg)
         | 
         | > Also with regards to using something like unpkg URLs in built
         | code, whilst I a not completely against using urls for
         | dependencies (ala deno), isn't there the huge risk that without
         | pulling dependencies in at build time, those URLs will break or
         | become overloaded or compromised?
         | 
         | In my post, I said I use unpkg for prototypes, so I don't think
         | it's a problem. But in any case, unpkg let's you pin a version:
         | 
         | unpkg.com/:package@:version/:file
        
           | antihero wrote:
           | No worries buddy, and I think that it's important that you
           | enjoy using something that works for you. I just thought it
           | prudent to point out the limited scope of certain approaches
           | as there's a lot of people trying to push this kind of
           | simplicty into situations where it is less appropriate (in my
           | opinion).
        
             | tomaszs wrote:
             | I'd rather see more of a chase for simplicity these days.
             | It is the hallmark of good project. However today the
             | opposite is popular.
        
               | Chris_Newton wrote:
               | Indeed. If 40-something me could go back in time and tell
               | 20-something me what I'd learned in my career so far, one
               | of the first lessons would be that simplicity scales and
               | endures like almost nothing else and is probably the most
               | underrated virtue in software development. (Composability
               | would be #2.)
               | 
               | That is not to say that complexity is never necessary.
               | Sometimes we are trying to solve inherently complex
               | problems. But there is a disturbing amount of
               | _accidental_ complexity in modern web development. To
               | make things worse, because web development is such a huge
               | part of the software industry now and how so many people
               | have come into that industry, a whole generation of
               | developers is growing up believing that the accidental
               | complexity is necessary or even desirable.
        
               | [deleted]
        
         | solumos wrote:
         | > I do not think this approach would scale to a team in any
         | good way.
         | 
         | I mean, he literally says he's a solo/freelancer. Should be
         | pretty clear:
         | 
         | > I'm sure they won't work for everyone as all our contexts
         | differ. But working solo as a freelancer, I've found that these
         | principles contribute to me being content about what I'm doing.
         | Hence, I was eager to share them.
         | 
         | Honestly, if you're doing solo/freelance work, whoever comes
         | along next is likely to toss out whatever you've done anyway,
         | so you may as well optimize for whatever stack works best for
         | you.
        
           | antihero wrote:
           | > Honestly, if you're doing solo/freelance work, whoever
           | comes along next is likely to toss out whatever you've done
           | anyway, so you may as well optimize for whatever stack works
           | best for you.
           | 
           | This is a fair point
        
         | asiando wrote:
         | Parcel doesn't come for free. It does help, but it brings its
         | own problems.
         | 
         | If you stick an await in the code it breaks it because it
         | transpiles it to a missing library. You have to disable Babel
         | or import a regenerator/polyfill or whatever they need
         | nowadays... but first, you have to figure out what's wrong.
        
           | antihero wrote:
           | I didn't say Parcel comes for free - for clarification, the
           | author said they use Parcel, and I am saying that this comes
           | for free with Parcel.
        
       | _0o6v wrote:
       | This is a fair post and fair enough for striving for simplicity.
       | 
       | On the TypeScript thing, if you're already using Parcel it can do
       | all the TypeScript stuff for you with nothing extra required!
        
       | nathias wrote:
       | Imagine inheriting that guy's codebase.
        
         | pavlov wrote:
         | I'd be much happier to inherit this codebase than the more
         | common kind of front-end: "We made a bunch of choices on
         | frameworks and toolchains 7 years ago because they ticked a lot
         | of buzzwords. To understand what's really going on, be prepared
         | to dive into old issue trackers of deprecated versions of
         | unpopular projects to figure out why the code is doing thing X
         | to work around bug Y. But isn't reactive functional
         | metaprogramming in CoffeeScript pretty awesome though?"
        
         | timdaub wrote:
         | Hi,
         | 
         | "that guy" is here and reading your mean comment. Anyways, I
         | don't think my code is that bad.
        
           | aerovistae wrote:
           | It can be very very difficult to find your way around a large
           | JavaScript code base without types. There's a reason everyone
           | complains about a lack of typing in ruby, python, and
           | javascript. I loved it too at first but as I got into larger
           | corporate code bases I found that typing was absolutely
           | crucial for productivity. You're going to get flack for that,
           | may as well accept it.
        
             | bob1029 wrote:
             | This is why we use Blazor now. Our domain model has over 50
             | different types, some with well over 300 unique properties
             | per. In a complex use case for our application, there can
             | be tens of thousands of total business facts to deal with
             | at the same time. If we were still trying to define JSON
             | API contracts and mappers to pass this amount of domain
             | knowledge around, we would have closed up shop a few years
             | ago.
             | 
             | We now have 1 strongly-typed domain model that is used
             | directly throughout the entire application. If you want to
             | talk about productivity, cutting out entire layers of
             | unnecessary mapping is key to getting leverage. Our custom
             | javascript interop amounts to approximately 150 lines of
             | code. Needless to say, we don't worry about javascript too
             | much. Any interaction requiring js is quickly abstracted
             | away under some razor component, never to be worried about
             | again.
        
             | nathias wrote:
             | What would you say the codebase size threshold is for when
             | types become needed? I mostly work on medium projects I
             | think, and never found typescript to be of any use...
        
           | nathias wrote:
           | I mean kudos, you have optimized as you should, for you. As a
           | freelancer you have other concerns, but people that will
           | maintain it will curse you (but that's what they're paid
           | for). You have some very cool projects.
        
       | simonw wrote:
       | Slightly misleading title change here - the article was "How I
       | Build JavaScript Apps In 2021" but here it appears as "How I
       | Build Web Apps As A Freelancer"
       | 
       | Web apps and JavaScript apps are not the same thing.
        
       | c0nfused wrote:
       | Personally, I have arrived at a similar set of ideas in my
       | consulting gigs, though not the same technology stack choices.
       | 
       | I think it is the need to be maximally productive in the shortest
       | amount of time. Basically, any time you spend fixing someone
       | else's problem is time you aren't getting closer to the clients
       | goals. It is not that the time isn't for the greater good, but
       | the hours I have allocated to this problem are fairly tight to
       | start with and I don't enjoy the "We are over budget. Here is
       | why" talks.
       | 
       | I have reached the point where I have started using npm ls as a
       | proxy for how much pain migrating a legacy app will end up being.
        
         | timdaub wrote:
         | > I think it is the need to be maximally productive in the
         | shortest amount of time. Basically, any time you spend fixing
         | someone else's problem is time you aren't getting closer to the
         | clients goals.
         | 
         | Yes, that is an important reason how I arrived at this way of
         | working!
        
         | yawnxyz wrote:
         | as a single dev, I decided to get rid of ORMs and Typescript
         | because... if I can't figure out what I did between my comments
         | and my Notion documents, I'm doing it really wrong...
         | 
         | I've realized the more time not spent on producing output in
         | the shortest amount of time, I'm eating away at my work life
         | balance
        
       | pier25 wrote:
       | I don't use it anymore, but I think being able to use Vue without
       | any build step is one of its greatest assets. You can just start
       | writing components on vanilla .js files just like in the old
       | school days.
       | 
       | I mainly use Svelte now which unfortunately requires a
       | compilation step but the benefits are so great it's worth it.
       | 
       | There's such a great disconnect between what front end devs need
       | and what the W3C/TC39 keep adding.
        
       | zwbetz wrote:
       | I mostly agree with the author on "I avoid the new and shiny."
       | ... The post links to another named "TypeScript is weakening the
       | JavaScript ecosystem". In that post, the author says "My context
       | is that I've not looked into TypeScript yet. That means I have no
       | idea how it works.". I am all for reading a good critique, but
       | how can you adequately critique a technology if you don't know
       | how to use it?
        
         | timdaub wrote:
         | Surprisingly, many get upset about this particular line while
         | the reason I added it was simply to be honest in my argument.
         | 
         | As you can already infer from the headline of that post, I
         | tried writing a statement that is about how Typescript is
         | weakening the JavaScript ecosystem.
        
           | nandi95 wrote:
           | I don't see the argument that it's weakening the JavaScript
           | ecosystem. If anything it enriches it as you have (generally)
           | safer more robust code to work with.
        
         | serial_dev wrote:
         | I think it _could_ be a good critique. It 's a good point in
         | general (just think about Grunt, Gulp, Broccoli, webpack and
         | the like), but I don't see TypeScript as the "new and shiny"
         | anymore.
         | 
         | Although there are alternatives (Flow, for example), to me it
         | seems like the community has picked TS as the way forward, so
         | in my opinion TS is a very low risk technology with real
         | benefits, so I wouldn't hesitate adding it to a project's tech
         | stack.
         | 
         | It's here to stay and a big chunk of JavaScript developers
         | enjoy using TypeScript.
        
       | tomaszs wrote:
       | Interesting set of tools. I'd love to learn how it works and see
       | the code, there has to be some true craftsmanship inside.
       | 
       | Something that is unknown to a wide range of today's programmers.
        
       | tommica wrote:
       | I'm happy that you have fpund a stack you enjoy using!
        
       | simonw wrote:
       | Love the section "I use open source to my advantage":
       | https://timdaub.github.io/2021/01/16/web-principles/#i-use-o....
       | 
       | I started doing this a couple of years ago - defaulting to
       | writing open source code unless I had a really good reason not to
       | - and my productivity has gone through the roof as a direct
       | result.
       | 
       | The way I think about this is that ideally as a software
       | developer I should only ever have to solve any problem once. If I
       | solve it by writing some open source code, and do it well, I'll
       | never have to solve it again in the future.
       | 
       | I compare that to my previous decade+ of engineering where I
       | would frequently find myself solving a problem that I'd already
       | solved a couple of years earlier, but in closed-source code that
       | I couldn't easily reuse.
        
         | timdaub wrote:
         | > The way I think about this is that ideally as a software
         | developer I should only ever have to solve any problem once.
         | 
         | Exactly! Imagine we software developer craftspeople would all
         | come with an "open source utility belt" when someone hired us
         | <3
        
       | tmotwu wrote:
       | Some commenters are missing the point. They are narrowing their
       | mindset by focusing how it would scale in a team environment.
       | However, this post is coming from a freelancer perspective - it's
       | a perfectly good set of principles, even for any side project.
       | 
       | Too many developers start their baby projects thinking they'll be
       | building it alongside hundreds of fellow developers and spend
       | weeks prematurely configuring their build tooling, boilerplate,
       | tech stack. How it'll be supported in twenty platforms, etc.
       | You're only giving yourself more headaches for later on.
       | 
       | I agree with your point on using your own work. People reach for
       | the nicest looking library but there are so many standardized web
       | apis capable of doing what they need, with only very little
       | modification to make it work the way they expect it to.
        
         | timdaub wrote:
         | Thank you. I'm happy that we speak the same language!
         | 
         | Getting out the big guns in solo freelance is like going to the
         | hardware store and buying the most complex and expensive drill
         | possible. Only to arrive home full of sweat to drill a 5mm
         | hole.
         | 
         | (FYI: I love expensive drills, but I don't own one)
        
       ___________________________________________________________________
       (page generated 2021-01-18 23:01 UTC)