Tari Ibaba

Tari Ibaba is a software developer with years of experience building websites and apps. He has written extensively on a wide range of programming topics and has created dozens of apps and open-source libraries.

10 tips to supercharge VS Code and code 10x faster (0 to 100)

95% of developers are just wasting the potential of VS Code.

It has so many hidden gems that upgrade your productivity and quality of life — but they’re not using them.

Use these 10 solid tips to gradually supercharge VS Code and code faster: with powerful extensions, little-known keyboard shortcuts, beautiful fonts & colors, and so much more.

1. First things first

Starting with the essentials.

Learn important keyboard shortcuts

You will code so much faster once you learn these

  • Copy line with Ctrl + C
  • Highlight code left & right with Shift + Left / Right
  • Move line up / down with Alt + Up / Down
  • Delete line with Ctrl + K
  • Close file with Ctrl + W
  • Close all files with Ctrl + K, W

Enable autosave

To save your files automatically.

I’ve talked about why I dislike autosave before, but it’s a great feature to stop the constant Ctrl + S’s.

Set up outline view

The Outline View gives you a quick overview of all the symbols in your active file from the File Explorer Pane:

But I recommend you move to a separate pane to have more space:

2. Set up source control

You need to set up integrations for Git to easily track your changes.

Init repo with VS Code

Use the Source Control Pane to initialize a new local repo.

Commit changes

You can quickly stage your files and press Ctrl + Enter anytime you need to commit:

Install this extension

Now install the GitLens extension for even better integration:

GitLens will show you essential repo data and info on your current file — file history, commits, branches, and more.

Place the cursor on any line in the editor and GitLens will display info on the latest commit where the line was changed:

3. Code faster with AI

GenAI has booming recently and now we have extensions that give you intelligent AI code completions as you type.

And IDE-integration chatbots, some of which use context from your codebase.

Great ones you can try:

  1. GitHub Copilot: paid, $10/month
  2. Coding Beauty Assistant: free, $10 per month for more features
  3. Tabnine: has free version, $12 per month

4. Learn snippets to code faster

Emmet

With this I type much faster when working with JSX, CSS, HTML, and more.

One thing you’ll notice is how similar the abbreviations are to CSS selectors.

This is by design: Emmet syntax is inspired by CSS selectors.

Install this extension

JavaScript (ES6) code snippets: fully loaded with heaps of time-saving code snippets for JavaScript.

See how the imp and imd snippets quickly import the modules with the ES6 syntax:

5. Install keymaps and feel at home

Priceless if you’re used to another code editor.

So if you’re coming from:

  1. Vim: Install this extension
  2. Atom: Install this extension
  3. Visual Studio: Install this extension

For example in Atom, you could easily press A and Shift + A to create a new file or a new folder.

Installing the Atom keymap instantly brings this shortcut to VS Code — no need to manually edit hotkeys:

6. Start auto-linting code

You should install a linter to avoid errors and enforce style.

Use ESLint to quickly find and fix problems in your JS code and easily avoid poor coding practices — like unused vars:

7. Enable auto-formatting

Install Prettier to automatically format your code with consistent formatting.

With Format On Save, Prettier instantly formats your code when you press Ctrl + S.

You can enable it in Settings:

8. Set up debugging and testing

So VS Code already gives you fantastic debugging features.

Set breakpoints, inspect the call stack, watch variables and more.

Testing

These extensions will make testing much easier:

Clicking Run runs the particular test case with no need for the terminal.

9. Use a more code-friendly font

If you look closely you’ll see that I’m NOT using the default Consolas font.

I’m using Cascadia Code — a beautiful font from Microsoft with aesthetically pleasing code ligatures.

Ligatures:

Fira Code is another great one I’ve used:

You can easily change your font in settings:

10. Beautify your editor with colorful themes

Color themes

Set up a beautiful theme to easily modify the colors of all the aspects of the UI.

Including your code’s highlighting:

Some great themes I’ve used:

You can change themes with the Settings icon:

Icon themes

The way VS Code displays icons in the File Explorer Pane is pretty underwhelming:

That’s why you should install VS Code Icons and spice things up:

The distinct icons make it much easier to understand every file and the purpose they play in the codebase.

Go from 0 to 100 in VS Code

Final thoughts

With all these new settings & extensions, you’re all set up to build rapidly and achieve your dev goals much faster.

The 5 most transformative JavaScript features from ES13

ES13 was packed with valuable features that completely transformed the way we write JavaScript.

Code became cleaner, shorter, and easier to write.

Let’s check them out and see the ones you missed.

1. Top-level await

With ES13 we were finally able to use await in the global scope!

❌ Before ES13:

JavaScript
// ❌ Syntax error: await is only valid in async functions await setTimeoutAsync(3000); function setTimeoutAsync(timeout) { return new Promise((resolve) => { setTimeout(() => { resolve('codingbeautydev.com'); }, timeout); }); }

We always had to put it in an async function or create an async IIFE:

JavaScript
// async IIFE (async () => { await setTimeoutAsync(3000); })(); // à la C++ async function main() { await setTimeoutAsync(3000); }

✅ After ES13:

JavaScript
// ✅ Waits for timeout - no error thrown await setTimeoutAsync(3000); function setTimeoutAsync(timeout) { return new Promise((resolve) => { setTimeout(() => { resolve('codingbeautydev.com'); }, timeout); }); }

2. Class declaration upgrades

Class field declarations

Before ES13 we could only declare class fields in the constructor!

Unlike in many other languages we could not declare or define them in the outermost scope of the class.

❌ Before:

JavaScript
class Site { constructor() { // ❌ wouldn't work outside this.url = 'codingbeautydev.com'; this.color = '🔵blue'; } } const site = new Site(); console.log(site.url); // codingbeautydev.com console.log(color); // blue

✅ Now with ES13:

Just like in TypeScript:

JavaScript
class Site { // ✅ no constructor needed url = 'codingbeautydev.com'; color = '🔵blue'; } const site = new Site(); console.log(site.url); // codingbeautydev.com console.log(color); // 🔵blue

Private methods and fields

Creating private methods was impossible before ES13.

We also had to the ugly underscore hack to indicate privacy — but that was just an indication.

❌ Before:

JavaScript
class Person { _firstName = 'Tari'; _lastName = 'Ibaba'; get name() { return `${this._firstName} ${this._lastName}`; } } const person = new Person(); console.log(person.name); // Tari Ibaba // We can still access private members! console.log(person._firstName); // Tari console.log(person._lastName); // Ibaba // They can also be modified person._firstName = 'Lionel'; person._lastName = 'Messi'; console.log(person.name); // Lionel Messi

✅ Now after ES13:

We can add private fields and members to a class by prefixing it with a hashtag (#):

You’ll get a syntax error if you try to access it from outside the class:

JavaScript
class Person { #firstName = 'Tari'; #lastName = 'Ibaba'; get name() { return `${this.#firstName} ${this.#lastName}`; } } const person = new Person(); console.log(person.name); // SyntaxError: Private field '#firstName' must be // declared in an enclosing class console.log(person.#firstName); console.log(person.#lastName);

We can see something interesting from the error message:

The compiler doesn’t expect you to even try to access private fields from outside the class — it assumes you’re trying to creating one.

Static class fields and static private methods

Static fields — properties of the class itself rather than any specific instance.

Ever since ES13 we can now easily create them for any class:

JavaScript
class Person { static #count = 0; static eyeCount = 2; static getCount() { // Access fellow static member with this return this.#count; } // instance member constructor() { // Access static member with this.constructor this.constructor.#incrementCount(); } static #incrementCount() { this.#count++; } } const person1 = new Person(); const person2 = new Person(); console.log(Person.getCount()); // 2

3. Array upgrades: new at() method

So usually we’d use square brackets ([]) to access the Nth of the array.

JavaScript
const arr = ['a', 'b', 'c', 'd']; console.log(arr[1]); // b

But accessing the Nth item from the end was always a pain — we had to index with arr.length - N:

❌ Before ES13:

JavaScript
const arr = ['a', 'b', 'c', 'd']; // 1st element from the end console.log(arr[arr.length - 1]); // d // 2nd element from the end console.log(arr[arr.length - 2]); // c

Luckily ES13 brought a new at() method that solved all that:

JavaScript
const str = 'Coding Beauty'; console.log(str.at(-1)); // y console.log(str.at(-2)); // t

4. Static class blocks

With static fields came static blocks.

To execute code only once, at the creation of the class — just like static constructors in OOP languages like C# and Java.

So you can create as many of them as you want in the class — all the code will run in the order you defined them:

JavaScript
class Vehicle { static defaultColor = 'blue'; } class Car extends Vehicle { static colors = []; static { this.colors.push(super.defaultColor, 'red'); } static { this.colors.push('green'); } } console.log(Car.colors); // [ 'blue', 'red', 'green' ]

5. Error reporting upgrades

So sometimes we catch errors of methods down the call stack only to rethrow it back up the stack.

But when we do this we lose crucial information from the original error:

JavaScript
try { userAction(); } catch (err) { // ❌ doesn't know fundamental cause of error console.log(err); } function userAction() { try { apiCallThatCanThrow(); } catch (err) { // 👇 rethrow throw new Error('New error message'); } } function apiCallThatCanThrow() { console.log('fetching from codingbeautydev.com...'); throw new Error('throwing for no reason'); }

That was why ES13 introduce a new cause property to preserve this important info and make debugging easier:

JavaScript
try { userAction(); } catch (err) { // ✅ now knows what caused the error console.log(err); console.log(`Cause by: ${err.cause}`); } function userAction() { try { apiCallThatCanThrow(); } catch (err) { // ✅ error cause throw new Error('New error message', { cause: err }); } } function apiCallThatCanThrow() { console.log('fetching from codingbeautydev.com...'); throw new Error('throwing for no reason'); }

Final thoughts

Overall ES13 was a significant leap for JavaScript with several features that have become essential for modern development.

Empowering you to write cleaner code with greater conciseness, expressiveness, and clarity.

Why parseInt(0.0000005) returns 5 in JavaScript

An interesting occurrence showing the sheer weirdness of JavaScript:

Just when you thought you knew everything about parseInt:

The funny thing is it returns 0 for four and five zeroes after the decimal point.

But just add one more zero and it starts acting crazy?

The difference from Number is even more stark.

parseInt vs Number — four and five zeroes:

But:

parseInt vs Number — six zeroes:

But we figure it out eventually.

parseInt: The missing parts

By understanding how the parseInt function work:

It takes two arguments: the string and the base or radix.

JavaScript
parseInt(string) parseInt(string, radix)

Look what it does for 6 zeroes when it’s a string:

JavaScript
parseInt('0.5') // 0 parseInt('0.05') // 0 parseInt('0.005') // 0 parseInt('0.0005') // 0 parseInt('0.00005') // 0 parseInt('0.000005') // 0 // 6 parseInt('0.0000005') // 0 parseInt('015') // 15 parseInt('015', 8) // 13

But for Number:

JavaScript
Number('0.5') // 0.5 Number('0.05') // 0.05 Number('0.005') // 0.005 Number('0.0005') // 0.0005 Number('0.00005') // 0.00005 Number('0.000005') // 0.000005 // 6 ! Number('0.0000005') // 0.0000005 Number('015') // 15

But what happens when it’s a number?

A number like 0.0000005?

Step 1: Convert the number to a string

Number gets coerced to a string!

So look what parseInt does to 0.0000005:

JavaScript
String(0.5); // => '0.5' String(0.05); // => '0.05' String(0.005); // => '0.005' String(0.0005); // => '0.0005' String(0.00005); // => '0.00005' String(0.000005); // => '0.000005' String(0.0000005); // => '5e-7' 👈 this is important

Step 2: Do the actual rounding

So:

parseInt(0.0000005) parseInt('5e-7')

And now see what happens for '5e-7' for parseInt:

Why?

Because of how parseInt works: It interprets only the leading portion of the string as an integer value.

It doesn’t recognize e, so it ignores it and everything onwards.

This is same reason why:

  1. parseInt(999999999999999999999) parseInt(1e+21) 1
  2. parseInt(0.0000007) parseInt(7) 7

So Number is your best bet if you wanna avoid surprises when converting a string to a number

And if you need just the integer part, Math.floor() is here for you:

JavaScript
Math.floor(0.5); // 0 Math.floor(0.05); // 0 Math.floor(0.005); // 0 Math.floor(0.0005); // 0 Math.floor(0.00005); // 0 Math.floor(0.000005); // 0 Math.floor(0.0000005); // 0 ✅ perfect

How I get $1000+ freelance clients consistently as a software developer (5 ways that work)

Don’t make the same mistake I did.

I used to spend hours cold-emailing strangers and applying to random low-quality job listings.

I thought it was all a numbers game.

But it was a complete and utter waste of time.

The truth is there are only 5 major strategies that work — and they are NOT easy (sorry).

If you use them blindly like 95% of people do: you will fail.

Or you get flaky, low-quality clients — if you’re lucky.

1. Build your 1st party network the right way

Most ways of networking are just a waste of time for freelancing.

Either they don’t work or it’s not worth it.

I don’t follow the tired clichéd advice of attending network events and meetups.

You will achieve much faster results online.

2 major ways I use:

  • Internal network building

My primary strategy.

I meet new people from people already in my network on WhatsApp and my email contacts.

These people end up either becoming clients or referring me to clients.

But it won’t work when you don’t have any network in the first place.

In that case, you’ll do:

  • External network building

You deliberately search for new people on social platforms — LinkedIn and Twitter are the best.

But you won’t just add any random people — quality matters just as much as quantity.

They need to meet specific criteria:

Example: if you already have a client in mind, you’d search for people in their network — like employees of the company.

2. Join an exclusive freelance network

This was by far the easiest way for me.

Building your network from scratch gives you more control — but it takes a lot of time, effort, and planning.

This is much faster.

In the networks I’m in I get offered at least 3 new freelancing opportunities every single day.

I don’t accept them all but when I do — these are no-nonsense clients with serious budgets.

But the hard part was finding legit networks and getting entry — they’re called exclusive for a reason.

3. Use freelancing platforms properly

Upwork is dead!

No it’s not. If it’s dead then where is their $1,400,000,000 market cap coming from?

You’re using it wrong. Simple.

For a start:

  • Don’t be a generalist:

“Programmer” won’t get you far.

“Next.js web developer” is much better.

“Next.js web developer building AI chatbots” is powerful.

  • Don’t expect fast money

I can tell you for free — starting from scratch on any online platform is no easy feat.

But once you get past a certain point, all the initial focus and consistency will be worth it.

  • Don’t be intimidated by the competition

A job may have 50+ proposals but many of the applicants are just mass-buying connections and spamming with AI.

You’ll stand out greatly if you personalize your cover letter.

4. Create “content”

And by content I don’t only mean posting on social media or blogging.

“Content” also includes your portfolio — on GitHub and more.

It means creating significant projects in your niche and talking about them.

It means sharing your experience and teaching others what you know.

Your discoveries, ideas, opinions, and what you’re passionate about.

You will boost your visibility and improve your chances of attracting great opportunities.

5. Run targeted ads

I put this one last because it’s quite risky.

Without a well-defined strategy, you’ll end up wasting money and getting nothing out of it.

You’ll need to run extremely targeted ads on Google, LinkedIn, and Facebook — and constantly refine your approach to see any real results.

Follow one or more of these strategies with persistence and you’ll eventually find high-quality clients.

Key points

Recap: 5 major ways to find $1000+ freelance clients as a software developer:

  1. Build your 1st party network
  2. Join an exclusive freelance network
  3. Use freelancing platforms properly
  4. Create content and code
  5. Run paid ads

New HTML <dialog> tag: An absolute game changer

HTML will never be the same with the new <dialog> tag.

❌Before:

See how much work it would have taken me to create a dialog 👇

Almost 20 lines of CSS alone:

And that’s just CSS for the dialog functionality — it will still look very basic:

But how about with the new <dialog> tag!

✅ Now:

HTML
<button id="open">Open</button> <dialog id="dialog"> ⚡Lighting strikes the earth 44 times every second! </dialog>
JavaScript
const dialog = document.getElementById('dialog'); const open = document.getElementById('open'); open.addEventListener('click', () => { dialog.showModal(); });

We can even use the show() method to show a non-modal dialog — less intrusive with no backdrop:

JavaScript
const dialog = document.getElementById('dialog'); const open = document.getElementById('open'); open.addEventListener('click', () => { dialog.show(); });

Dialogs have always been a powerful way to forcefully seize your user’s attention and slam information in their faces.

It’s been a staple feature of every UI design system from Material Design to Fluent Design.

But even as common as they are we always had to resort to third-party libraries or create custom components to use them.

And many of these libraries don’t even follow the official recommendations for usability & accessibility…

Example: pressing the Escape key should dismiss the dialog on the page — but this doesn’t happen for many custom dialogs.

So <dialog> changes all that.

Auto-open dialog

The open attribute keeps the dialog open from the moment you open the page:

HTML
<dialog id="dialog" open> Giraffes are much more likely to be struck by lightning than humans are. In fact, they're 30 times more likely </dialog>

Auto-close button

Yes, you could add close functionality with standard event listeners and the close() method:

JavaScript
const close = document.querySelector( '#dialog .close' ); close.addEventListener('click', () => { dialog.close(); });

But the built-in <dialog> makes this even easier — no JavaScript needed:

HTML
<dialog id="dialog"> ⚡Gain essential coding skills & knowledge at codingbeautydev.com <br /> <form method="dialog"> <button class="close">Close</button> </form> </dialog>

How to style <dialog> the right way

<dialog> has a special ::backdrop pseudo-element for styling the backdrop:

CSS
::backdrop { background-image: linear-gradient( 45deg, magenta, rebeccapurple, dodgerblue, green ); opacity: 0.75; }

Styling the main element is straightforward:

CSS
dialog { background-color: black; color: white; }

Final thoughts

With the new HTML <dialog> tag, creating modals and dialogs in our web apps has never been easier and faster.

How to write “natural” code everybody will love to read

The biggest reason we use languages like JavaScript and Python instead of Assembly is how much closer to natural language they are.

Or how much they CAN be!

Because sometimes we write code just for it to work without any care about demonstrating what we’re doing to other humans.

And then this backfires painfully down the line. Especially when one of those humans is your future self.

Parts of speech: back to basics

You know your code is natural when it resembles English as much as possible. Like an interesting, descriptive story.

It means you’ve intelligently made the entities and actions in the story to powerfully express the code flow from start to completion.

Nouns

What entities are we talking about?

  • Variables
  • Properties (getters & setters)
  • Classes & objects.
  • Modules

Every character has a name, so we describe them with expressive nouns and noun phrases.

Not this:

JavaScript
// ❌ do-examples.ts // ❌ Cryptic const f = 'Coding'; const l = 'Beauty'; // ❌ Verb const makeFullName = `${f} ${l}`; class Book { // ❌ Adjectival phrase createdAt: Date; }

But this:

JavaScript
// ✅ examples.ts // ✅ Readable const firstName = 'Coding'; const lastName = 'Beauty'; // ✅ Noun const fullName = `${firstName} ${lastName}`; class Book { // ✅ Noun phrase dateCreated: Date; }

Verbs

What are the actions in your codebase?

  • Functions
  • Object methods

An action means an entity is doing something; the naturally way to name them is with descriptive verbs and verb phrases.

Not this:

JavaScript
class Product { constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity; } // ❌ Noun total() { return this.price * this.quantity; } } const product = new Product('Pineapple🍍', 5, 8); console.log(product.total()); // 40

But this:

JavaScript
class Product { constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity; } // ✅ Verb getTotal() { return this.price * this.quantity; } } const product = new Product('Banana🍌', 7, 7); console.log(product.getTotal()); // 49

Methods are for doing something. Properties are for having something.

So better still:

JavaScript
class Product { constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity; } get total() { return this.price * this.quantity; } } const product = new Product('Orange🍊', 7, 10); console.log(product.total); // 70

Adverbs

Remember an adverb tells you more about a noun or verb or another adverb.

In JavaScript this is any function that takes function and returns another: a higher-order function. They upgrade the function.

So instead of this:

JavaScript
// ❌ Verb function silence(fn) { try { return fn(); } catch (error) { return null; } } const getFileContents = (filePath) => silence(() => fs.readFileSync(filePath, 'utf8'));

It’ll be more natural to do this:

JavaScript
// ✅ Adverb function silently({ fn }) { // or "withSilence" try { return fn(); } catch (error) { return null; } } const getFileContents = (filePath) => silently({ fn: () => fs.readFileSync(filePath, 'utf8') });

It’s like saying, “Get the file contents silently“.

Natural inputs

Coding and computing are all about processing some input to produce output.

And in natural code the processing is action and the input + output are entities.

Let’s say we have a function that calculates a rectangle’s area and multiplies it by some amount.

Can you see the problem here?

JavaScript
const area = calculateArea(2, 5, 10); // 100

Which argument is the width and height? Which is the multiplier?

This code doesn’t read naturally; In English we always specify objects of an action.

How to fix this? Named arguments:

JavaScript
// Inputs are entities - nouns✅ const area = calculateArea({ multiplier: 2, height: 5, width: 10 }); function calculateArea({ multiplier, height, width }) { return multiplier * height * width; }

This is far easier to read; we instantly understand what inputs we’re dealing with.

Even when there’s just 1 argument I recommend using this.

Natural outputs

And we can be just as explicit in our outputs:

JavaScript
const { area } = calculateArea({ multiplier: 2, height: 5, width: 10, }); function calculateArea({ multiplier, height, width }) { return { area: multiplier * height * width }; }

Which also allows us easily upgrade the function later:

JavaScript
const { area, perimeter } = calculateArea({ multiplier: 2, height: 5, width: 10, }); console.log(area, perimeter); // 100 60 function calculateArea({ multiplier, height, width }) { return { area: multiplier * height * width, perimeter: (height + width) * 2 * multiplier, }; }

There’s no time for magic

Coding isn’t a mystery thriller! It’s a descriptive essay; be as descriptive as possible.

Not this cryptic mess:

JavaScript
function c(a) { return a / 13490190; } const b = c(40075); console.log(p); // 0.002970677210624906

What do all those numbers and variables mean in the bigger picture of the codebase? What do they tell us – the human?

Nothing. They tell us nothing. The entity & action names are either non-existent or of terrible quality.

It’s like telling your friend:

Yeah I went to this place and did this thing, then I did something to go to this other place and did something of 120!.

This is nonsense.

Natural code describes everything. Nice nouns for entities, great verbs for the actions.

JavaScript
const speedstersSpeedKmPerHr = 13490190; const earthCircumferenceKm = 40075; function calculateSpeedstersTime(distance) { return distance / speedstersSpeedKmPerHr; } const time = calculateSpeedstersTime(earthCircumferenceKm); console.log(time); // 0.002970677210624906 ~ 11s

Now you’ve said something.

Yeah I went to the restaurant and ate a chicken sandwich, then I drove to the gym and did bicep curls of 120 pounds!.

Create “useless” variables

Variables in natural code are no longer just for storing values here and there.

They’re also tools to explain what you’re doing:

That’s why instead of doing this:

JavaScript
if ( !user.isBanned && user.pricing === 'premium' && user.isSubscribedTo(channel) ) { console.log('Playing video...'); }

We’ll do this:

JavaScript
const canUserWatchVideo = !user.isBanned && user.pricing === 'premium' && user.isSubscribedTo(channel); if (canUserWatchVideo) { console.log('Playing video...'); }

We’re going to use the variable only once but it doesn’t matter. It’s not a functional variable but a cosmetic variable; a natural variable.

Final thoughts

Code is for your fellow humans too, not just compilers.

Can someone who doesn’t know how to code understand what’s going on in your code?

This is no doubt a powerful guiding question to keep your code as readable an natural as possible.

5 unexpected ways coding upgrades your life — beyond making money

I could code for many hours straight but I usually couldn’t say the same about writing!

And I always wondered why.

But I knew it was because of certain underlying emotions and values I felt when coding but didn’t quite feel for writing.

Eventually, I discovered at least 5 things about coding that make it so enjoyable and meaningful.

Things that can make any activity more pleasurable and fulfilling.

1. Purpose

There’s a deep sense of purpose in coding that gives us constant drive & passion.

A reason to wake up in the morning.

Every massive coding project is a brand new mission in itself with lots of exciting goals & milestones.

It’s an endless adventure.

Imagine creating an endless runner game like Subway Surfers from scratch:

You will have so many invigorating things to do:

  • Download & install the game engine: like Unity
  • Create the sprites: characters, hoverboards, costumes, etc.
  • Create the algorithm for the endless running…

Every milestone gives you a strong sense of accomplishment & direction.

2. Growth: of people & code

You

Growing as a person makes life feel new and exciting.

You grow when you gain more of something valuable:

  • Strength: Levelling up at the gym
  • Freedom: Beating an addiction: alcohol, porn, etc.
  • Knowledge: Becoming more fluent in a language

As you improve your coding knowledge & skills you feel like you’re making focused progress as an individual.

You get better at:

  • Solving problems: and designing algorithms
  • Writing clean, readable code
  • Writing modular cohesive code with minimal coupling

Your code

You nurture when you help something else grow:

  • Raising children
  • Body transformation coaching
  • Gardening

When you code, you nurture programs.

Every new line and every new commit upgrades the system with new capabilities.

At a high level:

  • You give it more features
  • You make it faster
  • You improve the UI

Low-level:

  • You refactor: greater readability
  • You fix bugs
  • You create tests: greater stability

3. Cognitive challenge: and mental stimulation

No secret that coding makes your brain work!

Just like:

  • Chess
  • Philosophy
  • Debating & solving math proofs

You need lots of logical processing and memory retrieval to create problem-solving algorithms.

Especially for complex games and backend-heavy apps.

You stretch your cognitive abilities and enter into an enjoyable state of flow — keeping you glued to the chair for hours.

And when you’re done you feel a deep sense of accomplishment.

It’s a key reason why we created Coding Beauty Play — regular puzzles to test your memory and make you think!

Just see all the processing needed to go from the formatted string to the number:

4. Power: of creation & automation

Coding transforms you into an all-powerful digital god.

You can autonomously create a brand new world of your own with nothing but your thoughts.

It’s a major reason why game programming and front-end UI design can be so exciting.

And where did all the millions of games & apps we use every day come from?

They didn’t come from the investor money or the code editors; these were just tools.

They came from the minds of the creators and developers.

It all started with an idea — ideas that go on to revolutionize the world and generate billions.

Making an impact on both the virtual and physical world.

Of automation

With coding, you complete unbelievable amounts of work in fractions of a second.

Think of all the work Google Search does every day:

  • 99,000 queries every second
  • 8.5 billion searches per day
  • 2 trillion global searches per day

This is simply out of the bounds of manual human ability, to put it lightly.

With automation I finally stopped those annoying Windows Updates.

By creating a tiny app to constantly stop the services any time Windows auto-restarted them.

5. Unity: of code & humans

Of code

Coding brings you face-to-face with the beauty of collaboration.

You experience the magnificence of various components of a complex system cohesively working together towards a common end.

Like carefully connected pieces on a chessboard working in harmony.

You see this when you split up your files into modules and objects.

Every single module plays its role in achieving the overall goals of the larger system.

They have the opportunity to be part of a community; of something bigger than themselves.

Of humans

And so do we when we work as a team.

We feel a shared sense of belonging as we strive toward a common goal together.

We are energies by the connection and fulfilled by our contributions towards the group and the mission.

Join the community on Discord for more engaging & free-flowing discussions on these things, and tips for leveling up and earning more as a developer.

10 must-have skills to become a top 1% web developer

10 essential skills every web developer should have…

From web basics you may be familiar with already; then going on to crucial skills like working with browser dev tools and coding rapidly with AI.

Notice how the focus is on real-world action instead of just theoretical knowledge — because that’s what matters.

1. HTML essentials: Create a basic functional web page

All about the core skeleton of a website.

How to:

  • Create an HTML page in an editor & open it in the browser
  • Set page title & icon
  • Create paragraphs of text
  • Create headings
  • Create links to other pages
  • Display images
  • Display tabular data
  • Show lists of elements
  • Handle input with forms
  • Create comments & comment out code
  • Make your page more meaningful with Semantic HTML

Some people think semantic HTML is useless because of CSS but they’re wrong.

It’s still crucial for accessibility and explaining your page to search engines to rank high on the results page.

JavaScript
<!-- tells search engine that the "AI singularity" is a time --> <time datetime="2025-01-07">AI singularity</time> is coming sooner than you think!

Without this you end up like those devs who use <div> for everything.

2. CSS essentials: Style the web page

That’s how you can go from this:

To this:

Enriching the skeleton with life.

How to:

  • Add styles to a page
  • Add colors: Fills, gradients, opacity, foreground vs background colors
  • Customize fonts: Font family, size, styles, weight, web-safe fonts, Google Fonts
  • Create layouts: Margin & padding, visual stacking, relative alignments
  • Add and customize backgrounds
  • Add flair with animations and transitions
  • Style particular states and parts of elements: Pseudo-selectors and pseudo-classes
  • Customize shape: outline & borders, height, width,
  • Reuse styles: CSS variables
  • Make your page look great for all screen sizes: breakpoints, responsive images,
  • Style faster with frameworks: Tailwind, Sass

3. JavaScript essentials

How to add interactivity to your web pages and make things happen:

Basics

If you’re new to coding:

How to:

  • Think about programming
  • Add JavaScript code to a page
  • Print output: alert(), innerHTML, console logging
  • Manage data — Create, use, update, and print variables: data types, scopes
  • Create comments & comment out existing code
  • Reuse actions: Create & call functions: syntax, parameters & arguments, return values, types, scopes
  • Create objects to represent real-world entities: data & variables, actions & methods, nested objects
  • Select and manipulate elements on a page: getElementById, querySelector, use methods & properties, etc.
  • Handle input & events: on a web page, etc.
  • Manipulate text with strings: multiline, substrings, case, concatenate, interpolate, split & join, trim & pad, search & replace, regex
  • Use lists: initialize, add, update, remove, iterate, transform, search, filter, sort, reverse
  • Use date and time: Create, update, format & display
  • Get data or do action conditionally: if/else, switch, ternaries, dictionary selection
  • Indefinitely do action conditionally: while, do while, for, break, continue
  • Upgrade your dev experience with TypeScript: types, generics, interfaces, transpiling, configuring, etc.

Develop for the client-side

You may know coding basics in & out but can you write JS code specifically for the browser?

How to:

  • Make network requests to a server: fetch() API, HTTP verbs, send & get data
  • Handle UI states: empty, loading, error, partial, ideal
  • Store data locally: cookies, Local Storage, Session Storage, etc.
  • Organize and package code: modules & module bundlers
  • Handle form input
  • How to code faster with NPM packages

4. Improve quality of life with dev tools

How to:

  • Create, inspect, & filter console logs: info, errors, warnings
  • Add temporary scripts & actions
  • Inspect, select & debug HTML elements
  • Inspect & temporarily modify styles
  • Monitor network requests
  • Test your pages on multiple screen sizes
  • Install editor extensions to develop faster
  • Customize editor themes, fonts, and settings to enjoy development more
  • Use an integrated debugger
  • Code faster with snippets: including Emmet
  • Develop faster with keyboard shortcuts
  • Use AI to develop faster

5. Improve site performance

How to:

  • Measure performance
  • Improve perceived performance
  • Improve Core Web Vitals: LCP, CLS, INP
  • Optimize general resource delivery: caching,
  • Optimize images: compressing, WebP
  • Lazy load images & video
  • Optimize CSS
  • Optimize web fonts: compressing, swapping, etc.

6. JavaScript framework: Develop faster

Whether it’s React, Angular, or Vue, they all have the same fundamental concepts:

How to:

  • Create and reuse components
  • Accept & display data in components: data binding, conditional rendering, etc.
  • Manage state in a component
  • Display & update list data
  • Handle events from components
  • Handle side effects and external data changes & state changes
  • Manage app-level state — independent from components
  • Handle form input
  • Style components
  • Handle SPA navigation with frontend routing

7. Version control: Track changes

Version control makes it easy to track changes across your codebase and experiment.

How to:

  • Create a local repo to store code & assets
  • Stage and commit files & changes: best practices, etc.
  • Ignore files with .gitignore
  • Check out previous commits
  • Create new branches: from latest or previous commits
  • Merge branches: resolving merge conflicts, etc.

Git & GitHub

How to:

  • Create your own GitHub repo: README.md, licenses, etc.
  • Use remotes: Create, push, pull, remove
  • Clone a repo from GitHub
  • Fork a GitHub repo
  • Make pull requests to a GitHub repo

8. Manage data in a database

Even if you’re dedicated to frontend, knowing these will refine your understanding of data processing & manipulation.

How to:

  • Design a schema for the data
  • Implement schema: tables, keys, data types, foreign keys, collections (NoSQL)
  • Add data to the database
  • Read data: joins, filter, sort, search, aggregate
  • Update data
  • Delete data

9. Develop for the server-side

How to:

  • Respond to a request: URLs, using the header & body
  • Manage logs: Create, inspect
  • Create a RESTful API: HTTP verbs, status codes
  • Fetch data from other APIs
  • Send requests to a database: Create, read, update, delete

10. General but crucial

How to:

  • Learn rapidly on demand
  • Solve problems independently from code
  • Communicate: with designers, clients & other devs
  • Debug: and be patient
  • Search for information on demand: and process it for your needs

Final thoughts

Once you learn all these you’ll be able to build 99% of web apps and sites from start to finish with great speed and high quality of life.

The 5 most transformative JavaScript features from ES8

ES8 was packed with valuable features that completely transformed the way we write JavaScript.

Code became cleaner, shorter, and easier to write.

Let’s check them out and see the ones you missed.

1. Trailing commas

Trailing commas used to cause a syntax error before ES8!

❌ Before:

JavaScript
const colors = [ '🔴red', '🔵blue', '🟢green', '🟡yellow', // ❌ not allowed ]; const person = { name: 'Tari Ibaba', site: 'codingbeautydev.com' // ❌ nope };

But this caused some problems:

But this made things inconvenient when rearranging the list:

Also we always had to add a comma to the last item to add a new one — cluttering up git diffs:

So ES8 fixed all that:

✅ Now:

JavaScript
const colors = [ '🔴red', '🔵blue', '🟢green', '🟡yellow', // ✅ yes ]; const person = { name: 'Tari Ibaba', site: 'codingbeautydev.com', // ✅ yes };

The benefits they bring also made tools Prettier add them by default after formatting:

2. async / await

This was where it all started with async/await!

No more annoying nesting with then():

❌ Before:

JavaScript
wait().then(() => { console.log('WHERE ARE YOU?!😠'); }); function wait() { return new Promise((resolve) => setTimeout(resolve, 10 * 1000) ); }

✅ After:

JavaScript
// 💡 immediately invoked function expression (IIFE) (async () => { await wait(); console.log('WHERE ARE YOU?!😠'); })(); function wait() { return new Promise((resolve) => setTimeout(resolve, 10 * 1000) ); }

The difference is clear:

❌ Before:

JavaScript
function getSuggestion() { fetch('https://api.example/suggestion', { body: JSON.stringify, }) .then((res) => { return res.json(); }) .then((data) => { const { suggestion } = data; console.log(suggestion); }); }

✅ After:

JavaScript
async function getSuggestion() { const res = await fetch('https://api.example/suggestion'); const { suggestion } = await res.json(); console.log(suggestion); }

10 lines 3 lines.

With async/await we could finally use our native try-catch for async code:

❌ Before ES8:

JavaScript
startWorkout(); function startWorkout() { goToGym() .then((result) => { console.log(result); }) .catch((err) => { console.log(err); }); } function goToGym() { return new Promise((resolve, reject) => { if (Math.random() > 0.5) { reject(new Error("I'm tired today!😴")); } resolve("Let's go!🏃‍♂️👟"); }); }

✅ Now:

JavaScript
startWorkout(); function startWorkout() { try { goToGym(); } catch (err) { console.log(err); } } function goToGym() { return new Promise((resolve, reject) => { if (Math.random() > 0.5) { reject(new Error("I'm tired today!😴")); } resolve("Let's go!🏃‍♂️👟"); }); }

3. Powerful Object static methods

Object.values()

A brilliant static method to extract all the values from an object into an array:

JavaScript
const person = { name: 'Tari Ibaba', site: 'codingbeautydev.com', color: '🔵blue', }; const arr = Object.values(person); // ['Tari Ibaba', 'codingbeautydev.com', '🔵blue'] console.log(arr);

Awesome for data visualization:

JavaScript
const fruits = [ { name: 'Banana', pic: '🍌', color: 'yellow', }, { name: 'Apple', pic: '🍎', color: 'red', }, ]; const keys = Object.keys(fruits.at(0)); const header = keys.map((key) => `| ${key} |`).join(''); const rows = fruits .map((fruit) => keys.map((key) => `| ${fruit[key]} |`).join('') ) .join('\n'); console.log(header + '\n' + rows);

Object.entries()

Bunches each key-value pair in the object to give a list of tuples:

JavaScript
const person = { name: 'Tari Ibaba', site: 'codingbeautydev.com', color: '🔵blue', }; const arr = Object.entries(person); /* [ [ 'name', 'Tari Ibaba' ], [ 'site', 'codingbeautydev.com' ], [ 'color', '🔵blue' ] ] */ console.log(arr);

Great for data transformations using both the object key and value:

Object keyed by ID list of objects:

❌ Before:

JavaScript
const tasks = { 1: { title: '👟HIIT 30 minutes today', complete: false, }, 2: { name: 'Buy the backpack🎒', complete: true, }, }; const taskList = Object.keys(tasks).map((id) => ({ id, ...tasks[id], })); console.log(taskList);

✅ Now:

JavaScript
// ✅ cleaner const taskList = Object.entries(tasks).map( ([id, task]) => ({ id, ...task, }) ); console.log(taskList);

4. Native string padding

On the 22nd of March 2016, the popular NPM package left-pad broke several thousands of software projects after the creator took it down as a form of protest.

It made a lot of people worried about our possible over-dependence on external modules — even something as simple as string padding.

But luckily ES8 brought native string padding to JavaScript with the padStart and padEnd string methods:

JavaScript
const name = 'tari'; console.log(name.padStart(9, ' ')); // ' tari' console.log(name.padEnd(10, '🔴')); // 'tari🔴🔴🔴'

We no longer needed to rely on yet another 3rd party dependency.

5. Object.getOwnPropertyDescriptors()

Semi-fancy name but effortless to understand.

Descriptors are properties of properties — one of these:

  • value
  • enumerable
  • get
  • set
  • configurable
  • enumerable
JavaScript
const person = { name: 'Tari Ibaba', color: '🔵color', age: 999, greet: () => console.log('Hey!'), }; console.log( Object.getOwnPropertyDescriptors(person) );

Final thoughts

Overall ES8 was a significant leap for JavaScript with several features that have become essential for modern development.

Empowering you to write cleaner code with greater conciseness, expressiveness, and clarity.

95% of users will never use your app again without this JavaScript feature

Without this JaaScript you will waste thousands of dollars and users will hate your app.

1. They will hate your app

They will be irritated by the horrible user experience and never return.

So imagine you’ve created an amazing AI writing assistant giving helpful suggestions for writing engaging stories:

You’ve got your API all set up for requests in handleChange:

JavaScript
export function AssistantUI() { const [suggestions, setSuggestions] = useState(''); const [loading, setLoading] = useState(false); const handleChange = async (event: any) => { const value = event.target.value; setLoading(true); const res = await fetch( 'https://api.writer.example.com/suggestions', { method: 'POST', body: JSON.stringify({ text: value }), } ); const json = await res.json(); setSuggestions(json.suggestions); setLoading(false); }; return ( <div className="flex flex-col justify-center flex-wrap content-start"> <textarea onChange={handleChange} className="mt-2 mb-4" cols={40} rows={10} /> { //... } </div> ); }

But unfortunately there’s a serious problem — can you spot it? 👇

I just started writing and immediately your AI is telling me nonsense about wrong spelling!

Where is my breathing space? Can’t you at least allow me to stop typing?

Oh no, I’m done — You ruined my day and I’ll never return.

But luckily that was just you in an alternate reality — the real you already knew that such UX would be annoying at best and infuriating at worst.

You’re so thoughtful and empathetic — that was why you knew this was a much better way to write handleChange:

JavaScript
export function AssistantUI() { const [suggestions, setSuggestions] = useState(''); const [loading, setLoading] = useState(false); const timeout = useRef<NodeJS.Timeout | null>(null); const handleChange = async (event: any) => { const value = event.target.value; setLoading(true); // restart delay clearTimeout(timeout.current!); // ✅ 1-second delay before fetch timeout.current = setTimeout(async () => { const res = await fetch( 'https://api.writer.example.com/suggestion', { method: 'POST', body: JSON.stringify({ text: value }), } ); const json = await res.json(); setSuggestions(json.suggestions); setLoading(false); }, 1000); }; return ( // ... ); }

Now the AI waits for 1 second before giving suggestions!

Everybody is in love with your app now – we could even stop using it if we tried…

In programming, we call this technique debouncing.

And it shows up everywhere…

  • Google Search: Any time you search, you’re experiencing debouncing in action.

Notice the delay between typing and the autocomplete update. It’s not latency, it’s debouncing.

  • Conversation: When we’re debating and you let me make my points before responding, you’re debouncing.

You didn’t interrupt and start screaming — you made sure I was done by constantly setting a subconscious timeout until I finally stopped speaking:

JavaScript
let silenceTimeout; let silenceDelay = 1000; function opponentKeepsTalking() { clearTimeout(silenceTimeout); silenceTimeout = setTimeout(() => { reply('Your fallacious premises have no basis in reality'); }, silenceDelay); }

2. You lose thousands of $$$

Your users are not the only ones getting overloaded — your servers are crying out for help.

❌ Before debounce:

1,000 users typing 10 times a second = 10 x 60 x 1000 = 600,000 requests a minute!

This load isn’t a functional issue with cloud computing but what about the costs?

Especially since you’re probably using an expensive AI service like OpenAI or GCP Vertex.

✅ Now after debounce:

Typing frequency no longer matters — if they pause typing 10 times every minute that’s

10 x 1000 = 10,000 requests a minute! A 98.3% reduction in requests and costs!

You were spending $1000 a day but now you’re spending less than $170 (!)

What took you a day to spend now takes you a week. Thanks to debounce.

But you can do better

Okay but that’s still like $5,000 a month — can’t we do better?

90% of your users are free and we need to keep their usage at a bare minimum.

Luckily you’re really smart so you quickly came up with this:

JavaScript
const timeout = useRef<NodeJS.Timeout | null>(null); const ignoring = useRef<boolean>(false); const handleChange = async (event: any) => { if (plan === 'free') { // ✅ still ignoring so nope if (ignoring.current) return; // ✅ start ignoring for 20 seconds ignoring.current = true; setTimeout(() => { ignoring.current = false; }, 20 * 1000); } // after throttle debounce(); const value = event.target.value; setLoading(true); const res = await fetch( 'https://api.writer.example.com/suggestion', { method: 'POST', body: JSON.stringify({ text: value }), } ); const json = await res.json(); setSuggestions(json.suggestions); setLoading(false); };

You ignore free users for 20 seconds after getting their last suggestion.

So only 3 suggestions per minute for them.

900 free users, 100 paying.

900 x 3 + 100 x 10 = 3,700 requests a minute — from $5,100 to $1900.

Killing two birds with one stone:

  • Massive 63% savings
  • Incentivize free users to upgrade for unlimited suggestions.

This is another technique we call throttling.

And it shows up anywhere you have periodically limited access to something:

  • GPT-4o model: Only allow 80 messages every 3 hours for Plus users, as of May 13th 2024.
  • Eating: You can only gobble up so much food at a time

Recap from our earlier debate:

  • Debounce: You wait for me to finish talking before responding and vice versa.
  • Throttle: We both have 5 minutes max at a time to talk.

With this powerful combo, what lasted only one day now lasted 3 weeks.

600,000 requests became 3,700, everyone loves your app, and you’re going to be a billionaire.