Steve (Builder.io) Profile picture
Aug 17, 2024 18 tweets 6 min read Read on X
Don't be that teammate who blindly refactors code and only makes things worse.

Let's look at some good vs bad refactoring patterns with real examples 🧵 Code screenshot with text that says "this refactor caused us downtime"
Let's take this code.

I hired a developer once that saw us calling this `functions.runWith(...)` repeatedly with different options and decided to consolidate it all into one createApi function Code example with some redundant function calls
This new, consolidated code, had a huge issue.

Can you see it?

When we started deploying these APIs, they began breaking left and right. Code that consolidates the function calls into one, also consolidating the options each gave into one set of options used for all
Why?

Because different functions needed different options timeout and memory options.

The inconsistency was not a mistake, it was intentional and ignored by this dev causing us a lot of headaches.

A better approach would've been to pass through the options like so: Revision of the previous code that allows each function to pass its own options in as needed
Now let's take this code.

Tbh its completely fine, but depending on your preferences you may think it would look nicer with a more functional approach. A basic for loop in JS
I hired a dev once that all of the code they touched they refactored to use a very opinionated functional style using Ramda and other libraries A code snippet of opinionated functional code written in ramda.js
Needless to say, most other devs on the team were not familiar with Ramda and didn't love working with it.

A better refactor would've been to simply do this.

This code is cleaner, more functional, doesn't add new libraries, and better matches the other code in the codebase. The for loop code revised to be simpler with .filter().map()
I hired another dev once that loved to over abstract things.

They would've refactored that original for loop to look more like this.

Every time you worked with their code there were just so many more layers than necessary to do simple things. A large JS class with a lot of methods to do the same thing the simple for loop did before
If one feels its so important to create clearly separated and named functions for each step in the flow, this would be a much better solution that is simpler and more conventional within the existing codebase: An alternative refactor of the original for loop breaking each step into its own functions and calling .filter().map() using those
Too many times I've seen devs assume that just because they didn't understand some code, it must be bad code and they should just refactor it before learning it.

Let's take this code: Code that fetches data and caches it in localstorage manually
I've worked with devs before that would just blindly assume this is better code.

It's so simple and beautiful, right?

Well, most code starts out simple.

But we added more layers for a reason, and blindly deleting them is rarely answer. Simpler code that removes the caching
A better approach would be to do this: create a basic cache manager.

This small abstraction allows us to keep caching in our implementation, but clean out the JSON/localStorage logic from the function itself.

No more performance regressions. Cleaned up code that moves the caching logic into its own cacheManager
Don't forget that business context matters too.

I once worked at an ecommerce company that was on an eight year old Java framework that didn't even have online documentation anymore.

I convinced the business to move us to something more modern and fast... Angular.js Example ecommerce site snippet in Angular.js
We built a massive single page app before I fully understood that this was an SEO-driven business where first page load times matter a *lot*.

SEO and conversions tanked, and the business lost a lot of money.

In hindsight, server side rendering was essential for this business: Ecommerce site snippet in Next.js
Some tips and tools to refactor better.

1. Write tests to ensure updates match the prior behavior
2. Use type-safe languages to avoid silly mistakes
3. Get feedback on your changes via code reviews
Also, use tools that can understand and match your existing coding style and reuse existing code.

E.g. when turning Figma designs into code Visual Copilot by @builderio will reuse your existing components and match your specific coding style via custom instructions.
Oh you're still here?

Well I have something for you.

More examples and depth on this topic in my full blog post: builder.io/blog/good-vs-b…
Theres also a YouTube video on this by yours truly if you like vids

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Steve (Builder.io)

Steve (Builder.io) Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @Steve8708

Aug 22, 2024
LLMs are pretty cool when they're not being incredibly stupid

In your products, you need more of the smart parts and less of the dumb parts

Steal my tricks for making LLMs as least dumb as possible 🧵 Two code examples pointing out that adding specificity to the prompt yields better results
The Achilles heel of LLMs is hallucination, aka giving confidently wrong answers

E.g. if you ask chatgpt "how do I create a user with 's APIs" it'll say "create a POST to /api/v1/users"

Thing is, this API doesn't exist, and never did

So what can you do? Builder.io
A diagram showing AI gives both correct responses and incorrect hallucinations
LLMs are bad at acknowledging what they don't know

But they are good at answering questions from a well defined context

So instead, you can provide a set of information via RAG (retrieve it and supply it in the prompt) and tell the LLM to *only* answer questions from this data A code example showing RAG
Read 15 tweets
Apr 18, 2023
ChatGPT now in your terminal!

Chat mode was just added to AI Shell, and it's shockingly handy
Totally free and open source, just requires an OpenAI API key - github.com/builderio/ai-s…
Hoping to add more backends in the future, such as Alpaca so you can use this completely free with no API keys needed

Looking for contributors! github.com/BuilderIO/ai-s…
Read 4 tweets
Feb 14, 2023
8 modern browser APIs you might not know, but really should:
structuredClone() gives you browser native deep cloning that supports a variety of types like Date, Set, Map, etc
Promise.allSettled helps you await multiple promises concurrently to increase perceived performance, while still handling errors effectively
Read 10 tweets
Jan 15, 2023
the code was written like 3 weeks ago ok Spiderman pointing at himse...
In all seriousness though, I know I post a lot of coding tips and "do this not that" best practices stuff, but I want to use this as a reminder to point out...
I don't write perfect code. No one does. My code has been complained about by fellow engineers as much as anyone, if not probably more.
Read 6 tweets
Jan 7, 2023
One new way you can make fetch() more elegant is to use the new Error.prototype.cause property in JS:

const res = await fetch(...)
if (!res.ok) {
throw new Error('...', { cause: res })
}

...

catch (err) {
if (err.cause.status === ...) {
// Handle each status
}
}
Full code example: Screenshot of the code:  try {   const res = await fetch('/u
You can even write your own tiny wrapper around fetch to make it more intuitive now too: Screenshot of the following code:  async function myFetch(..
Read 7 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(