<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[The T-Shaped Dev]]></title><description><![CDATA[A newsletter sharing practical tips on React, Node, Software Architecture, and AI. Elevate your Full-Stack JavaScript skills to the next level!]]></description><link>https://thetshaped.dev</link><image><url>https://substackcdn.com/image/fetch/$s_!9lD-!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f66bb7c-c96f-4c71-ba2d-d561152c83a2_600x600.png</url><title>The T-Shaped Dev</title><link>https://thetshaped.dev</link></image><generator>Substack</generator><lastBuildDate>Sun, 05 Apr 2026 01:28:07 GMT</lastBuildDate><atom:link href="https://thetshaped.dev/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Petar Ivanov]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[petarivanovv9@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[petarivanovv9@substack.com]]></itunes:email><itunes:name><![CDATA[Petar Ivanov]]></itunes:name></itunes:owner><itunes:author><![CDATA[Petar Ivanov]]></itunes:author><googleplay:owner><![CDATA[petarivanovv9@substack.com]]></googleplay:owner><googleplay:email><![CDATA[petarivanovv9@substack.com]]></googleplay:email><googleplay:author><![CDATA[Petar Ivanov]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Dependency Injection in Node.js & TypeScript. The Part Nobody Teaches You]]></title><description><![CDATA[Learn the hidden costs about importing everything directly and the structural change you need to make. (8 min)]]></description><link>https://thetshaped.dev/p/dependency-injection-in-nodejs-and-typescript-dependency-inversion-part-no-body-teaches-you</link><guid isPermaLink="false">https://thetshaped.dev/p/dependency-injection-in-nodejs-and-typescript-dependency-inversion-part-no-body-teaches-you</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sun, 29 Mar 2026 12:19:37 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8d012d0b-328c-46d9-b752-ca354941c93c_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This post outlines a common Node.js pattern and how to solve it.</em></p><ul><li><p><em><a href="https://thetshaped.dev/p/dependency-injection-in-nodejs-and-typescript-dependency-inversion-part-no-body-teaches-you">Share this post</a> &amp; I&#8217;ll send you some rewards for the referrals.</em></p></li></ul><p>In the Java/C# world, DI containers are a religion.</p><p>In Node.js, most developers just <code>import</code> modules directly, until testing becomes a nightmare and swapping implementations means rewriting half the app.</p><p>You don&#8217;t need dependency injection containers like <a href="https://github.com/inversify/InversifyJS">InversifyJS</a> or <a href="https://github.com/microsoft/tsyringe">tsyringe</a>.</p><p>Here&#8217;s how to do dependency injection with plain TypeScript, and why it&#8217;ll make your code instantly more testable.</p><div><hr></div><h2>Dependency Injection vs. Dependency Inversion</h2><p>These terms get used interchangeably. But they're not the same.</p><p><strong>Dependency Injection</strong> (DI) is a technique: instead of a class/function creating its own dependencies, you pass them in from the outside.</p><p><strong>Dependency Inversion</strong> is a principle (the &#8220;D&#8221; in SOLID): high-level modules shouldn&#8217;t depend on low-level modules. Both should depend on abstractions.</p><p>Dependency Injection is how you implement Dependency Inversion.</p><p>But you can do DI without inverting anything. This is the place where most Node.js developers stop.</p><pre><code>// Direct dependency &#8212; no injection
import { db } from './database';

export async function getUser(id: string) {
  return db.query('SELECT * FROM users WHERE id = $1', [id]);
}</code></pre><p>This works. But you can&#8217;t test <code>getUser</code> without a real database.</p><p>You can&#8217;t swap PostgreSQL for an in-memory store.</p><p>And if <code>database.ts</code> has side effects on import, every test file that touches <code>getUser</code> pays that cost.</p><div><hr></div><h2>The Node.js Anti-Pattern: Import Everything Directly</h2><p>Here&#8217;s what most Express apps look like:</p><pre><code>// userService.ts
import { knex } from &#8216;../lib/database&#8217;;
import { sendEmail } from &#8216;../lib/email&#8217;;
import { logger } from &#8216;../lib/logger&#8217;;

export async function createUser(data: CreateUserInput) {
  const [user] = await knex(&#8217;users&#8217;).insert(data).returning(&#8217;*&#8217;);
  await sendEmail(user.email, &#8216;Welcome!&#8217;);
  logger.info(`User created: ${user.id}`);
  return user;
}</code></pre><p>There are three hardcoded dependencies. And to test this function, you need:</p><ul><li><p>A running database (or mock Knex globally)</p></li><li><p>An email service (or mock the module)</p></li><li><p>A logger (or suppress output)</p></li></ul><p>Module mocking (<code>jest.mock</code>, <code>vi.mock</code>) is the usual escape hatch, but it&#8217;s brittle because we&#8217;re mocking import paths, not the actual contracts.</p><p>For example, if you rename a file, your mocks break silently.</p><p><strong>Module mocking is a code smell.</strong></p><p>It tells you your code has hidden dependencies that should be explicit.</p><div><hr></div><h2>What Dependency Injection Actually Solves</h2><p>Before we continue further, let&#8217;s be clear about what we&#8217;re fixing:</p><ul><li><p><strong>Testability.</strong> When a module imports its dependencies directly, you&#8217;re forced into module-level mocking (<code>jest.mock()</code>, <code>vi.mock()</code>) to test it. These mocks are fragile, magical, and break when you rename a file. With DI, you pass plain objects, and no mocking framework is needed.</p></li><li><p><strong>Swappability.</strong> Imagine you have to switch from Knex to Drizzle, or from SendGrid to AWS SES. When dependencies are injected, you swap the implementation in one place. When they&#8217;re imported, you touch every file.</p></li><li><p><strong>Explicit dependencies.</strong> A function&#8217;s signature should tell you what it needs. If <code>createUser</code> secretly depends on a database, an email client, and a logger, but its signature only shows <code>data: CreateUserDTO</code>, that&#8217;s a lie. DI makes dependencies visible.</p></li><li><p><strong>Separation of concerns.</strong> Your business logic shouldn&#8217;t know (or care) whether it&#8217;s talking to Postgres or SQLite, SendGrid or a local SMTP server. DI enforces that boundary naturally.</p></li></ul><p>Now, let&#8217;s see how to do dependency injection in Node.js without any frameworks.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, and Software Architecture delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>Step 1: Constructor Injection (Manual DI)</strong></h2><p>The simplest fix: <strong>accept dependencies as parameters</strong>.</p><pre><code>// userService.ts
interface UserRepository {
  create(data: CreateUserInput): Promise&lt;User&gt;;
}

interface EmailService {
  send(to: string, subject: string): Promise&lt;void&gt;;
}

interface Logger {
  info(message: string): void;
}

export function createUserService(
  repo: UserRepository,
  email: EmailService,
  logger: Logger
) {
  return {
    async createUser(data: CreateUserInput) {
      const user = await repo.create(data);
      await email.send(user.email, &#8216;Welcome!&#8217;);
      logger.info(`User created: ${user.id}`);
      return user;
    },
  };
}</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!H_M7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!H_M7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 424w, https://substackcdn.com/image/fetch/$s_!H_M7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 848w, https://substackcdn.com/image/fetch/$s_!H_M7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 1272w, https://substackcdn.com/image/fetch/$s_!H_M7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!H_M7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png" width="1456" height="561" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:561,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:178393,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/191737097?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!H_M7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 424w, https://substackcdn.com/image/fetch/$s_!H_M7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 848w, https://substackcdn.com/image/fetch/$s_!H_M7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 1272w, https://substackcdn.com/image/fetch/$s_!H_M7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4664d57-86d7-484e-9f6d-cdb4dcdab229_1932x744.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>Before and After DI: How You Use the Code</strong></h3><p>The real difference isn&#8217;t just how the service is <em><strong>defined</strong></em>, but how it&#8217;s <em><strong>consumed</strong></em>.</p><p><strong>Before DI, we use direct imports (hidden dependencies):</strong></p><pre><code>// Somewhere in your route handler or controller
import { createUser } from &#8216;./userService&#8217;;

// Just call it. What does it need? Who knows.
// Knex? Email service? Logger? You can&#8217;t tell from here.
const user = await createUser({ email: &#8216;alice@example.com&#8217;, name: &#8216;Alice&#8217; });</code></pre><p>Dependencies are invisible.</p><p>The function looks simple, but it&#8217;s secretly reaching into the module graph for a database client, an email service, and a logger.</p><p>You only discover this when something breaks or when you try to test it.</p><p><strong>After DI, we use Factory + DI (explicit dependencies):</strong></p><pre><code>// In your composition root or setup code
import { createUserService } from &#8216;./userService&#8217;;
import { createUserRepo } from &#8216;./repos/userRepo&#8217;;
import { createEmailService } from &#8216;./infra/email&#8217;;
import { createLogger } from &#8216;./infra/logger&#8217;;

// Dependencies are explicit at creation time
const userService = createUserService(
  createUserRepo(knex),
  createEmailService({ apiKey: process.env.SENDGRID_KEY! }),
  createLogger({ level: &#8216;info&#8217; })
);

// Now use it &#8212; the service is fully configured
const user = await userService.createUser({ email: &#8216;alice@example.com&#8217;, name: &#8216;Alice&#8217; });</code></pre><p>Yes, the setup is more verbose. But now you can see every dependency. The function signature tells the truth.</p><p>When you read the composition root, you know exactly what each service needs, no grepping through imports, no surprises.</p><div><hr></div><h2><strong>Step 2: The Composition Root</strong> </h2><p>If every service takes its dependencies as arguments, where do you actually wire everything together?</p><p>At the <strong>composition root</strong>, the entry point of your application. This is the one place that knows about all the concrete implementations.</p><pre><code>// composition-root.ts
import Knex from &#8216;knex&#8217;;
import { createKnexDatabase } from &#8216;./infra/knexDatabase&#8217;;
import { createUserService } from &#8216;./services/userService&#8217;;
import { createOrderService } from &#8216;./services/orderService&#8217;;
import { createEmailService } from &#8216;./infra/email&#8217;;
import { createLogger } from &#8216;./infra/logger&#8217;;

export function createApp() {
  // Infrastructure
  const knex = Knex({
    client: &#8216;pg&#8217;,
    connection: process.env.DATABASE_URL,
  });
  const db = createKnexDatabase(knex);
  const email = createEmailService({ apiKey: process.env.SENDGRID_KEY! });
  const logger = createLogger({ level: &#8216;info&#8217; });

  // Repositories
  const userRepo = createUserRepo(db);
  const orderRepo = createOrderRepo(db);

  // Services
  const userService = createUserService(userRepo, email, logger);
  const orderService = createOrderService(orderRepo, userService, logger);

  return { userService, orderService, knex };
}</code></pre><pre><code>// server.ts
import express from &#8216;express&#8217;;
import { createApp } from &#8216;./composition-root&#8217;;

const app = express();
const { userService, orderService } = createApp();

app.post(&#8217;/users&#8217;, async (req, res) =&gt; {
  const user = await userService.createUser(req.body);
  res.status(201).json(user);
});</code></pre><p>Everything flows downward from one place. No global singletons. No magical auto-wiring. Just functions calling functions.</p><div><hr></div><h2><strong>When to Reach for a Container?</strong></h2><p>Manual DI works beautifully for small-to-medium apps.</p><p>But when you have 20-30+ services with complex dependency graphs, the composition root becomes hard to read and follow.</p><p>I&#8217;ve personally used <a href="https://github.com/microsoft/tsyringe">tsyringe</a>. It&#8217;s a lightweight container, easy to use and configure.</p><p><a href="https://github.com/microsoft/tsyringe">tsyringe</a> uses decorators and <code>reflect-metadata</code> to inspect constructor parameters and auto-wire dependencies.</p><p>It supports singleton, transient, and scoped lifecycles, with strong TypeScript support.</p><p>To be honest, I didn&#8217;t have any trouble with it.</p><p>Here is a simple example:</p><pre><code>import &#8216;reflect-metadata&#8217;;
import { container, injectable, inject, singleton } from &#8216;tsyringe&#8217;;
import Knex from &#8216;knex&#8217;;

@singleton()
class KnexDatabase implements Database {
  private knex = Knex({ client: &#8216;pg&#8217;, connection: process.env.DATABASE_URL });

  users = {
    create: async (data: CreateUserInput) =&gt; {
      const [user] = await this.knex(&#8217;users&#8217;).insert(data).returning(&#8217;*&#8217;);
      return user;
    },
    findById: async (id: string) =&gt; {
      return this.knex(&#8217;users&#8217;).where({ id }).first() ?? null;
    },
  };
}

container.register(&#8217;Database&#8217;, { useClass: KnexDatabase });

@injectable()
class UserService {
  constructor(@inject(&#8217;Database&#8217;) private db: Database) {}

  async createUser(data: CreateUserInput) {
    return this.db.users.create(data);
  }
}

// Resolve with all dependencies auto-wired
const userService = container.resolve(UserService);</code></pre><p>If you&#8217;re not sure whether you need a container, start simple without an additional framework.</p><p>You can easily add it later if needed.</p><div><hr></div><h2><strong>The Testing Payoff</strong></h2><p>Here&#8217;s why all this matters. Let&#8217;s compare full test files side by side.</p><h3><strong>Before: Testing with Module Mocking</strong></h3><pre><code>import { describe, it, expect, vi, beforeEach } from &#8216;vitest&#8217;;

// Mock every dependency by file path &#8212; get any path wrong and it silently breaks
vi.mock(&#8217;../lib/database&#8217;, () =&gt; ({
  knex: vi.fn().mockReturnValue({
    insert: vi.fn().mockReturnValue({
      returning: vi.fn().mockResolvedValue([{ id: &#8216;1&#8217;, email: &#8216;test@example.com&#8217; }]),
    }),
  }),
}));

vi.mock(&#8217;../lib/email&#8217;, () =&gt; ({
  sendEmail: vi.fn(),
}));

vi.mock(&#8217;../lib/logger&#8217;, () =&gt; ({
  logger: {
    info: vi.fn(),
  },
}));

// Now import the function AFTER the mocks (order matters!)
import { createUser } from &#8216;./userService&#8217;;
import { knex } from &#8216;../lib/database&#8217;;
import { sendEmail } from &#8216;../lib/email&#8217;;

describe(&#8217;createUser&#8217;, () =&gt; {
  beforeEach(() =&gt; {
    vi.clearAllMocks();
  });

  it(&#8217;creates a user and sends a welcome email&#8217;, async () =&gt; {
    const user = await createUser({ email: &#8216;test@example.com&#8217;, name: &#8216;Test&#8217; });

    expect(user.id).toBe(&#8217;1&#8217;);
    expect(sendEmail).toHaveBeenCalledWith(&#8217;test@example.com&#8217;, &#8216;Welcome!&#8217;);
  });
});</code></pre><p>Problems everywhere:</p><ul><li><p><strong>Path-coupled</strong>: rename <code>../lib/database</code> to <code>../db/database</code> and the mock breaks silently &#8212; the test passes but uses the real module</p></li><li><p><strong>Import order matters</strong>: <code>vi.mock</code> calls are hoisted, but if you get it wrong, debugging is miserable</p></li><li><p><strong>Type-unsafe</strong>: you&#8217;re casting to <code>any</code> because the mock system doesn&#8217;t know your interfaces</p></li><li><p><strong>Framework-locked</strong>: switch from Vitest to Node&#8217;s built-in test runner? Rewrite every mock</p></li></ul><h3><strong>After: Testing with DI</strong></h3><pre><code>import { describe, it, expect } from &#8216;vitest&#8217;;
import { createUserService } from &#8216;./userService&#8217;;

describe(&#8217;createUser&#8217;, () =&gt; {
  it(&#8217;creates a user and sends a welcome email&#8217;, async () =&gt; {
    // Plain objects that satisfy the interface &#8212; no mock framework needed
    const fakeRepo = {
      create: async (data: any) =&gt; ({ id: &#8216;1&#8217;, email: data.email }),
    };
    const fakeEmail = {
      send: async () =&gt; {},
    };
    const fakeLogger = {
      info: () =&gt; {},
    };

    // Track calls manually if needed (or use vi.fn() &#8212; your choice, not a requirement)
    const emailCalls: any[] = [];
    fakeEmail.send = async (to: string, subject: string) =&gt; {
      emailCalls.push({ to, subject });
    };

    const service = createUserService(fakeRepo, fakeEmail, fakeLogger);
    const user = await service.createUser({ email: &#8216;test@example.com&#8217;, name: &#8216;Test&#8217; });

    expect(user.id).toBe(&#8217;1&#8217;);
    expect(emailCalls).toEqual([{ to: &#8216;test@example.com&#8217;, subject: &#8216;Welcome!&#8217; }]);
  });

  it(&#8217;logs user creation&#8217;, async () =&gt; {
    const logs: string[] = [];
    const service = createUserService(
      { create: async (data: any) =&gt; ({ id: &#8216;42&#8217;, email: data.email }) },
      { send: async () =&gt; {} },
      { info: (msg: string) =&gt; logs.push(msg) }
    );

    await service.createUser({ email: &#8216;test@example.com&#8217;, name: &#8216;Test&#8217; });

    expect(logs).toEqual([&#8217;User created: 42&#8217;]);
  });
});</code></pre><p>The difference:</p><ul><li><p><strong>No mocking framework required</strong>: plain objects that match the interface</p></li><li><p><strong>Type-safe</strong>: TypeScript checks your fakes against the real interfaces</p></li><li><p><strong>No import order tricks</strong>: just functions and objects</p></li><li><p><strong>Portable</strong>: works with Vitest, Jest, Node&#8217;s test runner, or even a plain script</p></li><li><p><strong>Each test is self-contained</strong>: no shared mutable mock state leaks between tests</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vQvD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vQvD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 424w, https://substackcdn.com/image/fetch/$s_!vQvD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 848w, https://substackcdn.com/image/fetch/$s_!vQvD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 1272w, https://substackcdn.com/image/fetch/$s_!vQvD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vQvD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png" width="1456" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:859,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:251097,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/191737097?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vQvD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 424w, https://substackcdn.com/image/fetch/$s_!vQvD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 848w, https://substackcdn.com/image/fetch/$s_!vQvD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 1272w, https://substackcdn.com/image/fetch/$s_!vQvD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75616c64-f8fd-43a4-b22f-6e5bb4e4c8e3_1658x978.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2><strong>&#128204; Key Takeaways</strong></h2><ol><li><p><strong>Dependency Injection isn&#8217;t a framework feature</strong> &#8212; it&#8217;s passing arguments to functions. You already know how to do it.</p></li><li><p><strong>Module mocking is a smell.</strong> If you need <code>vi.mock()</code> to test something, remember that something has hidden dependencies.</p></li><li><p><strong>Start with manual DI.</strong> Factory functions + a composition root covers 90% of Node.js apps.</p></li><li><p><strong>Graduate to a container (tsyringe) when your dependency graph gets complex.</strong> Not because it&#8217;s &#8220;proper&#8221;, but because it saves maintenance.</p></li><li><p><strong>The real value is testability.</strong> DI makes unit testing trivial, integration testing focused, and your architecture honest about its dependencies.</p></li></ol><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, and Software Architecture delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="pullquote"><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cmMn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" width="248" height="207.7" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:800,&quot;resizeWidth&quot;:248,&quot;bytes&quot;:257716,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ebf3ac-ad2f-415d-9e32-111e959c8e4e_800x800.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Follow me on <a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong> | <strong><a href="https://x.com/intent/follow?screen_name=petarivanovv9">Twitter(X)</a></strong> |<strong> <a href="https://www.threads.net/@petarivanovv9">Threads</a></strong></p></div><p>Thank you for supporting this newsletter.</p><p>Consider sharing this post with your friends and get rewards.</p><p>You are the best! &#128591;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EvJY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg" width="800" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83253,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/p/dependency-injection-in-nodejs-and-typescript-dependency-inversion-part-no-body-teaches-you?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://thetshaped.dev/p/dependency-injection-in-nodejs-and-typescript-dependency-inversion-part-no-body-teaches-you?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div class="pullquote"><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UzWz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UzWz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 424w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 848w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif" width="48" height="57.6" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39609b45-f68c-4557-8772-8e2a45182842_500x600.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:500,&quot;resizeWidth&quot;:48,&quot;bytes&quot;:7028,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188785536?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UzWz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 424w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 848w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p style="text-align: center;"><em><strong>Press the Like button if you found this post helpful</strong></em></p></div>]]></content:encoded></item><item><title><![CDATA[Screaming Architecture & Colocation: Let Your Project Structure Tell the Story]]></title><description><![CDATA[Learn why you should organize your code by what your app actually does, not by technical roles. (5 min)]]></description><link>https://thetshaped.dev/p/screaming-architecture-and-colocation-nodejs-typescript-react</link><guid isPermaLink="false">https://thetshaped.dev/p/screaming-architecture-and-colocation-nodejs-typescript-react</guid><pubDate>Sat, 14 Mar 2026 07:19:34 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/01fd2aa6-0feb-4fb1-ac03-572fd4a7d02a_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This post outlines the importance of applying Screaming Architecture and Collocation in both your back-end and front-end projects, and how this helps you and your teammates.</em></p><ul><li><p><em><a href="https://open.substack.com/pub/petarivanovv9/p/screaming-architecture-and-colocation-nodejs-typescript-react?utm_campaign=post-expanded-share&amp;utm_medium=web">Share this post</a> &amp; I&#8217;ll send you some rewards for the referrals.</em></p></li></ul><div><hr></div><p>Open most Node.js projects, and you see this:</p><pre><code><code>src/
&#9500;&#9472;&#9472; controllers/
&#9500;&#9472;&#9472; services/
&#9500;&#9472;&#9472; models/
&#9500;&#9472;&#9472; middleware/
&#9500;&#9472;&#9472; utils/
&#9492;&#9472;&#9472; routes/</code></code></pre><p>What does this app do?</p><p>You see that it&#8217;s an Express app. But that&#8217;s all the structure tells you.</p><p>Is it an e-commerce platform? A healthcare system? A social network?</p><p>You&#8217;d have to open files and read code to find out.</p><p>That&#8217;s the problem.</p><div><hr></div><h2>What Is Screaming Architecture?</h2><p>Uncle Bob coined the term:</p><blockquote><p><strong>Your project structure should </strong><em><strong>scream</strong></em><strong> what the application does, not what framework it uses.</strong></p></blockquote><p>For example, a healthcare app should look like this:</p><pre><code><code>src/
&#9500;&#9472;&#9472; patients/
&#9500;&#9472;&#9472; appointments/
&#9500;&#9472;&#9472; prescriptions/
&#9500;&#9472;&#9472; billing/
&#9492;&#9472;&#9472; shared/</code></code></pre><p>You open the folder and immediately know: this is a healthcare system.</p><p>The domain is front and center.</p><p>Express, REST, GraphQL, Prisma, React, those are implementation details, tucked inside each feature.</p><p>And this is not just about aesthetics.</p><p>When <strong>folders map to business capabilities</strong>, you get:</p><ul><li><p><strong>Discoverability</strong>: New developers find code faster.</p></li><li><p><strong>Ownership</strong>: Teams own features, not layers.</p></li><li><p><strong>Change isolation</strong>: Modifying &#8220;appointments&#8221; doesn&#8217;t require touching 5 different layer folders.</p></li><li><p><strong>Deletion</strong>: You can remove an entire feature by deleting one folder.</p></li><li><p><strong>Low/High Coupling</strong>: Low coupling between features and High coupling for a single feature.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ow4z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ow4z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ow4z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ow4z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ow4z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ow4z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg" width="1718" height="948" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:948,&quot;width&quot;:1718,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157616,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/190265218?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db9be8a-4158-4185-be3c-a33de4f2e135_2000x1490.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ow4z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ow4z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ow4z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ow4z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15027ec9-b1f7-4d53-85a0-f47ea6052a93_1718x948.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Or we could also look at it in another way to see more clearly how a single feature maps across different technical layers:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CysD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CysD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 424w, https://substackcdn.com/image/fetch/$s_!CysD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 848w, https://substackcdn.com/image/fetch/$s_!CysD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 1272w, https://substackcdn.com/image/fetch/$s_!CysD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CysD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png" width="962" height="504" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:504,&quot;width&quot;:962,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:117607,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/190265218?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CysD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 424w, https://substackcdn.com/image/fetch/$s_!CysD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 848w, https://substackcdn.com/image/fetch/$s_!CysD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 1272w, https://substackcdn.com/image/fetch/$s_!CysD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b20ab5a-60aa-4213-a013-956fd44694ca_962x504.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>The Colocation Principle</h2><p>In the React world, we must strive to:</p><blockquote><p><strong>Keep things as close as possible to where they're used.</strong></p></blockquote><p>Consider the following hierarchy:</p><ol><li><p>If only one component uses it &#8594; put it in that component&#8217;s file</p></li><li><p>If only components in one folder use it &#8594; put it in that folder</p></li><li><p>If multiple folders use it &#8594; move it up to the nearest shared parent</p></li><li><p>If the whole app uses it &#8594; put it in <code>shared/</code> or <code>lib/</code></p></li></ol><p>This is the same idea as screaming architecture, applied at a granular level.</p><p>Don't prematurely extract.</p><p>Don't create <code>utils/</code> and <code>helpers/</code> folders that become junk drawers.</p><div><hr></div><h2>Combining Both: Feature-First Structure</h2><p>Here&#8217;s what a feature-first Node.js project looks like when you combine screaming architecture with colocation:</p><pre><code><code>src/
&#9500;&#9472;&#9472; patients/
&#9474;   &#9500;&#9472;&#9472; patient.controller.ts
&#9474;   &#9500;&#9472;&#9472; patient.service.ts
&#9474;   &#9500;&#9472;&#9472; patient.repository.ts
&#9474;   &#9500;&#9472;&#9472; patient.types.ts
&#9474;   &#9500;&#9472;&#9472; patient.validation.ts
&#9474;   &#9500;&#9472;&#9472; patient.routes.ts
&#9474;   &#9492;&#9472;&#9472; __tests__/
&#9474;       &#9500;&#9472;&#9472; patient.service.test.ts
&#9474;       &#9492;&#9472;&#9472; patient.controller.test.ts
&#9500;&#9472;&#9472; appointments/
&#9474;   &#9500;&#9472;&#9472; appointment.controller.ts
&#9474;   &#9500;&#9472;&#9472; appointment.service.ts
&#9474;   &#9500;&#9472;&#9472; appointment.repository.ts
&#9474;   &#9500;&#9472;&#9472; appointment.types.ts
&#9474;   &#9500;&#9472;&#9472; appointment.validation.ts
&#9474;   &#9500;&#9472;&#9472; appointment.routes.ts
&#9474;   &#9492;&#9472;&#9472; __tests__/
&#9474;       &#9492;&#9472;&#9472; appointment.service.test.ts
&#9500;&#9472;&#9472; shared/
&#9474;   &#9500;&#9472;&#9472; middleware/
&#9474;   &#9474;   &#9500;&#9472;&#9472; auth.middleware.ts
&#9474;   &#9474;   &#9492;&#9472;&#9472; error-handler.ts
&#9474;   &#9500;&#9472;&#9472; database/
&#9474;   &#9474;   &#9492;&#9472;&#9472; prisma.ts
&#9474;   &#9492;&#9472;&#9472; types/
&#9474;       &#9492;&#9472;&#9472; common.ts
&#9500;&#9472;&#9472; app.ts
&#9492;&#9472;&#9472; server.ts
</code></code></pre><p>Every feature is self-contained.</p><p>Tests live next to the code they test.</p><p>Shared infrastructure sits in <code>shared/</code>, but only things that are genuinely shared across features.</p><div><hr></div><h2><strong>The Same Principle in React</strong></h2><pre><code><code>src/
&#9500;&#9472;&#9472; features/
&#9474;   &#9500;&#9472;&#9472; patients/
&#9474;   &#9474;   &#9500;&#9472;&#9472; PatientList.tsx
&#9474;   &#9474;   &#9500;&#9472;&#9472; PatientDetail.tsx
&#9474;   &#9474;   &#9500;&#9472;&#9472; usePatients.ts
&#9474;   &#9474;   &#9500;&#9472;&#9472; patient.types.ts
&#9474;   &#9474;   &#9492;&#9472;&#9472; patient.api.ts
&#9474;   &#9500;&#9472;&#9472; appointments/
&#9474;   &#9474;   &#9500;&#9472;&#9472; AppointmentCalendar.tsx
&#9474;   &#9474;   &#9500;&#9472;&#9472; BookAppointment.tsx
&#9474;   &#9474;   &#9500;&#9472;&#9472; useAppointments.ts
&#9474;   &#9474;   &#9492;&#9472;&#9472; appointment.api.ts
&#9500;&#9472;&#9472; shared/
&#9474;   &#9500;&#9472;&#9472; components/
&#9474;   &#9474;   &#9500;&#9472;&#9472; Button.tsx
&#9474;   &#9474;   &#9492;&#9472;&#9472; Modal.tsx
&#9474;   &#9500;&#9472;&#9472; hooks/
&#9474;   &#9474;   &#9492;&#9472;&#9472; useAuth.ts
&#9474;   &#9492;&#9472;&#9472; lib/
&#9474;       &#9492;&#9472;&#9472; api-client.ts
&#9500;&#9472;&#9472; App.tsx
&#9492;&#9472;&#9472; main.tsx
</code></code></pre><p>Same idea.</p><p>Features own their components, hooks, types, and API calls.</p><p><code>shared/</code> contains only genuinely reusable pieces.</p><div><hr></div><h2>When Layers Still Make Sense</h2><p>Layers aren&#8217;t always wrong. They work when:</p><ul><li><p><strong>Your app is small</strong> (&lt; 10 files). Feature folders are overhead for a simple CRUD API.</p></li><li><p><strong>You&#8217;re building a library</strong>. Internal structure matters less than the public API.</p></li><li><p><strong>Your team is one person</strong>. You already know where everything is.</p></li></ul><p>The pragmatic hybrid: <strong>features at the top level, layers within each feature.</strong></p><p>Each feature has its own controller, service, repository, but they&#8217;re colocated, not scattered.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, Software Architecture, and Career Development delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Enforcing Boundaries</h2><p>Structure without enforcement is just a suggestion.</p><p>Here's how to make it stick:</p><h3>ESLint (with <code>eslint-plugin-boundaries</code>)</h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;javascript&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-javascript">// .eslintrc.js
module.exports = {
  plugins: ['boundaries'],
  settings: {
    'boundaries/elements': [
      { type: 'patients', pattern: 'src/patients/*' },
      { type: 'appointments', pattern: 'src/appointments/*' },
      { type: 'shared', pattern: 'src/shared/*' },
    ],
  },
  rules: {
    'boundaries/element-types': [2, {
      default: 'disallow',
      rules: [
        { from: 'patients', allow: ['shared'] },
        { from: 'appointments', allow: ['shared', 'patients'] },
      ],
    }],
  },
};</code></pre></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mR-g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mR-g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 424w, https://substackcdn.com/image/fetch/$s_!mR-g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 848w, https://substackcdn.com/image/fetch/$s_!mR-g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!mR-g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mR-g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png" width="1456" height="1106" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1106,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:329283,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/190265218?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mR-g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 424w, https://substackcdn.com/image/fetch/$s_!mR-g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 848w, https://substackcdn.com/image/fetch/$s_!mR-g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 1272w, https://substackcdn.com/image/fetch/$s_!mR-g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bee52f0-3652-488c-aea3-54179d52e97b_1986x1508.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>TypeScript Project References</h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;typescript&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-typescript">// src/shared/tsconfig.json &#8212; every referenced project needs composite: true
{
  "compilerOptions": {
    "composite": true,
    "rootDir": ".",
    "outDir": "../../dist/shared"
  }
}</code></pre></div><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;typescript&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-typescript">// src/patients/tsconfig.json
{
  "compilerOptions": {
    "composite": true,
    "rootDir": ".",
    "outDir": "../../dist/patients"
  },
  "references": [
    { "path": "../shared" }
  ]
}</code></pre></div><p>Each feature is a TypeScript project.</p><p>It can only reference what's listed in <code>references</code>.</p><p>The compiler enforces boundaries at build time.</p><div><hr></div><h2>&#128204; Key Takeaways</h2><ol><li><p><strong>Your folder structure is documentation.</strong> It should tell a new developer what the app does in 5 seconds.</p></li><li><p><strong>Organize by feature, not by layer.</strong> Controllers, services, and models for the same feature belong together.</p></li><li><p><strong>Colocate aggressively.</strong> Tests, types, and utilities live next to the code that uses them. Move things to <code>shared/</code> only when two or more features need them.</p></li><li><p><strong>Migrate incrementally.</strong> One feature at a time, one PR at a time. No big-bang restructures.</p></li><li><p><strong>Enforce with tooling.</strong> ESLint boundaries, TypeScript project references, or Nx module boundaries. Structure without enforcement decays.</p></li></ol><div class="pullquote"><p><strong>The best architecture is invisible. When a developer opens your project and immediately knows where to find what they need, without reading a README or asking a teammate, your structure is doing its job.</strong></p></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, and Software Architecture delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="pullquote"><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cmMn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" width="248" height="207.7" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:800,&quot;resizeWidth&quot;:248,&quot;bytes&quot;:257716,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ebf3ac-ad2f-415d-9e32-111e959c8e4e_800x800.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Follow me on <a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong> | <strong><a href="https://x.com/intent/follow?screen_name=petarivanovv9">Twitter(X)</a></strong> |<strong> <a href="https://www.threads.net/@petarivanovv9">Threads</a></strong></p></div><p>Thank you for supporting this newsletter.</p><p>Consider sharing this post with your friends and get rewards.</p><p>You are the best! &#128591;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EvJY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg" width="800" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83253,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/p/screaming-architecture-and-colocation-nodejs-typescript-react?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://thetshaped.dev/p/screaming-architecture-and-colocation-nodejs-typescript-react?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div class="pullquote"><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UzWz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UzWz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 424w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 848w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif" width="48" height="57.6" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39609b45-f68c-4557-8772-8e2a45182842_500x600.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:500,&quot;resizeWidth&quot;:48,&quot;bytes&quot;:7028,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188785536?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!UzWz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 424w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 848w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p style="text-align: center;"><em><strong>Press the Like button if you found this post helpful</strong></em></p></div>]]></content:encoded></item><item><title><![CDATA[4 Disciplines That Separate Effective Engineers From Busy Ones]]></title><description><![CDATA[Learn about the daily habits that help engineers be more effective. (7 min)]]></description><link>https://thetshaped.dev/p/four-disciplines-that-separate-effective-software-engineers-from-busy-engineers</link><guid isPermaLink="false">https://thetshaped.dev/p/four-disciplines-that-separate-effective-software-engineers-from-busy-engineers</guid><pubDate>Tue, 24 Feb 2026 11:19:19 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7db15d0a-e497-4d86-bc0b-872f4b740762_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This post outlines my personal experience working with numerous engineers across various companies and distilling what habits an effective engineer has.</em></p><p><em>Those engineers ship less, talk more, think further ahead, and treat AI like a power tool, not a replacement for judgment.</em></p><ul><li><p><em><a href="https://thetshaped.dev/p/four-disciplines-that-separate-effective-software-engineers-from-busy-engineers">Share this post</a> &amp; I&#8217;ll send you some rewards for the referrals.</em></p></li></ul><div><hr></div><p>Imagine spending six weeks building a sleek, real-time notification system that nobody actually requested.</p><p>You nailed down the &#8220;right architecture&#8221;, covered the codebase with tests, and perfected the documentation.</p><p>Then comes the week before launch. Your PM demos the masterpiece, and suddenly part of your customers refuse to use it while the other asks why a certain bug still exists.</p><p>Stories like this project remind me of the difference between being <em>efficient</em> and being <em>effective</em>.</p><blockquote><p><strong>Efficient engineers do things right.</strong></p><p><strong>Effective engineers do the right things.</strong></p></blockquote><p>After 8+ years of shipping software, hiring engineers, and watching teams succeed and fail, I&#8217;ve distilled what makes engineers genuinely effective into four disciplines.</p><p>And none of them is about writing clever code.</p><div><hr></div><h2><strong><a href="https://brightdata.com/ai/mcp-server?utm_source=brand&amp;utm_campaign=brnd-mkt_newsletter_petar">BrightData: Connect Your AI To The Internet&#8217;s Data - Sponsor</a></strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://brightdata.com/ai/mcp-server?utm_source=brand&amp;utm_campaign=brnd-mkt_newsletter_petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GKHx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!GKHx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!GKHx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!GKHx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GKHx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:266997,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://brightdata.com/ai/mcp-server?utm_source=brand&amp;utm_campaign=brnd-mkt_newsletter_petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/185405137?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!GKHx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!GKHx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!GKHx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!GKHx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0755e22-597b-425f-a9b9-131d60c57a5d_1200x630.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://brightdata.com/ai/mcp-server?utm_source=brand&amp;utm_campaign=brnd-mkt_newsletter_petar">Bright Data</a>&#8217;s Web MCP solves web access for LLMs and AI agents, allowing them to effectively search, extract, and navigate the web without getting blocked. It helps to:</p><ul><li><p>Search the web in real-time</p></li><li><p>Extract data from any website</p></li><li><p>Navigate and interact with pages</p></li><li><p>Bypass blocks and restrictions</p></li></ul><p>It comes with a generous free tier - 5,000 MCP requests every month - for free!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://brightdata.com/ai/mcp-server?utm_source=brand&amp;utm_campaign=brnd-mkt_newsletter_petar&quot;,&quot;text&quot;:&quot;Try For Free&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://brightdata.com/ai/mcp-server?utm_source=brand&amp;utm_campaign=brnd-mkt_newsletter_petar"><span>Try For Free</span></a></p><div><hr></div><h1>1. Solve the Right Problems; Not Just Any Problem</h1><p><em>Traits: Care about the user. Understand team strategy. Prioritize ruthlessly.</em></p><p>The most expensive line of code is the one that solves the wrong problem.</p><p>I&#8217;ve seen teams spending time into plubming, like managing a custom-built deployment pipeline, instead of leveraging  $50/month SaaS.</p><p>Here is the uncomfortable part: most engineers aren&#8217;t trained to say no.</p><p>We&#8217;re rewarded for building. Promotions come from shipping. Saying &#8220;we shouldn&#8217;t build this&#8221; doesn&#8217;t show up in a pull request.</p><p>But caring about users, I mean actually caring, not only claiming that on a performance review, means understanding their real problems deeply enough to know which solutions are worth pursuing and which are engineering vanity projects.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Adpn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Adpn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 424w, https://substackcdn.com/image/fetch/$s_!Adpn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 848w, https://substackcdn.com/image/fetch/$s_!Adpn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 1272w, https://substackcdn.com/image/fetch/$s_!Adpn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Adpn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png" width="480" height="273.6448598130841" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:366,&quot;width&quot;:642,&quot;resizeWidth&quot;:480,&quot;bytes&quot;:327310,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188785536?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Adpn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 424w, https://substackcdn.com/image/fetch/$s_!Adpn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 848w, https://substackcdn.com/image/fetch/$s_!Adpn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 1272w, https://substackcdn.com/image/fetch/$s_!Adpn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F586cab84-1626-42f9-87bc-c5a013cae14e_642x366.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And you can&#8217;t make that judgment in a vacuum.</p><p>You need to understand your <strong>team&#8217;s strategy</strong>:</p><ul><li><p>What are we trying to accomplish this quarter?</p></li><li><p>How does my work connect to revenue, retention, or reliability?</p></li></ul><p>Engineers who can answer those questions prioritize themselves.</p><p>Engineers who can&#8217;t are always waiting to be told what to do next.</p><p>So next time, before writing any line of code, force yourself through these three questions:</p><ul><li><p><strong>Who suffers if this doesn&#8217;t ship?</strong> If the answer is &#8220;nobody, really,&#8221; put it in the icebox.</p></li><li><p><strong>What&#8217;s the cheapest version that tests the hypothesis?</strong> A spreadsheet, a Figma prototype, or a hardcoded endpoint can often answer the question a six-week feature build was supposed to answer.</p></li><li><p><strong>What am I not doing by doing this?</strong> Opportunity cost is invisible until you&#8217;ve missed a deadline on the thing that actually mattered.</p></li></ul><p>Of course, we can&#8217;t do some of these things by ourselves. That&#8217;s why we have Product Managers who are the point of contact to the end users and our organization.</p><p><strong>Our job as Effective Engineers is to advocate for users, do extensive user research, and prioritize user needs.</strong></p><div><hr></div><h1>2. Keep It Simple; Leave It Better</h1><p><em>Traits: Simplicity over cleverness. Quality as a discipline. The Boy Scout Rule.</em></p><p>I&#8217;ve reviewed pull requests where the author used three levels of abstraction to avoid repeating four lines of code.</p><p>The DRY principle is good. But taken to its extreme, it produces code that&#8217;s &#8220;elegant&#8221; but unreadable to everyone except the person who wrote it, and often to them too, three months later.</p><p>Simplicity isn&#8217;t the absence of thought. It&#8217;s the result of deep thought.</p><p>It means you&#8217;ve understood the problem well enough to solve it without over-engineering.</p><p>The engineers I respect most write code that a new team member can read on their first day and say, &#8220;Okay, I see what this does&#8221;.</p><p>But simplicity alone isn&#8217;t enough.</p><p>The effective engineers also leave things better than they found them.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L9cW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L9cW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 424w, https://substackcdn.com/image/fetch/$s_!L9cW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 848w, https://substackcdn.com/image/fetch/$s_!L9cW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 1272w, https://substackcdn.com/image/fetch/$s_!L9cW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L9cW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png" width="470" height="174.22413793103448" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:258,&quot;width&quot;:696,&quot;resizeWidth&quot;:470,&quot;bytes&quot;:337172,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188785536?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L9cW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 424w, https://substackcdn.com/image/fetch/$s_!L9cW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 848w, https://substackcdn.com/image/fetch/$s_!L9cW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 1272w, https://substackcdn.com/image/fetch/$s_!L9cW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F595a344b-ac8d-4525-9a87-61bf97c678da_696x258.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Every PR is an opportunity: fix a flaky test, update a stale README, delete dead code, or rename a confusing variable.</p><p>None of these show up in a sprint demo.</p><p>All of them compound into a codebase that&#8217;s a joy to work with versus one that slowly rots.</p><p>So the next time you write and ship code, try to:</p><ul><li><p><strong>Set a complexity budget.</strong> If a solution requires more than one new abstraction, pressure-test whether that abstraction earns its keep. Often it doesn&#8217;t.</p></li><li><p><strong>Timebox polish.</strong> I allocate roughly 10-15% of every feature&#8217;s time for cleanup, not gold-plating, but genuine improvement to the code I touched and the code around it.</p></li><li><p><strong>Measure quality that matters.</strong> Track things like time-to-first-meaningful-PR-review for new hires, or incident rate per deploy. These tell you more about codebase health than test coverage percentages.</p></li></ul><p>You have to be comfortable with invisible contributions.</p><p>The payoff comes in months, not days: fewer incidents, faster onboarding, less time debugging code nobody understands.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, Software Architecture, and Career Development delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h1>3. Earn Trust; Communicate Relentlessly</h1><p><em>Traits: Build trust and social capital. Communicate effectively. Operate with autonomy.</em></p><p>Early in my career, I thought trust was a soft-skills thing, something you got for free by being &#8220;nice&#8221;.</p><p>That&#8217;s not how it works.</p><p>Trust is an engineering asset.</p><p>It&#8217;s the reason one engineer can get a risky refactor approved in a single meeting while another spends two sprints writing a design doc that still gets rejected.</p><p>Think about it mechanically: engineers who&#8217;ve built trust get more autonomy.</p><p>More autonomy means they can take bigger swings.</p><p>Bigger swings, when they land, build <em>more</em> trust. It compounds like interest.</p><p>And the inverse is just as powerful: one blown deadline or one surprise production incident you didn&#8217;t communicate about can set you back months of accumulated credibility.</p><p>Communication is the engine that drives all of this.</p><p>Not &#8220;being good at presentations&#8221;, I mean the boring, daily discipline of keeping people informed. Status updates nobody asked for. A Slack message before you merge something risky. Flagging a blocker on Day 1 instead of Day 5.</p><p>The engineers who do this consistently become the ones everyone wants on their project.</p><p>Here are a few things you could try:</p><ul><li><p><strong>Estimate honestly, then pad 20%.</strong> On one project, I started adding explicit &#8220;risk buffers&#8221; to my estimates, and my on-time delivery rate went from roughly 60% to over 85% in two quarters.</p></li><li><p><strong>Communicate bad news early.</strong> If a project is slipping, saying so on Day 3 builds trust. Saying so on Day 13 destroys it. I&#8217;ve never seen anyone punished for early transparency. I&#8217;ve seen plenty punished for late surprises.</p></li><li><p><strong>Review others&#8217; code generously.</strong> Fast, thoughtful code reviews are one of the highest-leverage trust-building activities in engineering. They signal &#8220;I respect your time and your work&#8221;. They also build social capital, the kind of relationship equity that means people answer your Slack messages in minutes instead of hours.</p></li><li><p><strong>Invest in relationships outside your team.</strong> Grab coffee with the infrastructure team. Understand what the data team is struggling with. Cross-team relationships pay dividends when you need a favor, a quick answer, or buy-in on a proposal.</p></li></ul><p>Building trust slowly means you won't be the hero on Day 1. You might watch a louder, faster colleague get more visibility early on. The patience required is real.</p><p>And there's an uncomfortable truth: trust is context-dependent.</p><p>Switching teams or companies resets the meter. You have to be willing to re-invest every time.</p><div><hr></div><h1>4. Think Long-Term; Adapt Constantly</h1><p><em>Traits: Second-order thinking. Comfort with new challenges. Wielding AI as a force multiplier.</em></p><p>Junior engineers think about whether their code works. Mid-level engineers think about whether their code is maintainable. Senior engineers think about what their code <em>causes</em>, downstream, six months from now, in systems they don't own.</p><p>And here's the thing that's changed in the last two years:</p><blockquote><p>Long-term thinking now includes your relationship with AI tooling.</p></blockquote><p>The engineers who treat GitHub Copilot, Claude, or Cursor as magic black boxes are building on sand.</p><p>The ones who understand what these tools are good at (boilerplate, scaffolding, routine refactors), what they're bad at (nuanced architecture decisions, security edge cases, understanding your specific business context), and how to verify their output, are the engineers who are genuinely 2-3x more productive.</p><p>But only because they bring the judgment the AI lacks.</p><blockquote><p><strong>Treat AI-generated code like a pull request from a confident but context-blind junior.</strong></p><p>Review every line. Question every assumption. The speed is real, but so are the subtle bugs.</p></blockquote><p>Being comfortable with new challenges has always mattered. Now it's existential.</p><p>The landscape shifts every six months.</p><p>The engineers who thrive aren't the ones who memorize every new framework.</p><p>They're the ones who've <strong>built strong enough fundamentals that they can pick up any tool quickly and evaluate it critically</strong>.</p><p>Second-order thinking is slow.</p><p>Learning new tools takes time away from shipping.</p><p>There's a real risk of analysis paralysis, and an equally real risk of chasing every new AI tool instead of mastering the one you have.</p><p>The discipline is knowing when the blast radius is large enough to warrant the extra thought, and when to just ship.</p><div><hr></div><p>You can learn a new framework in a weekend.</p><p>You can learn a new AI tool in an afternoon.</p><p>These four disciplines take years. Start now.</p><p>See you next time! &#128588;</p><p><em>PS:</em> My friend Marko Denic has recently launched his new FREE e-book: <a href="https://dailytips.dev/ebook/">The Technical Decision Framework</a>. It&#8217;s about a framework for the choices that shape your codebase.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, Software Architecture, and Career Development delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="pullquote"><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cmMn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" width="248" height="207.7" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:800,&quot;resizeWidth&quot;:248,&quot;bytes&quot;:257716,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ebf3ac-ad2f-415d-9e32-111e959c8e4e_800x800.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Follow me on <a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong> | <strong><a href="https://x.com/intent/follow?screen_name=petarivanovv9">Twitter(X)</a></strong> |<strong> <a href="https://www.threads.net/@petarivanovv9">Threads</a></strong></p></div><p>Thank you for supporting this newsletter.</p><p>Consider sharing this post with your friends and get rewards.</p><p>You are the best! &#128591;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EvJY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg" width="800" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83253,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/p/four-disciplines-that-separate-effective-software-engineers-from-busy-engineers?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://thetshaped.dev/p/four-disciplines-that-separate-effective-software-engineers-from-busy-engineers?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div class="pullquote"><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UzWz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UzWz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 424w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 848w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif" width="48" height="57.6" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39609b45-f68c-4557-8772-8e2a45182842_500x600.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:500,&quot;resizeWidth&quot;:48,&quot;bytes&quot;:7028,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188785536?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UzWz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 424w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 848w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!UzWz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39609b45-f68c-4557-8772-8e2a45182842_500x600.gif 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Press the Like button if you found this post helpful</strong></p></div>]]></content:encoded></item><item><title><![CDATA[Database Design Doesn't Start With Table. It Starts With Consequences]]></title><description><![CDATA[Here's what most backend engineers get wrong about schema design and how to fix it before you hit production. (6 min)]]></description><link>https://thetshaped.dev/p/database-design-foundations-backend-engineers-mistakes-and-lessons</link><guid isPermaLink="false">https://thetshaped.dev/p/database-design-foundations-backend-engineers-mistakes-and-lessons</guid><pubDate>Tue, 17 Feb 2026 05:19:18 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b499f478-3f17-4fa8-8307-6a1eb1a2600c_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This post is an introduction to database design, a foundational concept for backend engineers, highlighting its importance and how to get it right before it&#8217;s too late.</em></p><ul><li><p><em><a href="https://open.substack.com/pub/petarivanovv9/p/database-design-foundations-backend-engineers-mistakes-and-lessons?r=643nm&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=true">Share this post</a> &amp; I&#8217;ll send you some rewards for the referrals.</em></p></li></ul><div><hr></div><p>Imagine a team launches a new product. Traffic grows. Everything&#8217;s fine. </p><p>Then one day, a query takes 8 seconds instead of 80ms. Engineers start adding indexes. Caching layers. Read replicas.</p><p>None of it helps enough.<br><br>The problem wasn't performance. It was bad database design. And by the time they realized it, they had 200 million rows in production and a Slack channel dedicated to database incidents.</p><blockquote><p>Database decisions are long-term bets. </p><p>Get them wrong early, and you'll spend years firefighting.</p><p>Get them right, and your system scales quietly while you build features.</p></blockquote><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, and Software Architecture delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Your Schema Will Outlive Your Code. Plan Accordingly.</h2><p>A careless column type. A missing foreign key constraint. An unnecessary denormalization because &#8220;it might be faster&#8221;.<br><br>These choices feel small when you're building v1. But databases are permanent in ways code isn't.</p><p>You can refactor a service in a weekend. </p><p>A schema migration on a table with 500 million rows in PostgreSQL?</p><p>That's a multi-month project involving table locks, replica lag monitoring, and very careful coordination with the ops team, who definitely don't want to hear from you at 2 AM.</p><p>The teams that win long-term <strong>treat table design with the same respect they give code architecture</strong>. Maybe more, because you can't just roll back a schema change when 50 million user records depend on it.</p><div><hr></div><h2>Start With Reality, Not With Tables.</h2><p>Most engineers rush straight to <code>CREATE TABLE</code> before understanding what they're actually modeling.<br><br>Don't do this.<br><br><strong>Spend real time mapping the business domain</strong>.</p><p>What entities exist in the real world? What relationships matter to the business? What constraints does reality enforce that your database should mirror?</p><p>If you&#8217;re building a job board, understand that a job posting isn&#8217;t just a row. It has a lifecycle: draft, published, filled, and expired. It belongs to a company. It attracts applications. Each application connects a candidate to a posting.<br><br>The <strong>database should enforce what the domain requires</strong>.</p><p>If your schema allows states that can't exist in reality, eventually someone will put your data into one of those states.</p><div><hr></div><h2>Normalization Is Your Friend (Until It Isn&#8217;t)</h2><p>Normalization means organizing data to eliminate redundancy and dependency issues.</p><p>Third normal form (3NF) is the target - every column depends on the primary key, the whole key, and nothing but the key.</p><p>In practice, this means that a user's data is in one table, addresses in another, and orders in a third. Then, we join them when needed.</p><p>This prevents update anomalies. We change a user&#8217;s email once, not in seventeen places. We can also safely delete an order without losing customer data.</p><p>But <strong>over-normalization can destroy read performance</strong>.</p><p>If your application shows &#8220;user profile with last 10 orders&#8221; on every page load, and that requires five joins across normalized tables, you&#8217;re paying a cost.</p><p>A good rule of thumb is:</p><blockquote><p>Let query patterns guide your final design.</p><p>Start normalized.</p><p>Denormalize deliberately when you have real performance data.</p></blockquote><p>To mitigate the above-mentioned problem, we might want to add a materialized view that flattens this query and then refresh it on writing.</p><p>Or we can do something else, depending on the business case and needs.</p><p><strong>Denormalization is a tool. Use it when the tradeoff is clear.</strong></p><div><hr></div><h2>Indexes: The Contract You Make With Future You</h2><p>An index is a data structure that makes lookups fast by avoiding full table scans.</p><p>Without an index on <code>users.email</code>, a query like <code>WHERE email = 'user@example.com'</code> checks every row. With an index, it jumps directly to the match.</p><p>But indexes aren&#8217;t free.</p><p>Every index slows down writes. The database must update the index on every INSERT, UPDATE, or DELETE. Indexes consume disk space. And poorly chosen indexes bloat over time, requiring maintenance.</p><p><strong>The strategy I follow:</strong></p><ul><li><p>Index foreign keys and columns used in WHERE, JOIN, and ORDER BY clauses</p></li><li><p>Avoid indexing columns with low cardinality (e.g., boolean flags)</p></li><li><p>Use composite indexes when queries filter on multiple columns together</p></li><li><p>Monitor and rebuild indexes periodically to prevent fragmentation</p></li></ul><p>Hint: Use <strong>pg_stat_user_indexes</strong> to monitor index usage in PostgreSQL.</p><blockquote><p>Index deliberately.</p><p>Measure the impact using E<code>PLAIN ANALYZE</code>.</p><p>Remove what doesn't serve you.</p></blockquote><div><hr></div><h2>Constraints Are The Best Documentation You&#8217;ll Ever Write</h2><p>Foreign keys. <code>NOT NULL</code>. <code>UNIQUE</code>. <code>CHECK</code> constraints.</p><p>These aren&#8217;t optional guardrails. They&#8217;re how you encode business rules into the database itself.</p><p>A foreign key constraint ensures referential integrity. If <code>orders.user_id</code> references <code>users.id</code>, you can&#8217;t have an orphaned order pointing to a deleted user.</p><p>A NOT NULL constraint guarantees a value exists. No defensive null checks in application code.</p><p>A CHECK constraint validates data at write time. Age must be positive. Status must be one of five valid values.</p><p>This matters because <strong>constraints catch bugs before they corrupt data</strong>.</p><p>Constraints add minor write overhead, maybe 1-2%, or sometimes less. But they give you guaranteed correctness.</p><p>If your database allows invalid data, eventually you&#8217;ll have invalid data.</p><div><hr></div><h2>Performance Is A Design Choice, Not a Tuning Exercise</h2><p>I&#8217;ve seen teams spend weeks chasing query plans, adding caches, and tuning connection pools.</p><p>Most of the time, the real problem is the schema.</p><p>A single redesign could fix the issue forever: moving a frequently-joined column into the main table, splitting a bloated table into hot and cold storage, adding a covering index, and partitioning by time range.</p><p>Here's what makes database design genuinely hard: you don't know the full business context at the start. Requirements evolve. Query patterns change.</p><p>The answer isn&#8217;t perfection upfront. It&#8217;s about designing for change.</p><p><strong>Keep things simple. Use clear naming conventions. Avoid premature optimization. And critically, don't be afraid to migrate the schema when you learn something new about your domain or your access patterns.</strong></p><p>A well-designed schema can handle 10x growth with minor adjustments. A poorly designed one requires rewrites.</p><div><hr></div><h2>What I Wish Someone Had Told Me</h2><p>If I could give my younger self advice, I'd say this:<br><br><strong>Practice designing schemas for real systems.</strong> Pick LinkedIn, Twitter, or Airbnb. Map the entities. Draw the relationships. Think through the queries. Do it on paper before you touch a database.</p><p><strong>Learn SQL deeply.</strong> Not just <code>SELECT</code> and <code>JOIN</code>. Window functions. CTEs. Query plans. Execution order. Understand what the database does with your query.<br><br><strong>Start simple, but extensible.</strong> Don't build for scale you don't have. But leave room to grow. Design your schema so that adding columns or splitting tables doesn't require a full rewrite.<br><br><strong>Measure everything.</strong> You can't optimize what you don't measure. Track query times. Index usage. Table sizes. Slow query logs.<br><br>The best engineers I know treat database design like architecture. They think through the consequences of their decisions. They plan for failure modes. They build systems that last, not just systems that work.<br><br>And they're never ashamed to run a migration when they learn something new.<br><br><strong>Because databases don't forget your mistakes, but they do forgive your improvements.</strong></p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get practical tips on React.js, Node.js, and Software Architecture delivered straight to your inbox:</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="pullquote"><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cmMn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png" width="248" height="207.7" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:800,&quot;resizeWidth&quot;:248,&quot;bytes&quot;:257716,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8ebf3ac-ad2f-415d-9e32-111e959c8e4e_800x800.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cmMn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 424w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 848w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1272w, https://substackcdn.com/image/fetch/$s_!cmMn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9aea932b-6248-4324-9ec7-68d0bfed782e_800x670.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><strong>Follow me on <a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong> | <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong> |<strong> <a href="https://www.threads.net/@petarivanovv9">Threads</a></strong></p></div><p>Thank you for supporting this newsletter.</p><p>Consider sharing this post with your friends and get rewards.</p><p>You are the best! &#128591;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://open.substack.com/pub/petarivanovv9/p/database-design-foundations-backend-engineers-mistakes-and-lessons?r=643nm&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=true" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg" width="800" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83253,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:&quot;https://open.substack.com/pub/petarivanovv9/p/database-design-foundations-backend-engineers-mistakes-and-lessons?r=643nm&amp;utm_campaign=post&amp;utm_medium=web&amp;showWelcomeOnShare=true&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/188025481?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EvJY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!EvJY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa356e02d-1b11-4eca-81ea-3db29a595cb9_800x500.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/p/database-design-foundations-backend-engineers-mistakes-and-lessons?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://thetshaped.dev/p/database-design-foundations-backend-engineers-mistakes-and-lessons?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div class="pullquote"><p><strong>Press the Like button if you found this post helpful</strong></p></div>]]></content:encoded></item><item><title><![CDATA[Invite Your Friends & Earn Rewards 🎁]]></title><description><![CDATA[Announcing the T-Shaped Dev Referral Program! &#127881;]]></description><link>https://thetshaped.dev/p/invite-your-friends-and-earn-rewards</link><guid isPermaLink="false">https://thetshaped.dev/p/invite-your-friends-and-earn-rewards</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Tue, 27 Jan 2026 13:01:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Em8X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Thank you for reading The T-Shaped Dev &#8212; your support allows me to keep doing this work.</p><p>If you enjoy The T-Shaped Dev, it would mean the world to me if you invited friends to subscribe and read with us. If you refer friends, you will receive benefits that give you special access to The T-Shaped Dev.</p><p><strong>How to participate </strong></p><p><strong>1. Share The T-Shaped Dev. </strong>When you use the referral link below, or the &#8220;Share&#8221; button on any post, you'll get credit for any new subscribers. Simply send the link in a text, email, or share it on social media with friends.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://thetshaped.dev/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p><p>2.<strong> Earn benefits.</strong> When more friends use your referral link to subscribe (free or paid), you&#8217;ll receive special benefits.</p><ul><li><p>Get <strong>Pull Request Checklist</strong> for <strong>1 referrals</strong></p></li><li><p>Get <strong>Brag List (Work Log) Template</strong> for <strong>2 referrals</strong></p></li><li><p>Get <strong>Technical Design Document Template</strong> for <strong>3 referrals</strong></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Em8X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Em8X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 424w, https://substackcdn.com/image/fetch/$s_!Em8X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 848w, https://substackcdn.com/image/fetch/$s_!Em8X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 1272w, https://substackcdn.com/image/fetch/$s_!Em8X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Em8X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png" width="800" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:90566,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/185955792?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Em8X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 424w, https://substackcdn.com/image/fetch/$s_!Em8X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 848w, https://substackcdn.com/image/fetch/$s_!Em8X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 1272w, https://substackcdn.com/image/fetch/$s_!Em8X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18c44996-187d-412e-ada7-8f2ea52f974a_800x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Refer just 3 people &amp; I'll send you some rewards. &#127873;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://thetshaped.dev/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p>]]></content:encoded></item><item><title><![CDATA[How to 10x Your Code Quality With Three AI Tools]]></title><description><![CDATA[Learn how to build software smartly with Advisor, Generator & Reviewer AI Agents (5 min)]]></description><link>https://thetshaped.dev/p/how-to-10x-your-code-quality-with-three-ai-tools-advisors-generators-reviewers</link><guid isPermaLink="false">https://thetshaped.dev/p/how-to-10x-your-code-quality-with-three-ai-tools-advisors-generators-reviewers</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sat, 17 Jan 2026 07:19:32 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a6989583-b9ce-4568-859d-3a82ca0ee348_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 29,500+ engineers to receive one practical tip on JS, React, NodeJS, Software Design, and Architecture every 1-2 weeks.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>Imagine you&#8217;re using one AI tool for everything - designing, planning, coding, reviewing, etc.</p><p>After a while, you start to see some pitfalls in the LLMs output.</p><p>While many LLMs are doing okay for general-purpose tasks, they tend to fall short when it comes to highly specialized tasks.</p><p>That&#8217;s why it is important to use different types of AI agents, each optimized for a different task.</p><p>For example, let&#8217;s say you have a UI problem. You would ask for help from the Front-End guy, not the Back-End guy, even though the Back-End guy has some knowledge of the front-end too.</p><p>We should apply the same logic and approach to using LLMs as well.</p><blockquote><p><strong>Use the right agent for the right task so we can craft better software</strong>.</p></blockquote><p>In the previous article, we covered the <a href="https://thetshaped.dev/p/the-systematic-ai-code-review-workflow-plan-generate-validate">systematic AI code review workflow: Plan, Generate, Validate</a>.</p><p>Now, let&#8217;s map the right tools to each phase:</p><ul><li><p>Plan &#8594; use Advisors (think through decisions)</p></li><li><p>Generate &#8594; use Generators (write code fast)</p></li><li><p>Validate &#8594; use Reviewers (catch issues automatically)</p></li></ul><p>Each phase needs a different type of AI agent. Let&#8217;s understand what makes each one specialized and what traps to avoid when using.</p><div><hr></div><h2>The Three Types of AI Agents</h2><p>Each AI agent is trained and optimized for specific tasks.</p><p>Using a generator for security review is like using a hammer to tighten a screw.</p><p>It&#8217;s technically possible, but we would use the wrong tool for the job.</p><p>Here is the breakdown:</p><ul><li><p><strong>Advisors</strong> (<a href="https://claude.ai/">Claude</a>, <a href="https://chat.openai.com/">ChatGPT</a>)</p><ul><li><p><em>Purpose</em>: understanding and decision making</p></li><li><p><em>Optimized for</em>: explaining concepts, evaluating trade-offs, designing, researching, refactoring strategy</p></li><li><p><em>Blind to</em>: your specific codebase, real-time feedback, automated integration</p></li></ul></li><li><p><strong>Generators</strong> (<a href="https://cursor.com/">Cursor</a>, <a href="https://copilot.microsoft.com/">Copilot</a>)</p><ul><li><p><em>Purpose</em>: fast code implementation</p></li><li><p><em>Optimized for</em>: speed, autocomplete, pattern matching</p></li><li><p><em>Blind to</em>: security vulnerabilities, architectural implications, edge cases</p></li></ul></li><li><p><strong>Reviewers</strong> (<a href="https://coderabbit.link/dev">CodeRabbit</a> and similar)</p><ul><li><p><em>Purpose</em>: quality assurance and bug detection</p></li><li><p><em>Optimized for</em>: security, bugs, performance, consistency</p></li><li><p><em>Blind to</em>: design decisions, why code exists, future requirements</p></li></ul></li></ul><p>If you&#8217;re wondering when to use each, use these questions to navigate your judgment:</p><ul><li><p>Need to make a design decision? &#8594; use Advisor</p></li><li><p>Need to write code fast? &#8594; use Generator</p></li><li><p>Need to validate code quality? &#8594; use Reviewer</p></li></ul><blockquote><p><strong>Your role is to select the tool, knowing which agent to use and when.<br>You have to validate, reason, and do problem-solving.</strong></p></blockquote><p>Now, let&#8217;s dig deeper into each AI agent.</p><p><em><strong>Note</strong>: Some IDEs, like Cursor, have different modes built in, like Agent, Plan, Debug, Ask, so you could use one IDE, switch the mode, and have a different type of AI agent. However, you still have to know how to use each of those tools.</em></p><div><hr></div><h2>The Advisor: When Decisions Matter</h2><p>Advisors don&#8217;t write your code or review it automatically.</p><p>They help you think through problems, break down complex tasks into an executable plan, understand trade-offs, and make better decisions before you start implementing a specific approach.</p><p>Advisors excel at explaining the &#8220;why&#8221; behind code, not just what it does, but the reasoning and trade-offs that led to that implementation.</p><p>&#9989; With Advisors, you should <strong>prefer</strong>:</p><ul><li><p>Using before making major architectural decisions</p></li><li><p>Understanding existing and/or unfamiliar code</p></li><li><p>Exploring different approaches and strategies and their trade-offs</p></li><li><p>Providing context about your project, current choices, and structure</p></li><li><p>Learning new patterns and concepts</p></li></ul><p>&#9940; With Advisors, you should <strong>avoid</strong>:</p><ul><li><p>Writing code (generators are faster)</p></li><li><p>Using them for bug detection (reviewers are better)</p></li><li><p>Expecting it to know your codebase or internal team&#8217;s dynamics</p></li><li><p>Following advice blindly without understanding</p></li></ul><p>So,</p><blockquote><p><strong>Advisors help you make better decisions.</strong></p></blockquote><p>Use them before you start coding, not after.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Join 29,500+ engineers to receive one practical tip on JS, React, NodeJS, Software Design, and Architecture every 1-2 weeks.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>The Generator: When Speed Matters</h2><p>The Generators excel at writing code quickly.</p><p>They&#8217;re autocomplete on steroids, trained on millions of code examples to predict what you&#8217;re trying to write.</p><p><strong>&#9989; </strong>With Generators, you should <strong>prefer</strong>:</p><ul><li><p>Using for daily coding, boilerplate, CRUD operations, etc</p></li><li><p>Scaffolding tests</p></li><li><p>Writing type definitions and interfaces</p></li><li><p>Writing code to follow existing patterns and conventions</p></li><li><p>Iterating on suggestions and do not always accept the first try</p></li></ul><p>&#9940; With Generators, you should <strong>avoid</strong>:</p><ul><li><p>Trusting it for security-critical code without review</p></li><li><p>Assuming it validates business logic</p></li><li><p>Assuming it writes proper type definitions of your domain models</p></li><li><p>Using it to make architectural decisions</p></li><li><p>Skipping review because &#8220;AI wrote it&#8221;</p></li></ul><p>So,</p><blockquote><p><strong>Generators are for speed.<br>Always validate the output with a review and your reasoning.</strong></p></blockquote><p>Use them after you have a concrete plan in mind.</p><div><hr></div><h2>The Reviewer: When Quality Matters</h2><p>Reviewers are specialized for finding issues in existing code.</p><p>An example of a Reviewer is <a href="https://coderabbit.link/dev">CodeRabbit</a>.</p><p>They don&#8217;t generate. They analyze, detect patterns and conventions, and flag problems.</p><p><strong>&#9989; </strong>With Reviewers like <a href="https://coderabbit.link/dev">CodeRabbit</a>, you should <strong>prefer</strong>:</p><ul><li><p>Using on every PR before merging</p></li><li><p>Addressing security and bug findings immediately</p></li><li><p>Using suggestions as learning opportunities (you could ask Advisors to help)</p></li><li><p>Configuring rules and guidelines for your specific tech stack and codebase</p></li></ul><p>&#9940; With Reviewers like <a href="https://coderabbit.link/dev">CodeRabbit</a>, you should <strong>avoid</strong>:</p><ul><li><p>Skipping review because the code &#8220;looks fine&#8221;</p></li><li><p>Dismissing warnings or applying suggestions without understanding them</p></li><li><p>Using it to write new code (wrong tool)</p></li><li><p>Expecting it to validate business logic</p></li></ul><p>So,</p><blockquote><p><strong>Reviewers help us catch things which generators miss.</strong></p><p>They act as our QA and Security guy.</p></blockquote><p>Use them while or after you generate code. Then you fix and repeat.</p><div><hr></div><p>Now that we understand each agent&#8217;s specialty.</p><p>Here is how to use them together effectively:</p><ul><li><p>Making a decision? &#8594; Advisor (understand trade-offs first, make a plan)</p></li><li><p>Writing code? &#8594; Generator (fast implementation)</p></li><li><p>Code written? &#8594; Reviewer (catch issues automatically)</p></li><li><p>Issues found? &#8594; Generator (quick fixes) &#8594; Reviewer (validate)</p></li></ul><p>And remember:</p><blockquote><p><strong>&#9888;&#65039; Your role is to select the tool and always validate and understand the output!</strong></p></blockquote><div><hr></div><h2>When Agents Disagree</h2><p>Sometimes, different agents might suggest conflicting approaches.</p><p>Here is how I resolve them:</p><ul><li><p><strong>For architecture</strong>, I weigh the Advisor&#8217;s opinion carefully, but also consider the current context, business needs, and constraints.</p></li><li><p><strong>For implementation details</strong>, I follow the generated code from the Generator because it knows the codebase best and the already established patterns.</p></li><li><p><strong>For security issues</strong>, I trust the Reviewer&#8217;s suggestions (like <a href="https://coderabbit.link/dev">CodeRabbit</a>) because security is non-negotiable.</p></li></ul><p>In the end, the final decision is yours because you know all the specific domain and business context, needs, and constraints.</p><p>AI shouldn&#8217;t be your excuse for making wrong and unjustified decisions.</p><p>You are the Software Engineer who navigates and drives the AI, not the other way around.</p><p><strong>You&#8217;re the final decision maker!</strong></p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Join 29,500+ engineers to receive one practical tip on JS, React, NodeJS, Software Design, and Architecture every 1-2 weeks.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>Using one AI tool for everything means missing what other specialized tools catch.</p></li><li><p>Prefer to use a different AI agent, each optimized for different tasks</p></li><li><p>We have generally three types of AI agents: advisors (Claude/ChatGPT), generators (Cursor/Copilot), and reviewers (<a href="https://coderabbit.link/dev">CodeRabbit</a>).</p></li><li><p>Match the tool to the tasks, advisors for decisions, generators for speed, reviewers for safety.</p></li></ul><p>So try out these three agent types in your daily coding workflow and let me know how you found them.</p><p>I promise this way of working will improve your code.</p><p>Hope this was helpful.</p><p>See you next time! &#128588;</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 29.5K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[The Systematic AI Code Review Workflow: Plan, Generate, Validate]]></title><description><![CDATA[A practical guide to maintain quality at AI speed (6 min)]]></description><link>https://thetshaped.dev/p/the-systematic-ai-code-review-workflow-plan-generate-validate</link><guid isPermaLink="false">https://thetshaped.dev/p/the-systematic-ai-code-review-workflow-plan-generate-validate</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sat, 27 Dec 2025 12:07:14 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ef00d78f-b0d4-4d54-a72a-b40080ef322a_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 29,300+ engineers to receive one practical tip on JS, React, NodeJS, Software Design, and Architecture every 1-2 weeks.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>Once upon a time, a developer spent an afternoon building a user registration API with AI assistance.</p><p>API endpoints, proper validation, clean error handling&#8212;everything compiled perfectly and worked flawlessly in staging.</p><p>The PR was approved and merged into production.</p><p>Hours later, the security team sent an urgent Slack message.</p><p>The newly introduced endpoint was vulnerable to SQL injection through unvalidated query parameters.</p><p>One line of code. One blind spot.</p><p>One security vulnerability that an automated review would have caught instantly.</p><p>That&#8217;s the current reality of AI and Vibe coding without a systematic workflow:</p><blockquote><p><strong>It&#8217;s not a productivity, it&#8217;s a technical debt at AI speed.</strong></p></blockquote><p>To mitigate this, we need a new system to handle the massive code generation facilitated by AI.</p><p>In today&#8217;s article, I&#8217;ll share a systematic AI code review workflow to adapt to the new AI and Vibe coding era. </p><div><hr></div><h2>Why You Need a Loop</h2><p>Most developers follow this pattern:</p><ol><li><p>Generate code with AI</p></li><li><p>Push to production</p></li><li><p>Hope for the best</p></li></ol><p>The problem with this approach is that AI optimizes for &#8220;working&#8221;, not &#8220;correct&#8221; code.</p><p>It writes code that compiles and runs, but might have security vulnerabilities, performance issues, edge case failures, and inconsistent error handling.</p><p><em>Imagine the following scenario:</em> You ask your LLM to generate an Express API endpoint for user registration. The code works perfectly:</p><pre><code>app.post(&#8217;/api/register&#8217;, async (req, res) =&gt; {
  const { email, password, username } = req.body;
  
  const user = await db.query(
    `INSERT INTO users (email, password, username) VALUES (&#8217;${email}&#8217;, &#8216;${password}&#8217;, &#8216;${username}&#8217;) RETURNING *`
  );
  
  res.json({ success: true, user });
});</code></pre><p>However, there are a few major problems. SQL injection vulnerability. No password hashing. No input validation. No error handling, etc. You get the point.</p><p>The main point is that the code &#8220;works&#8221;, but it&#8217;s a security nightmare.</p><p>This is where the <strong>three-phase loop</strong> comes in:</p><pre><code>Plan &#8594; Generate &#8594; Review &#8594; Ship
         &#8593;            &#8595;
         &#9492;&#9472;&#9472; Fix &#9472;&#9472;&#9472;&#9472;&#9472;&#9496;</code></pre><p>The key principle is:</p><blockquote><p>Separate generation from validation.</p></blockquote><p>You might use:</p><ul><li><p><strong>Generation AI</strong>, like <a href="https://cursor.com/">Cursor</a>, <a href="https://claude.ai/">Claude</a>, or <a href="https://copilot.microsoft.com/">Copilot</a>, optimizes for speed and functionality.</p></li><li><p><strong>Review AI</strong>, like <a href="https://coderabbit.link/dev">CodeRabbit</a>, optimizes for security, performance, and quality.</p></li><li><p><strong>You</strong> act as an orchestrator of both.</p></li></ul><p>This way, each phase catches different types of issues.</p><p>Let&#8217;s dive in.</p><div><hr></div><h2>Phase 1: Plan Before You Generate</h2><p>Good AI output starts with good input.</p><p>Planning before you generate any code creates better results.</p><p>Why planning matters:</p><ul><li><p>clear specs = better AI output</p></li><li><p>prevents &#8220;works but unmaintainable&#8221; code</p></li><li><p>creates a checklist for validation</p></li><li><p>saves hours of debugging later</p></li></ul><p>You might use <a href="https://cursor.com/docs/agent/planning">Cursor Plan mode</a>, or any other LLM like Claude or ChatGPT, to come up with a detailed action plan.</p><p>I personally try to fill out the following template before moving to the code generation:</p><pre><code>Feature: [Name]
Purpose: [One sentence]
Inputs: [List with types and validation rules]
Outputs: [Success and error cases]
Edge cases: [What could go wrong?]
Security considerations: [What must be protected?]</code></pre><p><em>Feel free to edit it based on your current context, problem, and task.</em></p><p>This approach helps me be more confident that I&#8217;ve outlined all the important requirements and considerations before moving to the next phase.</p><p>If we follow the example from above related to the user registration endpoint for an Express API, we might prompt the following:</p><pre><code><strong>I need</strong> a user registration endpoint for an Express API. <strong>Users provide</strong> email, password, and username. <strong>Help me design</strong> the endpoint <strong>that handles</strong> validation errors, duplicate emails, and weak passwords. <strong>What else should I consider for</strong> security, validation, and error handling?</code></pre><p>Based on the given output, summarize the findings into the above-mentioned template, so you can share it in the prompt in a structured format when starting to generate code.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable Software Engineering and Full-Stack JavaScript-related tips straight into your inbox every two weeks.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Phase 2: Generate With Context</h2><p>Once you&#8217;ve gone through the planning and have a structured and summarized plan, you&#8217;re ready to generate.</p><p>Since you already defined a plan, you can create focused and high-quality prompts.</p><p><strong>Generation best practices</strong>:</p><ul><li><p>Generate one endpoint, component, or feature at a time. Don&#8217;t generate the entire service. The smaller and more focused the task, the better the outcome.</p></li><li><p>Use separate prompts/chats per task. Maintain the context window. Keep it as small as possible. This also reduces the costs.</p></li><li><p>Copy relevant sections from your plan directly into the prompt.</p></li><li><p>Iterate 2-3 times rather than expecting perfection on the first try.</p></li><li><p>Specify your exact tech stack, code style, and structure. Provide examples from the codebase if relevant.</p></li></ul><blockquote><p><strong>AI generation is a conversation, not a one-shot command!</strong></p></blockquote><p>During the code generation phase, you want to <strong>manually check</strong>:</p><ul><li><p>Does it follow your tech stack conventions?</p></li><li><p>Are the types and interfaces correct?</p></li><li><p>Does it match your project structure?</p></li><li><p>Are dependencies the ones you actually use?</p></li></ul><p>If something looks off, create a new chat and refine your prompt with more specific guidance.</p><blockquote><p>In the LLM world, if the first prompt is not okay, it&#8217;s hard to change it later.<br>Better create a new chat with a clean context and an improved prompt.</p></blockquote><p>Coming back to the example from above related to the user registration endpoint for an Express API, we might prompt the following:</p><pre><code>Create an Express TypeScript POST endpoint at /api/register for user registration.

Requirements:
- Accept email (string), password (string), username (string) in request body
- Validate email format (RFC 5322)
- Validate password: minimum 8 characters with at least one number
- Validate username: 3-20 alphanumeric characters only
- Hash password with bcrypt (12 rounds) before storing
- Use parameterized database queries to prevent SQL injection
- Handle duplicate email (return 409 with generic message)
- Handle validation errors (return 400 with field-specific errors)
- Handle database errors gracefully
- Return 201 with user object (exclude password) on success

Use Zod for input validation and proper TypeScript types throughout.</code></pre><p>Even though we&#8217;ve outlined a detailed plan and have a solid code, we might still miss important stuff.</p><p>For example, &#8220;Are there any missed edge cases?&#8221;, &#8220;Performance implications?&#8221;, &#8220;Is the validation comprehensive enough?&#8221;, etc.</p><p>This is exactly why we need the review phase.</p><p>We want to get a higher confidence in what we ship and double-check that we haven&#8217;t missed important considerations.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable Software Design and Software Architecture tips straight into your inbox every two weeks.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Phase 3: Review and Validate</h2><p>We have a working code. Now, it&#8217;s time to validate it with a second AI perspective specialized for review.</p><p>Why bother reviewing AI-generated code?</p><ul><li><p>AI generators have blind spots. They optimize for &#8220;working&#8221;, not &#8220;correct&#8221; code.</p></li><li><p>Different AI models catch different issues and blind spots.</p></li><li><p>Automated reviews find problems in seconds.</p></li><li><p>Ensures consistency across your codebase.</p></li></ul><p>An example of such an AI code review tool is <a href="https://coderabbit.link/dev">CodeRabbit</a>.</p><p>What <a href="https://coderabbit.link/dev">CodeRabbit</a> catches:</p><ul><li><p><strong>Security</strong>: SQL injections, XSS vulnerabilities, exposed secrets, etc.</p></li><li><p><strong>Bugs</strong>: race conditions, incorrect error handling, etc.</p></li><li><p><strong>Performance</strong>: missing db indexes, N+1 queries, etc.</p></li><li><p><strong>Best practices</strong>: inconsistent error handling, missing type safety, etc.</p></li></ul><p>Put simply, <a href="https://coderabbit.link/dev">CodeRabbit</a> complements human reviewers, adding a lot of context based on your repo and general engineering practices.</p><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><p>This systematic AI code review workflow isn&#8217;t optional; it&#8217;s how you maintain quality at AI speed:</p><ul><li><p><strong>Plan</strong> before you generate (upfront thinking saves hours).</p></li><li><p><strong>Generate</strong> with context (good prompts = good code).</p></li><li><p><strong>Review</strong> with specialized AI (e.g., <a href="https://coderabbit.link/dev">CodeRabbit</a> catches what generators miss).</p></li></ul><p>Hope this was helpful.</p><p>See you next time! &#128588;</p><p>P.S. If you&#8217;re into Web Development, I recommend you subscribe to <a href="https://markodenic.tech/">Marko Denic</a>&#8217;s newsletter, which is full of many tips and tricks.</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 29.3K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[2-Tier to 3-Tier Architecture: Migration Journey With Modular Monolith and GraphQL]]></title><description><![CDATA[A real-world case study of migrating a two-tier architecture to a three-tier architecture. (5 min)]]></description><link>https://thetshaped.dev/p/two-tier-to-three-tier-architecture-migration-case-stuty-modular-monolith-graphql-api-software-architecture</link><guid isPermaLink="false">https://thetshaped.dev/p/two-tier-to-three-tier-architecture-migration-case-stuty-modular-monolith-graphql-api-software-architecture</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Tue, 18 Nov 2025 11:09:47 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/06cdc73c-e487-4e0d-b706-e24a2ebf3136_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 28,000+ engineers to receive one practical tip on JS, React, NodeJS, Software Design, and Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>A while ago, I worked for a client who had a diverse portfolio of digital products.</p><p>They&#8217;ve struggled to develop new features, reuse business logic and functionality across products, and also scale the engineering team.</p><p>By digging deeper into the case, I&#8217;ve found they have:</p><ul><li><p>bad architecture, which doesn&#8217;t support their growth</p></li><li><p>years of accumulated technical debt</p></li></ul><p>The root cause turned out to be a 2-Tier Architecture that had outlived its purpose.</p><p>In today&#8217;s article, I&#8217;ll share how I tackled this challenge by migrating their system from a Two-Tier Architecture to a Three-Tier Architecture, introducing a scalable, robust GraphQL API.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5nt7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 424w, https://substackcdn.com/image/fetch/$s_!5nt7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 848w, https://substackcdn.com/image/fetch/$s_!5nt7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 1272w, https://substackcdn.com/image/fetch/$s_!5nt7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5nt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp" width="469" height="305.5828125" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:834,&quot;width&quot;:1280,&quot;resizeWidth&quot;:469,&quot;bytes&quot;:11044,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/156653767?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5nt7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 424w, https://substackcdn.com/image/fetch/$s_!5nt7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 848w, https://substackcdn.com/image/fetch/$s_!5nt7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 1272w, https://substackcdn.com/image/fetch/$s_!5nt7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ab1d82-5d53-4e65-a347-fd446e64aed0_1280x834.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar">IcePanel</a> is a collaborative diagramming and modelling tool for designing software architecture. Create interactive, layered views for different stakeholders from a single source of truth.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar&quot;,&quot;text&quot;:&quot;Try for free&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar"><span>Try for free</span></a></p><div><hr></div><p>Before we dive into the actual migration journey, let&#8217;s ensure we understand what a 2-Tier and a 3-Tier architecture are.</p><h2>What is Two-Tier Architecture?</h2><p>2-Tier Architecture is a simple setup in which your application talks directly to a database.</p><p>You have a presentation layer (the front-end) and a data layer (the database).</p><p>That&#8217;s it. No middle layer.</p><p>Think of it like a simple website or app that sends requests directly to the database, retrieves the data, and displays it to users.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!w_Ph!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 424w, https://substackcdn.com/image/fetch/$s_!w_Ph!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 848w, https://substackcdn.com/image/fetch/$s_!w_Ph!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 1272w, https://substackcdn.com/image/fetch/$s_!w_Ph!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!w_Ph!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png" width="507" height="657.0803571428571" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1887,&quot;width&quot;:1456,&quot;resizeWidth&quot;:507,&quot;bytes&quot;:145028,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/156653767?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!w_Ph!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 424w, https://substackcdn.com/image/fetch/$s_!w_Ph!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 848w, https://substackcdn.com/image/fetch/$s_!w_Ph!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 1272w, https://substackcdn.com/image/fetch/$s_!w_Ph!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717c6e12-81fb-4ce0-8a95-07b50a50d9ad_1600x2074.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Diagram created in <a href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar">IcePanel</a>.</figcaption></figure></div><div><hr></div><h2>What is Three-Tier Architecture?</h2><p>3-Tier Architecture adds an essential middle layer between your front-end and database. Now you have:</p><ol><li><p><strong>Presentation Layer</strong> - the front-end (what users see).</p></li><li><p><strong>Business Logic Layer</strong> - the API (where the magic happens).</p></li><li><p><strong>Data Layer</strong> - the database (where data lives).</p></li></ol><p>The middle layer handles all the business logic, security, and data processing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AXbD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 424w, https://substackcdn.com/image/fetch/$s_!AXbD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 848w, https://substackcdn.com/image/fetch/$s_!AXbD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 1272w, https://substackcdn.com/image/fetch/$s_!AXbD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AXbD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png" width="553" height="716.6971153846154" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1887,&quot;width&quot;:1456,&quot;resizeWidth&quot;:553,&quot;bytes&quot;:159125,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/156653767?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AXbD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 424w, https://substackcdn.com/image/fetch/$s_!AXbD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 848w, https://substackcdn.com/image/fetch/$s_!AXbD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 1272w, https://substackcdn.com/image/fetch/$s_!AXbD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c97fd46-8bdd-40c1-9cee-41d6a72ae768_1600x2074.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Diagram created in <a href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar">IcePanel</a>. <a href="https://s.icepanel.io/VshUdhGpfKEaFf/w2Ys">Link</a> to the diagram.</figcaption></figure></div><p>The main difference between a 2-Tier and a 3-Tier architecture is the <strong>separation of concerns</strong>.</p><p>In a Two-Tier architecture, your front-end must know too much about your data, whereas in a Three-Tier architecture, the business logic layer acts as a smart middleman.</p><p>This smart middleman protects your data and enables the whole system to be more flexible.</p><div><hr></div><h2>The Starting Architecture (Two-Tier)</h2><p>Now, let me show you what the client&#8217;s system looked like before the migration.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5GPa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5GPa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 424w, https://substackcdn.com/image/fetch/$s_!5GPa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 848w, https://substackcdn.com/image/fetch/$s_!5GPa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 1272w, https://substackcdn.com/image/fetch/$s_!5GPa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5GPa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png" width="1456" height="1034" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1034,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:350343,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/156653767?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5GPa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 424w, https://substackcdn.com/image/fetch/$s_!5GPa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 848w, https://substackcdn.com/image/fetch/$s_!5GPa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 1272w, https://substackcdn.com/image/fetch/$s_!5GPa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa84adb46-8e32-401a-8986-e44a37fff31a_3296x2341.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Diagram created in <a href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar">IcePanel</a>.</figcaption></figure></div><p>They had three main services, all sharing one MySQL database:</p><ul><li><p><strong>Portal</strong> - The customer-facing web portal. The front-end was React, but the back-end was built with CakePHP 2 (an outdated PHP framework).</p></li><li><p><strong>Admin</strong> - The internal management web portal of the company. Everyone in the company used it to run the business, from operations to finance. Also built with CakePHP 2.</p></li><li><p><strong>API</strong> - A small REST API with just three methods for customers. Again, Cake PHP 2.</p></li></ul><p>All three services are connected directly to the same MySQL database.</p><p>The database was the integration point for everything.</p><p>This setup created several serious problems.</p><h3>The Top Technical Challenges</h3><ul><li><p><strong>Duplicated logic</strong> - The same business logic and rules were duplicated in multiple services.</p></li><li><p><strong>Database as an integration point</strong>&nbsp;- Having multiple services write to the same database is risky. There is no single source of truth for business logic and data validation. Also, it is very hard to update or migrate the database when having multiple clients.</p></li><li><p><strong>Technical debt</strong> - CakePHP 2 reached end of life. There was a need to modernize the tech stack by using well-adapted technologies.</p></li><li><p><strong>Hard to scale the engineering team</strong> - This was hard to find developers to work on front-end and back-end with the present technologies. There was a need to enable full-stack developers.</p></li><li><p><strong>Slow feature development</strong> - With the challenges mentioned above, feature development was slow, hindering the business's growth.</p></li></ul><div><hr></div><p>To address these challenges, we introduced a new middle layer&#8212;a GraphQL API.</p><h2>The Final Architecture (Three-Tier)</h2><p>The GraphQL API became the heart of the system.</p><p>It sits between all front-ends and the database.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qFgK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qFgK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 424w, https://substackcdn.com/image/fetch/$s_!qFgK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 848w, https://substackcdn.com/image/fetch/$s_!qFgK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 1272w, https://substackcdn.com/image/fetch/$s_!qFgK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qFgK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png" width="1456" height="948" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:948,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:377186,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/156653767?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qFgK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 424w, https://substackcdn.com/image/fetch/$s_!qFgK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 848w, https://substackcdn.com/image/fetch/$s_!qFgK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 1272w, https://substackcdn.com/image/fetch/$s_!qFgK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6aaf9b16-73ce-4bed-9e95-0ceb36b7b970_3632x2365.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Diagram created in <a href="http://icepanel.io/?utm_source=substack&amp;utm_campaign=petar">IcePanel</a>. <a href="https://s.icepanel.io/VshUdhGpfKEaFf/TjoF">Link</a> to the diagram.</figcaption></figure></div><h3>The Main Architectural Improvements</h3><p>The new architecture solved our major pain points:</p><ul><li><p><strong>Centralized business logic</strong> - All business-related logic lives in one place now. The GraphQL API is the single source of truth for all features.</p></li><li><p><strong>Single database owner</strong> - Only the GraphQL API can access the database. This makes the system safer and easier to refactor.</p></li><li><p><strong>Modern tech stack</strong> - We built the API using Node.js, a technology already used by the company. Apart from that, <a href="https://thetshaped.dev/p/graphql-intro-101-part-1">GraphQL</a> provides flexible, efficient data fetching to accommodate the needs of different API clients.</p></li><li><p><strong>Full-stack friendly</strong> - Having the same core technology, JavaScript, on the front-end and back-end, enabled the company to hire Full-Stack JavaScript developers.</p></li><li><p><strong>Ready for microservices</strong>&nbsp;- To ensure the system's future flexibility and the company&#8217;s growth, the API was designed as a <a href="https://thetshaped.dev/p/what-is-a-modular-monolith-benefits-and-microservices-challenges">Modular Monolith</a>, so that, when needed, internal modules could be extracted into separate services.</p></li></ul><h2>The Migration Approach</h2><p>We didn&#8217;t rebuild everything overnight.</p><p>This was too risky from both a business and an engineering perspective.</p><p>The business must continue operating while the groundwork is being done under the hood.</p><p>That&#8217;s why we took an iterative approach:</p><ul><li><p><strong>Phase 1: Build the GraphQL API</strong> - We created the new API layer, starting with the most critical business logic, shared across multiple services.</p></li><li><p><strong>Phase 2: Migrate Portal</strong> - The Portal front-end started using the GraphQL API. We moved features one by one and tested thoroughly.</p></li><li><p><strong>Phase 3: Update Admin</strong> - We upgraded Admin to a modern version of CakePHP. Then we gradually moved its logic to the GraphQL API, starting with shared functionality.</p></li><li><p><strong>Phase 4: Rewrite REST API</strong> - The customer-facing REST API had only three methods, so we rewrote it in Node.js to align with the new stack.</p></li><li><p><strong>Phase 5: Migrate Admin to React</strong>&nbsp;- We started migrating the Admin to React, instead of CakePHP, prioritizing newly incoming feature requests.</p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable JS, React, NodeJS, Software Design and Architecture tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>2-Tier Architecture is when multiple clients or services directly communicate with the Database.</p></li><li><p>3-Tier Architecture is when multiple clients or services communicate with a middle layer, usually an API, which then communicates with the actual DB.</p></li><li><p>Having three clients communicating with a DB means duplicated business logic everywhere.</p></li><li><p>Having a middle layer, in this case a GraphQL API, means a single user communicates with the DB, removing duplicate business logic.</p></li><li><p>Centralizing business logic in the GraphQL API eliminated duplicate code, made onboarding new teammates easier, enabled quicker feature delivery, and created a system ready to scale into microservices when needed.</p></li></ul><p>Hope this was helpful.</p><p>See you next time! &#128588;</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 28.7K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Conscious Debugging: 10 Effective Strategies That Actually Work 🐛]]></title><description><![CDATA[Learn how to find and fix bugs like a pro with these ten effective debugging strategies. (6 min)]]></description><link>https://thetshaped.dev/p/conscious-debugging-10-effective-debugging-strategies-debug-like-pro</link><guid isPermaLink="false">https://thetshaped.dev/p/conscious-debugging-10-effective-debugging-strategies-debug-like-pro</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sat, 08 Nov 2025 05:19:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/52a28f14-9491-42d5-9b47-0fc902818396_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We&#8217;ve all been there - staring at a bug that makes absolutely no sense.</p><p>You&#8217;ve tried everything you can think of, but the issue persists&#8230;</p><p>Debugging doesn&#8217;t have to be this painful.</p><p>It&#8217;s a skill you can develop with the right strategies and tools.</p><p>It&#8217;s something you can learn and get better at.</p><blockquote><p><strong>Mastering debugging can save you time, energy, frustrations, and money as well as improve your code quality.</strong></p></blockquote><p>In today&#8217;s article, I&#8217;ll share ten practical debugging techniques I use daily that have saved me countless hours.</p><p>I&#8217;ll also show you some modern tools that could make these strategies even more effective.</p><div><hr></div><p>Being effective while debugging is crucial.</p><p>It&#8217;s really important to get it right so you find the root cause of the issue, fix it asap, and then make your customers happy.</p><p>Over the years, as a Software Engineer, I&#8217;ve found that good debugging is not only about the processes and systems you employ, but also about your mindset and tooling.</p><p>I&#8217;ve played around with various tools both at my daily job and side projects.</p><p>Recently, I tried out <a href="https://trymultiplayer.link/petar-ivanov">Multiplayer</a>, a new session replay platform that captures both the front-end and back-end traces.</p><p>I believe we can make debugging much simpler with the help of <a href="https://trymultiplayer.link/petar-ivanov">Multiplayer</a>, effective, and easier to do.</p><div><hr></div><h2>Part 1: Set Yourself Up For Success</h2><h3>1. Reproduce the Error Consistently</h3><p>You can&#8217;t fix what you can&#8217;t see.</p><p>The foundation of effective debugging is consistently reproducing the bug.</p><p>Start by writing step-by-step instructions that make the bug appear every time.</p><p>For example, map out how a user request flows through the whole system, so you build a clear mental model.</p><p>This is especially useful in the context of microservice architecture, where a single user request might hit several services.</p><p>Finding the bug in the ground schema is hard if you don&#8217;t have a good understanding of the flow.</p><p>Nowadays, there are tools that record session replays, so you can leverage them to see the flow from the front-end to the back-end instead of doing it manually.</p><p>An example of such a tool is <a href="https://trymultiplayer.link/petar-ivanov">Multiplayer</a>, which captures full-stack session recordings.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://trymultiplayer.link/petar-ivanov" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PcjW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 424w, https://substackcdn.com/image/fetch/$s_!PcjW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 848w, https://substackcdn.com/image/fetch/$s_!PcjW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 1272w, https://substackcdn.com/image/fetch/$s_!PcjW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PcjW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png" width="1024" height="604" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:604,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:266625,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://trymultiplayer.link/petar-ivanov&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/177173524?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PcjW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 424w, https://substackcdn.com/image/fetch/$s_!PcjW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 848w, https://substackcdn.com/image/fetch/$s_!PcjW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 1272w, https://substackcdn.com/image/fetch/$s_!PcjW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba4b94f4-38af-441d-9b76-4decf7fa2867_1024x604.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>2. Reproduce the Error Quickly</h3><p>Once you know how to reproduce a bug, make it fast.</p><p>Configure your development environment to jump straight to the problematic area.</p><p>This helps to quickly test various hypotheses and solutions.</p><p>Every second you save between reproducing the bug and testing a fix compounds over the course of dozens of debugging iterations.</p><h3>3. Capture the Full Context</h3><p>Debugging an issue in a complex system &#8212;from front-end to back-end &#8212;is hard.</p><p>It requires acquiring as much information and context as needed.</p><p>Imagine a user reporting a problem&#8212;&#8220;the page crashed&#8221;&#8212;but you miss information like why they clicked, what data they had loaded, or the system's state.</p><p>So, before digging into the problem, try to collect as much context as possible&#8212;ask your product manager, write an email to a client, check recordings, logs, etc.</p><p>You might also consider using a tool like <a href="https://trymultiplayer.link/petar-ivanov">Multiplayer</a>, which silently captures user sessions so you can collect all the context related to a single issue.</p><div><hr></div><h2>Part 2: Active Debugging Techniques</h2><h3>4. Isolate the Problem</h3><p>Large codebases make finding bugs like finding a needle in a haystack.</p><p>You need to narrow down the scope quickly.</p><p>Use a <strong>binary search approach</strong>: <strong>divide your code into working and non-working parts</strong>.</p><p>Comment out half of the suspicious code. Does the bug occur? If yes, the problem is in the other half. If no, it&#8217;s in the code you commented out.</p><p>You might also use breakpoints like a binary search to quickly jump to different points in your code.</p><p>Repeat this process until you&#8217;ve nailed the problematic area.</p><p>The main goal is to minimize the scope from &#8220;somewhere in this 1000-line file&#8221; to &#8220;somewhere in these 20 lines&#8221;.</p><h3>5. Use Your Debugger</h3><p>Debuggers are invaluable tools that provide real-time insights into your program&#8217;s execution.</p><p>You can set breakpoints, inspect variables, step through the code line by line, and examine the call stack.</p><p>The main benefit is that you can easily see the exact flow of your program and spot anomalies as they happen.</p><p>If you&#8217;re using tools for recording session replays, you could bring those recordings directly into your IDE.</p><p>I&#8217;ve personally tried <a href="https://trymultiplayer.link/petar-ivanov">Multiplayer</a> and it worked like a charm.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://trymultiplayer.link/petar-ivanov" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2EcT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 424w, https://substackcdn.com/image/fetch/$s_!2EcT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 848w, https://substackcdn.com/image/fetch/$s_!2EcT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 1272w, https://substackcdn.com/image/fetch/$s_!2EcT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2EcT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png" width="1024" height="602" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:602,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:217639,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://trymultiplayer.link/petar-ivanov&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/177173524?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2EcT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 424w, https://substackcdn.com/image/fetch/$s_!2EcT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 848w, https://substackcdn.com/image/fetch/$s_!2EcT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 1272w, https://substackcdn.com/image/fetch/$s_!2EcT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7f3ac9-1799-4eab-9426-335b90e2c697_1024x602.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>6. Rubber Duck It</h3><p>Rubber duck debugging is simple but extremely powerful.</p><p>The main idea is that you explain your code line by line to an object (&#129414;), a colleague, or even yourself.</p><p>You describe what you expect to happen at each step.</p><p>The act of explaining forces you to slow down and verify your assumptions.</p><p>There is a big difference in how we think about the code when we read and when we speak loudly about it.</p><p>I&#8217;ve caught the bug many times in the middle of the explanation.</p><h3>7. Form And Test Hypotheses</h3><p>To achieve good results while debugging, you must adopt a more scientific, methodological approach and avoid any random changes.</p><p>Do the following</p><ul><li><p><strong>Form a hypothesis</strong> about the root cause (ex, &#8220;I think the API is returning null when the user has no preferences&#8230;&#8221;).</p></li><li><p><strong>Experiment</strong> to verify it (add logging, set breakpoints, etc).</p></li><li><p><strong>Observe</strong> the result (confirm or reject the hypothesis).</p></li><li><p><strong>Fix</strong> the code based on what you learned.</p></li><li><p><strong>Verify</strong> the fix actually solves the problem.</p></li><li><p><strong>Repeat</strong> the cycle again with a new hypothesis if needed.</p></li></ul><p>This systematic approach prevents you from going in circles and helps you build an understanding of your codebase.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable JS, React, NodeJS, Software Design and Architecture tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Part 3: When You&#8217;re Stuck</h2><h3>8. Document Your Progress</h3><p>When a bug is particularly hard, write down what you&#8217;ve tried.</p><p>Keep a running list of your experiments, hypothesis, and their results.</p><p>This prevents you from doing the same thing twice and expecting different results.</p><p>Documentation also makes it easier for others to help you.</p><p>You can easily ping a colleague, share your progress, and learnings so far.</p><p>You might also consider a tool like <a href="https://trymultiplayer.link/petar-ivanov">Multiplayer</a> to annotate session replays with sketches and comments.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://trymultiplayer.link/petar-trial" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x9Uz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 424w, https://substackcdn.com/image/fetch/$s_!x9Uz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 848w, https://substackcdn.com/image/fetch/$s_!x9Uz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 1272w, https://substackcdn.com/image/fetch/$s_!x9Uz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x9Uz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png" width="1024" height="602" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:602,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:150511,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://trymultiplayer.link/petar-trial&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/177173524?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x9Uz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 424w, https://substackcdn.com/image/fetch/$s_!x9Uz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 848w, https://substackcdn.com/image/fetch/$s_!x9Uz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 1272w, https://substackcdn.com/image/fetch/$s_!x9Uz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34f042ff-60b3-4c79-91c9-48c39d453fa3_1024x602.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>9. Take Strategic Breaks</h3><p>This might sound counterintuitive, but stepping away from your laptop is sometimes the fastest way to solve a bug.</p><p>Taking a 15-minute walk allows your mind to rest and your subconscious to process the problem.</p><p>I can&#8217;t count how many times the solution to a difficult bug popped into my head while taking a walk, being at the toilet, or just making a drink.</p><p>There&#8217;s something about disengaging from the problem that allows your brain to make new connections.</p><h3>10. Leverage AI Smartly</h3><p>AI coding tools can be powerful debugging partners, especially if you give them the right information.</p><p>The right context is the key.</p><p>Try providing as much information about the bug as possible to your AI IDE and see how it could reason about it.</p><p>Of course, it&#8217;s not always correct, but you can quickly test and verify certain hypotheses.</p><p>Then, you could focus on the ones your AI coding tool hasn&#8217;t thought about.</p><p>It&#8217;s also helpful if you could share screenshots or session recordings to provide context.</p><p>I&#8217;ve personally tried <a href="https://trymultiplayer.link/petar-ivanov">Multiplayer&#8217;s</a> integration.</p><p>I&#8217;ve used it to feed my AI assistant with a full-stack session recording, so it can see the full context of a problem.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://trymultiplayer.link/petar-ivanov" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SBQS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 424w, https://substackcdn.com/image/fetch/$s_!SBQS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 848w, https://substackcdn.com/image/fetch/$s_!SBQS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 1272w, https://substackcdn.com/image/fetch/$s_!SBQS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SBQS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png" width="1023" height="604" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:604,&quot;width&quot;:1023,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:246176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://trymultiplayer.link/petar-ivanov&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/177173524?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SBQS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 424w, https://substackcdn.com/image/fetch/$s_!SBQS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 848w, https://substackcdn.com/image/fetch/$s_!SBQS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 1272w, https://substackcdn.com/image/fetch/$s_!SBQS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb03ff1cd-fc87-4271-b1c2-79789f8187ae_1023x604.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>After that, I wrote specific prompts and dug deeper into the problem.</p><blockquote><p><strong>AI is not a magic solution, but it&#8217;s a valuable debugging partner when given complete information.</strong></p></blockquote><div><hr></div><p><a href="https://trymultiplayer.link/petar-ivanov">Multiplayer</a> provides Full Stack Session Recordings.</p><p>Here&#8217;s how it helps with debugging and fixing bugs:</p><ul><li><p>Capture full-stack session recordings.</p></li><li><p>Annotate your replays with sketches and comments.</p></li><li><p>Bring full-stack session recordings directly into your IDE.</p></li><li><p>Give your AI coding tools all the context they need.</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://trymultiplayer.link/petar-trial&quot;,&quot;text&quot;:&quot;Access 1-month Free Trial&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://trymultiplayer.link/petar-trial"><span>Access 1-month Free Trial</span></a></p><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>Reproduce the error consistently.</p></li><li><p>Set up your environment to quickly reproduce the bug.</p></li><li><p>Capture the full context and information.</p></li><li><p>Isolate the problem.</p></li><li><p>Use your debugger.</p></li><li><p>Rubber duck the problem.</p></li><li><p>Form and test hypotheses.</p></li><li><p>Document your progress.</p></li><li><p>Take strategic breaks.</p></li><li><p>Leverage AI smartly.</p></li></ul><p>Hope this was helpful.</p><p>See you next time!</p><p><strong>Today&#8217;s action step:</strong> Take a look at your debugging process and see how you can apply at least one of the mentioned techniques.</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 28.5K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Functional Error Handling in Node.js With The Result Pattern]]></title><description><![CDATA[Learn how to improve your error handling in Node.js by using the Result Pattern. (5 Min)]]></description><link>https://thetshaped.dev/p/functional-error-handling-in-nodejs-with-the-result-pattern</link><guid isPermaLink="false">https://thetshaped.dev/p/functional-error-handling-in-nodejs-with-the-result-pattern</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Tue, 21 Oct 2025 10:19:27 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cd22faee-c7fc-4590-9183-5163d2183c21_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Error handling is a crucial aspect for building robust applications.</p><p>In Node.js, error handling relies on try-catch blocks and exceptions.</p><p>While this is a common way in Node.js apps, it creates an unpredictable control flow and hidden failure points.</p><p>A few years ago, I discovered the Result Pattern approach for handling errors, and it completely changed the way I look at error handling in Node.js applications.</p><p>The Result Pattern approach <strong>makes errors explicit</strong>, type-safe, and part of your function signatures.</p><p>In today&#8217;s article, I&#8217;ll dig deeper into the error handling and how to use the Result Pattern to better manage it.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 28,000+ engineers to receive one practical tip on JS, React, NodeJS, Software Design and Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Problems With Using Exceptions For Flow Control</h2><p>Most Node.js applications rely on exceptions for error handling.</p><p>You throw errors when something goes wrong, and catch them somewhere up the call stack.</p><p>This favors the so-called <strong>fail-fast principle</strong> because you terminate the method execution immediately once you throw an exception.</p><p>With this approach, you make the caller responsible for handling the exception.</p><p>The problem is that the client of the method must know which exceptions to handle, which is not obvious from the method&#8217;s signature.</p><p>This makes exceptions invisible and creates an opportunity for bugs related to improper error handling of these exceptions.</p><p>Code becomes unpredictable since you&#8217;re not sure if the method throws an exception or not.</p><p>Here is a simplified example of creating an order:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fKwc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fKwc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 424w, https://substackcdn.com/image/fetch/$s_!fKwc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 848w, https://substackcdn.com/image/fetch/$s_!fKwc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 1272w, https://substackcdn.com/image/fetch/$s_!fKwc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fKwc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png" width="688" height="431.8901098901099" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:914,&quot;width&quot;:1456,&quot;resizeWidth&quot;:688,&quot;bytes&quot;:362417,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/176553465?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fKwc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 424w, https://substackcdn.com/image/fetch/$s_!fKwc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 848w, https://substackcdn.com/image/fetch/$s_!fKwc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 1272w, https://substackcdn.com/image/fetch/$s_!fKwc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e5d44fc-770e-4873-9df2-d3eed7775c0a_2963x1859.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Use Exceptions For Exceptional Situations</h2><blockquote><p><strong>A good rule of thumb is to use exceptions for unexpected errors and exceptional situations.</strong></p></blockquote><p>You basically have two types of errors:</p><ul><li><p>Errors you know how to handle</p></li><li><p>Errors you don&#8217;t know how to handle</p></li></ul><p>You can use exceptions for the errors you don&#8217;t know how to handle. And you should catch and handle them at the lowest level possible.</p><p>For the errors you know how to handle, you could use the <strong>Result Pattern</strong> and handle the errors in a more functional way.</p><blockquote><p>Make these types of errors explicit since you already know about them.</p></blockquote><p>This way is more explicit and clearly shows that the method can fail.</p><p>The drawback is that the caller of the method has to check whether the operation succeeded or failed.</p><div><hr></div><h2>Using The Result Pattern For Better Error-Handling</h2><p>The Result Pattern makes errors explicit and type-safe.</p><p>Instead of throwing exceptions, methods return a Result object that contains the success data or error information.</p><p>You can think of the Result as a container that holds one of two things:</p><ul><li><p><strong>Success</strong>: Your data is inside.</p></li><li><p><strong>Error </strong>(or Failure): Information about what went wrong. </p></li></ul><p>The key change here is that errors become values, not exceptions.</p><p>You can handle them like any other data in your program.</p><p>Here is an example of what the Result object might look like:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xNuS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xNuS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 424w, https://substackcdn.com/image/fetch/$s_!xNuS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 848w, https://substackcdn.com/image/fetch/$s_!xNuS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 1272w, https://substackcdn.com/image/fetch/$s_!xNuS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xNuS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png" width="598" height="839.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2044,&quot;width&quot;:1456,&quot;resizeWidth&quot;:598,&quot;bytes&quot;:735509,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/176553465?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xNuS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 424w, https://substackcdn.com/image/fetch/$s_!xNuS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 848w, https://substackcdn.com/image/fetch/$s_!xNuS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 1272w, https://substackcdn.com/image/fetch/$s_!xNuS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a3b99bc-693c-4835-9da5-13b3b8fd0a8f_2820x3958.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Applying the Result Pattern</h2><p>Now that we have the <strong>IResult</strong> interface and utility methods, we could refactor the above-mentioned example by switching from using exceptions to the Result Pattern.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MO8C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MO8C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 424w, https://substackcdn.com/image/fetch/$s_!MO8C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 848w, https://substackcdn.com/image/fetch/$s_!MO8C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 1272w, https://substackcdn.com/image/fetch/$s_!MO8C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MO8C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png" width="432" height="748.2857142857143" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2522,&quot;width&quot;:1456,&quot;resizeWidth&quot;:432,&quot;bytes&quot;:596313,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/176553465?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MO8C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 424w, https://substackcdn.com/image/fetch/$s_!MO8C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 848w, https://substackcdn.com/image/fetch/$s_!MO8C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 1272w, https://substackcdn.com/image/fetch/$s_!MO8C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a6b51c-61bf-4f96-a377-f2c4b16bf2d6_1995x3455.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can notice a few things as improvements:</p><ul><li><p>No more throwing exceptions.</p></li><li><p>The return type of the method is explicit - using the <strong>IResult</strong> return type.</p></li><li><p>It is clear what errors the method can return.</p></li></ul><p>Another advantage of using the Result Pattern is that it simplifies the testing. It&#8217;s much easier to mock the Result object than to throw and handle exceptions.</p><p>As we said earlier, one drawback of the Result Pattern is its verbosity, as it might introduce more code compared to exceptions.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable JS, React, NodeJS, Software Design and Architecture tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>Exceptions are for exceptional situations.</p></li><li><p>Use exceptions for errors you don&#8217;t know how to handle.</p></li><li><p>Use the Result Pattern for errors you know how to handle, making the error handling more explicit and obvious.</p></li><li><p>The Result Pattern allows you to handle errors more elegantly in a functional way, express the intent that the method could fail, and encapsulate the error inside.</p></li></ul><p>So try out the Result Pattern and let me know how you found it.</p><p>I promise it will improve your code.</p><p>Hope this was helpful.</p><p>See you next time!</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 28K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Own Your Onboarding: The First 90 Days That Define Your Career 🚀]]></title><description><![CDATA[A practical guide to shipping fast and making an impact from day one. (6 Min)]]></description><link>https://thetshaped.dev/p/own-your-onboarding-the-first-30-60-90-plan-new-company-hiring</link><guid isPermaLink="false">https://thetshaped.dev/p/own-your-onboarding-the-first-30-60-90-plan-new-company-hiring</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Tue, 07 Oct 2025 10:19:32 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a717e639-5861-472e-b3ca-d5ffbd05b6b5_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Starting a new job is challenging.</p><p>You&#8217;re changing your current environment, including your teammates, office, and so on.</p><p>You&#8217;re also not sure how it would impact your career.</p><p>So yes, it&#8217;s a bit nerve-racking.</p><p>Till now, I&#8217;ve changed more than four tech companies, ranging from startups to big tech unicorns.</p><p>I&#8217;ve seen different onboarding plans and ways to kick off your &#8220;first impression&#8221; in your new workplace.</p><p>One of the biggest lessons I&#8217;ve learned for myself is:</p><blockquote><p><strong>Don&#8217;t rely on your company&#8217;s onboarding plan. Create one for yourself!</strong></p></blockquote><p>Regardless of the company's size and seasonality, there are many flaws.</p><p>It&#8217;s hard to create the &#8220;complete&#8221; plan for every new joiner.</p><p>That&#8217;s why it&#8217;s crucial to <strong>take ownership of your onboarding plan</strong>.</p><p>The effort you put in now will pay dividends for months.</p><p>A strong start makes you appear to be someone who cares.</p><p>This sense of ownership shows professionalism.</p><p>In today&#8217;s article, I&#8217;ll share ten lessons I&#8217;ve learned in my career on how to successfully onboard in your new company.</p><p>I also shared and applied these lessons with all the people I managed to onboard as an Onboarding Buddy.</p><p>I saw the work, so that&#8217;s why I&#8217;m sharing these lessons with you.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 28,000+ engineers to receive one practical tip on JS, React, NodeJS, Software Design and Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Before Day 1: Set Yourself Up For Success</h2><p>If you have a long notice period, reach out to your future manager or team before you start.</p><blockquote><p><strong>Ask what you can do to prepare before your first working day.</strong></p></blockquote><p>When I did that at my last company, they sent me a Udemy course on microservices architecture - a core part of their tech stack.</p><p>On Day 1, I showed up already speaking &#8220;their language&#8221;.</p><p>This shows two things: <strong>you actually prepare</strong> and <strong>you signal you are proactive</strong>.</p><p>Also, start a <strong>work log or brag document</strong> from Day 1.</p><p>Write down what you&#8217;re working on, problems you solved, your wins, and impact.</p><p>This becomes invaluable for 1:1s, performance reviews, and promotion discussions.</p><p>You can read more about it <a href="https://thetshaped.dev/p/how-keeping-a-work-log-aka-brag-list-helps-you-get-promoted">here</a>:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;72cbc906-01a6-464e-b9b7-bd7d1148fbae&quot;,&quot;caption&quot;:&quot;Just arriving? Join 20,200+ engineers to receive one practical tip on React, Node, and Software Architecture every week.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;How Keeping a Work Log (aka Brag List) Helps You Get Promoted? &#128200;&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:10269058,&quot;name&quot;:&quot;Petar Ivanov&quot;,&quot;bio&quot;:&quot;Senior Software Engineer | Practical React, Node, and Software Architecture Tips &#128293; | Author of &#8220;The Conscious React&#8221; book &#9883;&#65039;&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b236a7ab-735e-49d2-bbe8-98b1f901b169_500x500.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-03-09T14:57:45.825Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/949119de-ea8f-4505-9707-d9a40a2f3188_1456x1048.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://thetshaped.dev/p/how-keeping-a-work-log-aka-brag-list-helps-you-get-promoted&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:157248792,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:32,&quot;comment_count&quot;:7,&quot;publication_id&quot;:1508738,&quot;publication_name&quot;:&quot;The T-Shaped Dev&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!9lD-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f66bb7c-c96f-4c71-ba2d-d561152c83a2_600x600.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><h2>Week 1-4: Learn Fast, Contribute Faster</h2><h3>Ship Code Early</h3><p>I truly believe in getting your hands dirty immediately.</p><blockquote><p><strong>Aim to ship something in the first week, even in the first few days.</strong></p></blockquote><p>You might fix a bug, add a small feature, improve something in the codebase, or even add a formatting or linting rule.</p><p>I&#8217;ve worked in both frontend and backend, so when I joined my last company, I looked for bugs I could fix in both areas.</p><p>In my first week, I managed to raise the bar high by making an impact by starting to deliver.</p><p>During my first retro, the team said like I&#8217;d been there for months, not days.</p><p>There&#8217;s usually a &#8220;capacity penalty&#8221; when someone new joins.</p><p>You reduce this penalty by contributing quickly.</p><p>Another tip here is to:</p><blockquote><p><strong>Maintain your focus while exploring the codebase.</strong></p></blockquote><p>Don&#8217;t try to understand the entire codebase from the beginning.</p><p>Pick one area and start from there.</p><h3>Start Reviewing Code Immediately</h3><p>You might not understand the business domain yet, but you can still add value.</p><p>You can still share tips and tricks on code reviews related to software design, architecture, and engineering practices, like readability, testing, etc.</p><p>This shows that <strong>you care</strong>.</p><p>You also build your&nbsp;<strong>credibility as an expert</strong>&nbsp;in a particular field.</p><p>As you learn more about the product, you can begin to question requirements and suggest more effective approaches.</p><h3>Ask Questions; Ask Even More</h3><blockquote><p><strong>Your questions reveal what you care about. Ask good ones!</strong></p></blockquote><p>For example:</p><ul><li><p>How do we make money?</p></li><li><p>How do we handle payments?</p></li><li><p>What are our team&#8217;s responsibilities?</p></li><li><p>etc.</p></li></ul><p>Ask your buddy, your mentor, your team, or people outside your team.</p><p>And try not to eat lunch alone.</p><p>I&#8217;m an introvert, so this was hard for me.</p><p>However, I tried to eat at least twice a week with people outside my team.</p><p>This way, I met more smart people, heard different perspectives, and learned about challenges across the company.</p><h3>Align on Expectations</h3><p>On your 1:1s with your manager, sit down and clarify your goals:</p><ul><li><p>What does success look like in my first month?</p></li><li><p>What about the next three months?</p></li><li><p>How to progress further in the career ladder?</p></li></ul><p>Get specific.</p><blockquote><p><strong>Vague goals lead to vague results.</strong></p></blockquote><p>A good starting point is to create your 30-60-90 plan in a document.</p><p>This document maps out a new hire&#8217;s expectations from the perspective of the onboarding Team within the first 90 days of his new role.</p><div><hr></div><h2><strong>&#127873; Notion Template: Work Log (aka Brag List) Template For Software Engineers</strong></h2><p>Use this template to create your own work log (brag list) and list of accomplishments.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://petarivanovv9.gumroad.com/l/eeerf" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3J0Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!3J0Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!3J0Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!3J0Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3J0Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:245895,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://petarivanovv9.gumroad.com/l/eeerf&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/175195823?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3J0Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!3J0Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!3J0Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!3J0Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b639d2b-568b-4800-bdbb-9da5c81cc506_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://petarivanovv9.gumroad.com/l/eeerf&quot;,&quot;text&quot;:&quot;I want this!&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://petarivanovv9.gumroad.com/l/eeerf"><span>I want this!</span></a></p><p>Paid subscribers, you can get it here:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/i/144355834/plan-template-for-software-engineers-in-notion&quot;,&quot;text&quot;:&quot;I want this FREE!&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://thetshaped.dev/i/144355834/plan-template-for-software-engineers-in-notion"><span>I want this FREE!</span></a></p><div><hr></div><h2>Month 2-3: Build Your Network and Increase Impact</h2><h3>Map The Organization</h3><p>This is especially helpful for Senior+ roles.</p><p>The main idea here is to get to know the different teams, their responsibilities, and their core domains.</p><p>Since you&#8217;re new to the company, you have the perfect excuse to message someone from this team and ask what they&#8217;re working on:</p><p><em>&#8220;Hi, I&#8217;m new here, and I heard about your team lately. I&#8217;d love to learn what you work on and how our teams might interact&#8230;&#8221;</em></p><p>This is incredibly easy as a new person, and gets much harder later. Use this window.</p><h3>Understand The Business, Not Just The Code</h3><p>Learning the tech stack is one challenge.</p><p>Understanding the business and product domain is another.</p><p><strong>The best engineers combine technical knowledge with business context.</strong></p><p>If you don&#8217;t understand the product well, you can&#8217;t build the right solution.</p><blockquote><p><strong>If the product doesn&#8217;t work, the code doesn&#8217;t matter.</strong></p></blockquote><p>Talk to product managers and more experienced engineers.</p><p>Try to understand the business.</p><p>And <strong>try to work on high-impact things</strong>.</p><p>This isn&#8217;t always possible&#8212;sometimes you have to fix boring bugs&#8212;but communicate with your manager about your impact.</p><h3>Use Your Fresh Perspective</h3><p>You see things that others have become blind to.</p><p>Something that doesn&#8217;t make sense to you probably doesn&#8217;t make sense at all.</p><p>Others just got used to it.</p><blockquote><p><strong>When you spot something that could be improved, document it.<br>Better yet, fix it yourself if you can.</strong></p></blockquote><p>Seek opportunities to make a positive impact.</p><p>Apply your fresh perspectives not only to the code, but also to the current processes, including onboarding.</p><h3>Accept The Entropy</h3><p>Accept that many things won&#8217;t make sense at first, especially if you&#8217;re going from a small to &#8594; big company.</p><p>This is completely normal.</p><p>Give it time. It gets clearer.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable JS, React, NodeJS, Software Design and Architecture tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>Reach out to your manager before you start. Ask for materials to prepare.</p></li><li><p>Start your brag document from day 1.</p></li><li><p>Contribute code in week 1.</p></li><li><p>Start code reviews immediately.</p></li><li><p>Ask questions.</p></li><li><p>Try to eat lunch with people from different teams.</p></li><li><p>Align on goals with your manager.</p></li><li><p>Map important teams.</p></li><li><p>Learn the business, not just the code.</p></li><li><p>Apply your fresh perspective.</p></li></ul><p>Hope this was helpful.</p><p>See you next time!</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 28K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Ace Your Next JavaScript Interview: Promises, Async/Await, Event Loop (Part 4) ✨ ]]></title><description><![CDATA[Learn the deeper concepts in JavaScript, such as Promises, Async/Await, and Event-Loop (5 min)]]></description><link>https://thetshaped.dev/p/javascript-interview-questions-promises-async-await-event-loop-demystified</link><guid isPermaLink="false">https://thetshaped.dev/p/javascript-interview-questions-promises-async-await-event-loop-demystified</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Wed, 17 Sep 2025 11:19:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c1b51e40-122e-4a15-98e8-da802be52c92_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 27,700+ engineers to receive one practical tip on JavaScript, React, Node.js, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>Some time ago, I had an interview, which I almost failed.</p><p>The interviewer asked me questions like Promises and Event Loop.</p><p>I knew what they were, but I failed to clearly elaborate and explain them.</p><blockquote><p><em>If you can&#8217;t explain it simply, do you understand it really well?</em></p></blockquote><p>After the interview, I understood that some knowledge was missing.</p><p>I decided to dig deeper into JavaScript and fill my understanding and knowledge gaps.</p><p>I read many books and articles and took many notes along the way.</p><p>Every time I have a JavaScript interview, I review my notes to refresh my knowledge and prepare.</p><p>In today&#8217;s article, I&#8217;ll delve deeper into asynchronous programming in JavaScript, covering Promises, Async/Await, and the Event Loop.</p><p>This is part 4 of the &#8220;<strong>Ace Your Next JavaScript Interview</strong>&#8221; series. </p><p>If you missed the previous articles, see the bottom of this post.</p><p>Let&#8217;s dive in!</p><div><hr></div><h2><strong><a href="https://coderabbit.link/WFceYHa">CodeRabbit: Free AI Code Reviews in CLI - Sponsor</a></strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://coderabbit.link/WFceYHa" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NFyN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 424w, https://substackcdn.com/image/fetch/$s_!NFyN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 848w, https://substackcdn.com/image/fetch/$s_!NFyN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 1272w, https://substackcdn.com/image/fetch/$s_!NFyN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NFyN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png" width="1374" height="744" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:744,&quot;width&quot;:1374,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:104221,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://coderabbit.link/WFceYHa&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173012641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NFyN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 424w, https://substackcdn.com/image/fetch/$s_!NFyN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 848w, https://substackcdn.com/image/fetch/$s_!NFyN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 1272w, https://substackcdn.com/image/fetch/$s_!NFyN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d9cfd4f-d9c5-417d-b74e-f98bfd44d13c_1374x744.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://coderabbit.link/WFceYHa">CodeRabbit CLI</a> is an AI code review tool that runs directly in your terminal. It provides intelligent code analysis, catches issues early, and integrates seamlessly with AI coding agents like Claude Code, Codex CLI, Cursor CLI, and Gemini to ensure your code is production-ready before it ships.</p><ul><li><p>Enables pre-commit reviews of both staged and unstaged changes, creating a multi-layered review process.</p></li><li><p>Fits into existing Git workflows. Review uncommitted changes, staged files, specific commits, or entire branches without disrupting your current development process.</p></li><li><p>Reviews specific files, directories, uncommitted changes, staged changes, or entire commits based on your needs.</p></li><li><p>Supports programming languages including JavaScript, TypeScript, and more.</p></li><li><p>Offers free AI code reviews with rate limits so developers can experience senior-level reviews at no cost.</p></li><li><p>Flags hallucinations, code smells, security issues, and performance problems.</p></li><li><p>Supports guidelines for other AI generators, AST Grep rules, and path-based instructions.</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://coderabbit.link/WFceYHa&quot;,&quot;text&quot;:&quot;Get Started Today&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://coderabbit.link/WFceYHa"><span>Get Started Today</span></a></p><div><hr></div><h2>Promises</h2><p>A Promise is an object that allows us to take action when a future event happens.</p><p>It&#8217;s a placeholder for a value that will be available at some point in the future.</p><p>Imagine ordering food at a restaurant&#8212;you get a receipt (Promise) that represents your order, even though your meal is not ready yet.</p><p>Promises have three possible states:</p><ul><li><p><strong>pending</strong> - the operation is still in progress</p></li><li><p><strong>fulfilled</strong> - the operation completed successfully</p></li><li><p><strong>rejected</strong> - the operation failed</p></li></ul><p>Upon creation, the Promise takes a function that will be passed two arguments - a resolution callback and a rejection callback.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!O2g2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!O2g2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 424w, https://substackcdn.com/image/fetch/$s_!O2g2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 848w, https://substackcdn.com/image/fetch/$s_!O2g2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 1272w, https://substackcdn.com/image/fetch/$s_!O2g2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!O2g2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png" width="437" height="247.3131868131868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:824,&quot;width&quot;:1456,&quot;resizeWidth&quot;:437,&quot;bytes&quot;:240597,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173012641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!O2g2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 424w, https://substackcdn.com/image/fetch/$s_!O2g2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 848w, https://substackcdn.com/image/fetch/$s_!O2g2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 1272w, https://substackcdn.com/image/fetch/$s_!O2g2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0a31be2-7209-42c9-ad51-51c38dab1ac8_2246x1271.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Most of the time, you&#8217;ll be consuming Promises rather than creating them.</p><p>The <strong>then()</strong> method is available on the <strong>Promise</strong> object and will run with the value passed to the <strong>resolve()</strong> function.</p><p>The <strong>catch()</strong> method runs if the <strong>reject()</strong> function was called.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OPYS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OPYS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 424w, https://substackcdn.com/image/fetch/$s_!OPYS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 848w, https://substackcdn.com/image/fetch/$s_!OPYS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 1272w, https://substackcdn.com/image/fetch/$s_!OPYS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OPYS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png" width="430" height="211.16071428571428" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:715,&quot;width&quot;:1456,&quot;resizeWidth&quot;:430,&quot;bytes&quot;:192080,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173012641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OPYS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 424w, https://substackcdn.com/image/fetch/$s_!OPYS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 848w, https://substackcdn.com/image/fetch/$s_!OPYS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 1272w, https://substackcdn.com/image/fetch/$s_!OPYS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1938f7b-376a-4b5a-b531-79590945b54a_2246x1103.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>One of the most powerful features of Promises is chaining.</p><p>If a <strong>then()</strong> handler returns another Promise, you can chain additional <strong>then()</strong> calls.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QOHw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QOHw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 424w, https://substackcdn.com/image/fetch/$s_!QOHw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 848w, https://substackcdn.com/image/fetch/$s_!QOHw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 1272w, https://substackcdn.com/image/fetch/$s_!QOHw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QOHw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png" width="469" height="294.41346153846155" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:914,&quot;width&quot;:1456,&quot;resizeWidth&quot;:469,&quot;bytes&quot;:290623,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173012641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QOHw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 424w, https://substackcdn.com/image/fetch/$s_!QOHw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 848w, https://substackcdn.com/image/fetch/$s_!QOHw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 1272w, https://substackcdn.com/image/fetch/$s_!QOHw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F525e279d-a8fb-40cf-810a-258007becdfa_2425x1523.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Async/Await</h2><p>While Promises are powerful, the syntax can become hard to read and follow with complex chains.</p><p>The async/await keywords provide a syntax sugar over the Promises that will make your code read as if it were synchronous.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8_bE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8_bE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 424w, https://substackcdn.com/image/fetch/$s_!8_bE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 848w, https://substackcdn.com/image/fetch/$s_!8_bE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 1272w, https://substackcdn.com/image/fetch/$s_!8_bE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8_bE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png" width="457" height="253.6098901098901" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:457,&quot;bytes&quot;:226563,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173012641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8_bE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 424w, https://substackcdn.com/image/fetch/$s_!8_bE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 848w, https://substackcdn.com/image/fetch/$s_!8_bE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 1272w, https://substackcdn.com/image/fetch/$s_!8_bE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fb92f70-1747-49c7-894a-129df782d472_2139x1187.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There are a few key points about <strong>async/await</strong>:</p><ul><li><p>You can only use <strong>await</strong> inside functions marked with <strong>async</strong>.</p></li><li><p><strong>Async</strong> functions always return a <strong>Promise</strong>.</p></li><li><p>Use <strong>try/catch</strong> blocks for error handling instead of .<strong>catch()</strong>.</p></li><li><p>The code executed asynchronously despite looking synchronous.</p></li></ul><div><hr></div><h2>Event Loop</h2><p>Here is where things get really interesting.</p><p>JavaScript is single-threaded, meaning it can only do one thing at a time.</p><p>So how does it handle asynchronous operations without blocking the entire program?</p><p>The answer is its execution flow, which is based on an event loop.</p><p>On a high level, the engine runs an endless loop that checks if there are tasks waiting for it in a queue.</p><p>If there are, it executes them and continues to wait for more.</p><p>Any code that can&#8217;t run immediately is queued, and the execution continues until it exhausts the call stack.</p><pre><code>setTimeout(() =&gt; {
  console.log('Later');
}, 1000);

console.log('Now');

// Output:
// Now
// Later (after 1 second)</code></pre><p>Even with a zero timeout, the callback still runs after the synchronous code:</p><pre><code>setTimeout(() =&gt; {
  console.log('Later');
}, 0);

console.log('Now');

// Output:
// Now
// Later (after 1 second)</code></pre><p>The Event Loop manages two main areas:</p><ul><li><p><strong>Call Stack</strong> - where your currently executing code lives.</p></li><li><p><strong>Task Queue</strong> - where asynchronous callbacks wait to be executed.</p></li></ul><p>The Event Loop only processes the task queue when the call stack is empty.</p><pre><code>setTimeout(() =&gt; {
  console.log('Later');
}, 0);

// This loop keeps the call stack busy
for (let i = 0; i &lt; 100000; i++) {
  console.log(i);
}

// Output:
// 0
// 1
// 2
// ...
// 99999
// Later</code></pre><p>The loop keeps adding items to the call stack and the event loop never gets a chance to reach the task queue.</p><p>When asynchronous calls are queued using the same method, for example, <strong>setTimeout</strong>, their execution order follows the order in which they were added.</p><pre><code>setTimeout(() =&gt; {
  console.log('Later');
}, 0);

setTimeout(() =&gt; {
  console.log('Even Later');
}, 0)

// Output:
// Later
// Even Later</code></pre><p>But if we queue a <strong>Promise</strong> and a call to <strong>setTimeout</strong>, the <strong>Promise</strong> will be the first to run.</p><pre><code>setTimeout(() =&gt; {
  console.log('Later');
}, 0);

Promise.resolve().then(() =&gt; {
  console.log('Also Later');
});

// Output:
// Also Later
// Later</code></pre><p>This is because promises and timeouts are put on two separate queues that have different priorities:</p><ul><li><p><strong>Macrotask Queue</strong> (aka task queue) - <strong>setTimeout</strong>, <strong>setInterval</strong>, DOM events, etc.</p></li><li><p><strong>Microtask Queue</strong> (aka jobs queue) - <strong>Promise callbacks</strong>, <strong>queueMicrotask()</strong>, etc.</p></li></ul><p>The event loop prioritizes the execution of pending microtasks.</p><p>Then the event loop will handle the next pending macrotask.</p><p>Immediately after every macrotask runs, the event loop will run all pending microtasks before continuing with the macrotasks again.</p><p>Here is a nice visualization I found on the Internet:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UQ3Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 424w, https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 848w, https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 1272w, https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif" width="880" height="495" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:495,&quot;width&quot;:880,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1504612,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173012641?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 424w, https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 848w, https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 1272w, https://substackcdn.com/image/fetch/$s_!UQ3Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde275867-d25c-4dd3-8725-3e5e86b305c9_880x495.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let&#8217;s see one final code example to check your understanding:</p><pre><code>console.log("start");

setTimeout(() =&gt; console.log("timeout"), 0);

Promise.resolve().then(() =&gt; console.log("Promise.resolve"));

new Promise((resolve, reject) =&gt; {
    resolve();
    console.log("executor");
}).then(() =&gt; console.log("promise"));

console.log("synchronous");</code></pre><p>To see the answer, see the comments.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable JavaScript, React, Node.js, and Software Architecture tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>Promises give you a clean way to handle future values and chain async operations.</p></li><li><p>Async/Await is a syntax sugar over Promises, giving you a simple mental model and making your code more readable.</p></li><li><p>The Event Loop is a fundamental aspect of async programming in JavaScript.</p></li><li><p>Event Loop handles async operations efficiently in JavaScript.</p></li></ul><p>Hope this was helpful.</p><p>See you next time!</p><div><hr></div><h2>Ace Your Next JavaScript Interview Series</h2><ol><li><p><a href="https://thetshaped.dev/p/ace-your-next-javascript-interview-scope-hoisting-closures-simplified">Scope, Hoisting, and Closures</a></p></li><li><p><a href="https://thetshaped.dev/p/ace-your-next-javascript-interview-values-references-coercion-equality">Values, References, Coercion, and Equality</a></p></li><li><p><a href="https://thetshaped.dev/p/ace-your-next-javascript-interview-this-new-keywords-prototypes-classes">this, new, Prototypes, and Classes</a></p></li></ol><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 27.7K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[What Is a Modular Monolith And Why You Should Care? 🔥]]></title><description><![CDATA[Learn more about modular monoliths, their benefits, and the challenges with microservices. (6 min)]]></description><link>https://thetshaped.dev/p/what-is-a-modular-monolith-benefits-and-microservices-challenges</link><guid isPermaLink="false">https://thetshaped.dev/p/what-is-a-modular-monolith-benefits-and-microservices-challenges</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Tue, 09 Sep 2025 11:19:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/660ed777-9159-415d-9d85-0732ae775fc4_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 27,700+ engineers to receive one practical tip on JavaScript, React, Node.js, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>Over the last few years, I have managed to work with various software architectures, ranging from monoliths to microservices and their variations.</p><p>Each architecture had its own set of unique challenges, problems, and advantages.</p><p>And there is one architecture that really stood out&#8212;the <strong>Modular Monolith architecture</strong>.</p><p>Modular monoliths blend the simplicity and robustness of traditional monolithic applications with the flexibility and scalability of microservices.</p><p>I&#8217;d say that modular monoliths bring the best of both worlds.</p><p>The modular monolith architecture allows you to work in a unified codebase with clearly defined boundaries and independent modules.</p><p>This way, you can have high development velocity without the complexity of distributed systems.</p><p>In today&#8217;s article, I&#8217;ll share more about modular monolith architecture and why you should know about it.</p><div><hr></div><h2><strong><a href="https://coderabbit.link/petar">CodeRabbit: Free AI Code Reviews in VS Code - Sponsor</a></strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://coderabbit.link/petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_jzt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 424w, https://substackcdn.com/image/fetch/$s_!_jzt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 848w, https://substackcdn.com/image/fetch/$s_!_jzt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 1272w, https://substackcdn.com/image/fetch/$s_!_jzt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_jzt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp" width="1456" height="741" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:741,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83074,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173005271?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_jzt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 424w, https://substackcdn.com/image/fetch/$s_!_jzt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 848w, https://substackcdn.com/image/fetch/$s_!_jzt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 1272w, https://substackcdn.com/image/fetch/$s_!_jzt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cd9ea71-0439-48ac-9acc-d658528484d5_1456x741.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://coderabbit.link/petar">CodeRabbit</a> brings real-time, AI-powered code reviews straight into VS Code, Cursor, and Windsurf. It lets you:</p><ul><li><p>Get contextual feedback on every commit, not just at the PR stage</p></li><li><p>Catch bugs, security flaws, and performance issues as you code</p></li><li><p>Apply AI-driven suggestions instantly to implement code changes</p></li><li><p>Do code reviews in your IDE for free and in your PR for a paid subscription</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;text&quot;:&quot;Install in VS Code for FREE&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://coderabbit.link/petar"><span>Install in VS Code for FREE</span></a></p><div><hr></div><h2>What is a Modular Monolith?</h2><p>A modular monolith is a single deployable application that&#8217;s internally organized into well-defined and loosely-coupled modules.</p><p>The modules are split into logical boundaries, grouping related functionality together.</p><p>These modules communicate through well-defined, public APIs, events, or messages, instead of directly calling each other&#8217;s functionality.</p><p>These approaches promote modularity and separation of concerns, and improve the cohesion of the system.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!izZn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!izZn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 424w, https://substackcdn.com/image/fetch/$s_!izZn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 848w, https://substackcdn.com/image/fetch/$s_!izZn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!izZn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!izZn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png" width="1456" height="739" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:739,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:396697,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173005271?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!izZn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 424w, https://substackcdn.com/image/fetch/$s_!izZn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 848w, https://substackcdn.com/image/fetch/$s_!izZn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 1272w, https://substackcdn.com/image/fetch/$s_!izZn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F57ac305b-7f87-4678-89e7-2fb3c4e997f2_2052x1042.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can think of modular monoliths as a microservices architecture packaged into one deployment unit.</p><p>This way, you get the organizational benefits of the service boundaries without the distributed system overhead.</p><p>Even if you want to scale one of the modules due to high traffic or other factors, you can easily extract the module and deploy it independently.</p><p>Modular monoliths give you this kind of flexibility.</p><div><hr></div><h2>What is a Modular Architecture?</h2><p>To design a modular monolith, we must understand what a modular architecture is.</p><p>The <strong>core principles</strong> of modular architecture include:</p><ul><li><p><strong>Separations of Concerns</strong> - Each module is independent, handling a specific business domain or business capability.</p></li><li><p><strong>Loose Coupling</strong> - Modules depend on interfaces, not implementations.</p></li><li><p><strong>High Cohesion</strong> - Related functionality stays together within modules.</p></li><li><p><strong>Explicit Interfaces</strong> - Clear contracts define how modules interact.</p></li></ul><p>This means that <strong>each module</strong>:</p><ul><li><p>Must be independent.</p></li><li><p>Must provide the required functionality.</p></li><li><p>Must expose a well-defined interface to other modules.</p></li></ul><p>The end goal is not to have 100% independent modules because this would mean that modules are not integrated together.</p><p>The main idea is to have <strong>loosely coupled modules</strong> and <strong>keep the number of dependencies low</strong>.</p><p>We can use a few techniques to keep the modules independent, like data isolation and linting rules, for example.</p><p>If we see that two modules communicate too much with each other, you might have incorrectly defined boundaries.</p><p>Then, you could consider merging the two modules together.</p><p>Remember:</p><blockquote><p><strong>A module is a grouping of related functionalities together that are accessed through a well-defined interface.</strong></p></blockquote><p>And once you have a modular architecture, you can easily extract modules into separate services.</p><div><hr></div><h2>Start With a Modular Monolith</h2><p>In recent years, developers have favored the microservices architecture.</p><p>Yes, it provides many benefits like better scalability, clear service boundaries, independence, and much more.</p><p>But, it does come with a big cost - complexity.</p><p>I&#8217;d say that most teams and companies would be better off starting with a monolith application.</p><p>As <a href="https://martinfowler.com/bliki/MonolithFirst.html">Martin Fowler</a> says:</p><blockquote><p><strong>You shouldn't start a new project with microservices, even if you're sure your application will be big enough to make it worthwhile.</strong></p></blockquote><p>And even better, consider starting with a modular monolith.</p><p>When you&#8217;re building a new system, you&#8217;re making countless architectural decisions with incomplete information.</p><p>You don&#8217;t fully understand your users patterns, scaling needs, domain boundaries, etc.</p><p>Starting with microservices in these early days will lock you into these often incorrect assumptions.</p><p>Even big players like Shopify and Google bet on modular monoliths.</p><p>You can read this paper from Google about &#8220;<a href="https://dl.acm.org/doi/pdf/10.1145/3593856.3595909">Towards Modern Development of Cloud Applications</a>&#8221;.</p><p>In this paper, Goggle identifies five <strong>main challenges with microservices</strong>:</p><ul><li><p><strong>Performance</strong> - Sending data between services over the network slows everything down, especially when you split your app into too many pieces.</p></li><li><p><strong>Correctness</strong> - Most big failures happen when different versions of services try to talk to each other and mess up.</p></li><li><p><strong>Management</strong> - Have to manage multiple different applications, each with its release schedule.</p></li><li><p><strong>Frozen APIs</strong> - Once you create an API between services, it&#8217;s really hard to change it without breaking everything else.</p></li><li><p><strong>Development Velocity</strong> - When you need to make changes across multiple services, you can&#8217;t just deploy them all at once - you have to coordinate carefully.</p></li></ul><p>As you see, the cost of starting with microservices is high.</p><p>So starting with a modular monolith sounds compelling.</p><p>I also recommend reading about the <a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing">fallacies of distributed computing</a> if you&#8217;re unfamiliar with them.</p><p>Remember:</p><blockquote><p><strong>You can easily migrate from a modular monolith architecture to a microservices architecture because each module is well defined, isolated, and separated.</strong></p></blockquote><div><hr></div><h2>Benefits of a Modular Monolith</h2><p>Modular monoliths have multiple benefits.</p><p>Here are the ones I consider the most important:</p><ul><li><p><strong>Simplified deployment</strong> - You build, test, and deploy one application instead of multiple services across different environments.</p></li><li><p><strong>Improved performance</strong> - Communication between modules happens through fast in-memory calls, instead of slow network requests.</p></li><li><p><strong>Enhanced development velocity</strong> - You have a single codebase to manage which simplifies the debugging and the overall development process.</p></li><li><p><strong>Easier transaction management</strong> - Managing transactions in a distributed systems is very challenging. With modular monoliths you use a single database and transactions are much simpler.</p></li><li><p><strong>Lower operational complexity</strong> - Modular monoliths reduce the operational overhead that comes with managing and deploying a distributed microservice system.</p></li><li><p><strong>Easier transition to microservices</strong> - Well-defined module boundaries make it straightforward to extract individual services and use microservices.</p></li></ul><div><hr></div><h2>Monolith vs. Modular Monolith vs. Microservices</h2><p>The biggest difference between modular monoliths and microservices is how they&#8217;re deployed.</p><p>Microservices use physical boundaries between services, while modular monoliths use logical boundaries.</p><p>With microservices, you have a clear strategy for modularity and structuring bounded contexts.</p><p>But, you can achieve this without building a distributed system.</p><p>The main problem is when people try to enforce code boundaries using microservices.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZJpO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZJpO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 424w, https://substackcdn.com/image/fetch/$s_!ZJpO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 848w, https://substackcdn.com/image/fetch/$s_!ZJpO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 1272w, https://substackcdn.com/image/fetch/$s_!ZJpO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZJpO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png" width="1456" height="824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:824,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:432632,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/173005271?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZJpO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 424w, https://substackcdn.com/image/fetch/$s_!ZJpO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 848w, https://substackcdn.com/image/fetch/$s_!ZJpO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 1272w, https://substackcdn.com/image/fetch/$s_!ZJpO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fac4bc53c-0ea5-46f2-8206-3248b72a6d3f_3260x1844.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Instead, you can build a modular monolith to get almost the same benefits.</p><p>Modular monoliths give you high cohesion, low coupling, data encapsulation, focus on business functionalities, and more.</p><p>Microservices also give you independent deployments, independent scalability, and the ability to use a different tech stack per service.</p><p>You can think of the difference as a well-organized apartment (modular monolith) vs. a neighborhood of separate houses (microservices) - both have clear boundaries, but one is much simpler to maintain.</p><blockquote><p><strong>Choose microservices for the benefits, not because your monolithic codebase is a mess.</strong> <br>&#8212; <a href="https://x.com/simonbrown">Simon Brown</a></p></blockquote><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable JavaScript, React, Node.js, and Software Architecture tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>Modular monoliths offer a compelling way to structure applications.</p></li><li><p>Modular monoliths offer most of the benefits of microservices without the complexity of distributed systems.</p></li><li><p>Modular monoliths offer a smooth way to transition to microservices if needed.</p></li><li><p>The main difference between microservices and modular monoliths is how they are deployed.</p></li></ul><p>Hope this was helpful.</p><p>See you next week!</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 27.7K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Code Review Guidelines ✅]]></title><description><![CDATA[What Authors and Reviewers Should Actually Do? (5 min)]]></description><link>https://thetshaped.dev/p/code-review-guidelines-for-authors-and-reviewers-quality-code-reviews</link><guid isPermaLink="false">https://thetshaped.dev/p/code-review-guidelines-for-authors-and-reviewers-quality-code-reviews</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Tue, 02 Sep 2025 11:19:21 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/162d978b-6e6a-4dfe-94ef-1c9872b3644d_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 27,595+ engineers to receive one practical tip on JavaScript, React, Node, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>Code review is a process that allows others to review your code changes.</p><p>The person who submits the code changes is referred to as the &#8220;Author&#8221;, while those reviewing the changes are referred to as &#8220;Reviewers&#8221;.</p><p>The primary <strong>purpose</strong> of code reviews is to:</p><blockquote><p>Enhance the <strong>quality of the released solution</strong>&nbsp;and improve <strong>collaboration</strong> and <strong>knowledge transfer</strong> within the team.</p></blockquote><p>However, doing code reviews right is not an easy task.</p><p>There are many&nbsp;<strong>problems</strong>&nbsp;related to&nbsp;<strong>code reviews</strong>, like wasted human effort and time, wrong focus &#8594; wrong results, communication breakdown, criticism, decreased developer productivity, and team velocity.</p><p>In today&#8217;s article, I&#8217;d like to share several code review guidelines, both for Authors and Reviewers, that I've seen working in teams and companies.</p><p>Let&#8217;s dive in!</p><div><hr></div><h2>The Hidden Cost of Broken Code Reviews</h2><ol><li><p><strong>Reviews Become Time Sinks</strong></p></li></ol><ul><li><p>The average PR takes 2-4 days from submission to merge.</p></li><li><p>Teams spend 8-12 hours per week on code reviews instead of building features.</p></li></ul><ol start="2"><li><p><strong>Wrong Focus &#8594; Wrong Results</strong></p></li></ol><ul><li><p>Developers spend 50% of review time on formatting, naming conventions, and style preferences.</p></li><li><p>Meanwhile, logic bugs, security vulnerabilities, and performance issues slide past because reviewers are mentally exhausted from nitpicking.</p></li></ul><ol start="3"><li><p><strong>Communication Breakdown</strong></p></li></ol><ul><li><p>Authors write vague PR descriptions.</p></li><li><p>Reviewers give unclear feedback and/or criticize the author.</p></li><li><p>Nobody knows if an issue is critical or optional.</p></li><li><p>Simple fixes turn into multi-day discussions.</p></li><li><p>The cost isn&#8217;t just velocity&#8212;it&#8217;s team morale, code quality, and customer trust when bugs reach production. </p></li></ul><div><hr></div><p>Code reviews are expensive since there are many people involved in this activity.</p><p>That&#8217;s why I&#8217;m happy to partner with <strong><a href="https://coderabbit.link/petar">CodeRabbit</a></strong> on this newsletter.</p><p>With the help of&nbsp;<a href="https://coderabbit.link/petar">CodeRabbit</a>, I believe we can make them cheaper by automating the process, fixing the obvious problems, and focusing on the right things.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;text&quot;:&quot;Try CodeRabbit&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://coderabbit.link/petar"><span>Try CodeRabbit</span></a></p><div><hr></div><h2>Best Practices for Authors:</h2><ul><li><p><strong>Review your own code changes and PR first</strong> before sharing with others.</p><ul><li><p>Remove debug statements and commented code.</p></li><li><p>Check for obvious bugs or typos.</p></li><li><p>Consider using <a href="https://coderabbit.link/petar">CodeRabbit</a> for giving instant feedback.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://coderabbit.link/petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RLFG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 424w, https://substackcdn.com/image/fetch/$s_!RLFG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 848w, https://substackcdn.com/image/fetch/$s_!RLFG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 1272w, https://substackcdn.com/image/fetch/$s_!RLFG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RLFG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp" width="1456" height="741" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:741,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83074,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/172230453?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RLFG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 424w, https://substackcdn.com/image/fetch/$s_!RLFG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 848w, https://substackcdn.com/image/fetch/$s_!RLFG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 1272w, https://substackcdn.com/image/fetch/$s_!RLFG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7744e25-84b1-41ba-b58c-e6f028d70429_1456x741.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ul></li><li><p><strong>Ensure consistent naming and formatting.</strong></p><ul><li><p>Especially if your company follows a style guide.</p></li></ul></li><li><p><strong>Test your code changes.</strong></p><ul><li><p>Both manually and with automated tests.</p></li></ul></li><li><p><strong>Know what each new line does.</strong></p><ul><li><p>This is very crucial in the era of vibe coding.</p></li></ul></li><li><p><strong>Automate the easy stuff.</strong></p><ul><li><p>Add formatters, linters, and rules to prevent nitpicking.</p></li><li><p>Consider using <a href="https://coderabbit.link/petar">CodeRabbit</a> for finding potential issues.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://coderabbit.link/petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mUm7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 424w, https://substackcdn.com/image/fetch/$s_!mUm7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 848w, https://substackcdn.com/image/fetch/$s_!mUm7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 1272w, https://substackcdn.com/image/fetch/$s_!mUm7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mUm7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp" width="540" height="409.0796703296703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1103,&quot;width&quot;:1456,&quot;resizeWidth&quot;:540,&quot;bytes&quot;:112896,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/172230453?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mUm7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 424w, https://substackcdn.com/image/fetch/$s_!mUm7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 848w, https://substackcdn.com/image/fetch/$s_!mUm7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 1272w, https://substackcdn.com/image/fetch/$s_!mUm7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff458a44e-50a1-4ce3-ad47-24a1e9972385_1456x1103.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ul></li></ul><ul><li><p><strong>Keep your code changes and PR small.</strong></p><ul><li><p>Research shows that review quality drops dramatically with the increasing number of files, lines, and changes. Ex: 400+ lines.</p></li><li><p>If your feature needs more code, <strong>break it into logical steps</strong> that can be reviewed independently.</p></li></ul></li><li><p><strong>Write a clear PR description. </strong>Try to answer the questions:</p><ul><li><p><strong>What</strong> - &#8220;Add rate limiting to login endpoint...&#8221;</p></li><li><p><strong>Why</strong> - &#8220;Prevent brute force attacks&#8230;&#8221;</p></li><li><p><strong>How</strong> - &#8220;Implement rate limiting algorithms, block IPs&#8230;&#8221;</p></li><li><p><strong>Testing</strong> - &#8220;Tested with 100 concurrent requests and verified&#8230;&#8221;</p></li><li><p>For visual changes, include relevant <strong>screenshots and/or videos</strong> that showcase the changes.</p></li><li><p>For bug fixes, outline the <strong>Before and After behaviors</strong>, and how you fixed them.</p></li><li><p>Consider using <a href="https://coderabbit.link/petar">CodeRabbit</a> for generating a summary of the changes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qJyW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qJyW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 424w, https://substackcdn.com/image/fetch/$s_!qJyW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 848w, https://substackcdn.com/image/fetch/$s_!qJyW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 1272w, https://substackcdn.com/image/fetch/$s_!qJyW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qJyW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp" width="562" height="464.7307692307692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1204,&quot;width&quot;:1456,&quot;resizeWidth&quot;:562,&quot;bytes&quot;:94848,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/172230453?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qJyW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 424w, https://substackcdn.com/image/fetch/$s_!qJyW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 848w, https://substackcdn.com/image/fetch/$s_!qJyW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 1272w, https://substackcdn.com/image/fetch/$s_!qJyW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5cb6ed6f-d8e7-42fd-90f5-918f5888f80d_1456x1204.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ul></li><li><p><strong>Document the non-obvious changes.</strong></p><ul><li><p>Try to answer questions with the code itself.</p></li></ul></li><li><p><strong>Respond graciously to critiques.</strong></p><ul><li><p>Remember, it&#8217;s not about you, it&#8217;s about the code.</p></li></ul></li><li><p><strong>If you&#8217;re confused, ask clarifying questions.</strong></p><ul><li><p>Don&#8217;t guess, ask questions instead.</p></li><li><p>Ex:&nbsp;<em>"When you say 'this could be cleaner, ' do you mean splitting this function or renaming the variables?"</em></p></li></ul></li><li><p><strong>Be patient when your reviewer is wrong.</strong></p><ul><li><p>Reviewers might be wrong due to a lack of context or experience, so try to provide it and help them understand your perspective.</p></li></ul></li><li><p><strong>Minimize the lag between rounds of review.</strong></p><ul><li><p>Acknowledge feedback within 4 hours, even if you can&#8217;t fix everything immediately.</p></li><li><p>Quick responses show respect for your reviewer&#8217;s time.</p></li></ul></li><li><p><strong>Consider doing a pair programming session with the reviewer if needed.</strong></p><ul><li><p>Peer code reviews work as a two-way transfer of knowledge when conducted carefully.</p></li><li><p>Both the reviewer and the author can learn new things, either for the project or in general.</p></li></ul></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable Software Engineering and JavaScript-related tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Best Practices for Reviewers:</h2><ul><li><p><strong>Review PRs within 24 hours of submission.</strong></p><ul><li><p>This not only unblocks the author to merge their code but also speeds up the development process.</p></li></ul></li><li><p><strong>Prioritize your review using this framework:</strong></p><ul><li><p><strong>Correctness:</strong> Does the code work as intended?</p></li><li><p><strong>Organization:</strong> Is it well-structured, maintainable, and follows the style guides?</p></li><li><p><strong>Readability:</strong> Can the team and future me understand and modify this later?</p></li><li><p><strong>Reliability:</strong> Is the solution fault-tolerant?</p></li><li><p><strong>Scalability:</strong> Can the solution grow to accommodate higher future load?</p></li><li><p><strong>Edge cases:</strong> What could go wrong in production?</p></li></ul></li><li><p><strong>Prioritize your feedback:</strong></p><ul><li><p><strong>Critical (must fix)</strong>&nbsp;- logic errors and bugs; security vulnerabilities; breaking changes; performance bottlenecks.</p></li><li><p><strong>Important (should fix)</strong> - poor code organization; missing error handling; inadequate tests.</p></li><li><p><strong>Suggestions (optional)</strong> - alternative implementations; style improvements; minor optimizations.</p></li></ul></li><li><p><strong>Don&#8217;t make it personal! Review the code, not the author.</strong></p></li><li><p><strong>Learn to give better feedback. Ask, don&#8217;t tell!</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://www.linkedin.com/posts/petarivanovv9_if-you-want-to-learn-how-to-do-better-code-activity-7366427956782542848-Wr_q" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fMA0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 424w, https://substackcdn.com/image/fetch/$s_!fMA0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 848w, https://substackcdn.com/image/fetch/$s_!fMA0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 1272w, https://substackcdn.com/image/fetch/$s_!fMA0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fMA0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png" width="444" height="589.6256684491979" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1490,&quot;width&quot;:1122,&quot;resizeWidth&quot;:444,&quot;bytes&quot;:1030504,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://www.linkedin.com/posts/petarivanovv9_if-you-want-to-learn-how-to-do-better-code-activity-7366427956782542848-Wr_q&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/172230453?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fMA0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 424w, https://substackcdn.com/image/fetch/$s_!fMA0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 848w, https://substackcdn.com/image/fetch/$s_!fMA0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 1272w, https://substackcdn.com/image/fetch/$s_!fMA0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8a0129a-3f83-4b24-8a8c-a8b58c406487_1122x1490.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>When you add a comment, have a strong WHY and a suggestion.</p></li><li><p>Mark more comments as NIT and don&#8217;t block PRs.</p></li></ul></li><li><p><strong>Praise the good things.</strong></p><ul><li><p>Engineers, and people in general, tend to criticize when doing any kind of review, while forgetting to mention any good.</p></li><li><p>For the reviewer to be able to learn from the author, he should pay attention to the clever code as well, and it is a good habit to notice it.</p></li></ul></li><li><p><strong>Consider doing a pair programming session with the reviewer if needed.</strong></p><ul><li><p>Sometimes, it&#8217;s better to sit together and resolve all issues instead of going through multiple rounds of reviews.</p></li></ul></li><li><p><strong>When critical issues are resolved and code is &#8220;good enough&#8221;</strong> &#8594; <strong>Approve it</strong>.</p></li><li><p><strong>Code review is part of your job.</strong></p><ul><li><p>If you're not doing code reviews regularly, you are letting your teammates down.</p></li></ul></li></ul><div><hr></div><p><strong><a href="https://coderabbit.link/petar">CodeRabbit</a></strong> is an AI code review tool to reduce developer workload.</p><p>Here&#8217;s how it helps with code review flow:</p><ul><li><p>Do routine checks and reduce the time spent on reviews from days to minutes. Thus, improving developer velocity.</p></li><li><p>Do consistent reviews without getting tired or biased. Thus, it reduces the risk of missing important issues due to human mistakes.</p></li><li><p>Provide mentorship to junior engineers through detailed feedback.</p></li></ul><p>Put simply, <a href="https://coderabbit.link/petar">CodeRabbit</a> complements human reviewers. It serves 1+ million repositories and has reviewed over 10 million pull requests. And it remains the most installed app on GitHub and GitLab.</p><div><hr></div><h2>&#128204; TL;DR</h2><ul><li><p><strong><a href="https://thetshaped.dev/i/172230453/best-practices-for-authors">Guidelines for Authors:</a></strong></p><ul><li><p>Review your own code changes and PR first.</p></li><li><p>Ensure consistent naming and formatting.</p></li><li><p>Test your code changes.</p></li><li><p>Know what each new line does.</p></li><li><p>Automate the easy stuff.</p></li><li><p>Keep your code changes and PR small.</p></li><li><p>Write a clear PR description.</p></li><li><p>Document the non-obvious changes.</p></li><li><p>Respond graciously to critiques.</p></li><li><p>If you&#8217;re confused, ask clarifying questions.</p></li><li><p>Be patient when your reviewer is wrong.</p></li><li><p>Minimize the lag between rounds of review.</p></li></ul></li><li><p><strong><a href="https://thetshaped.dev/i/172230453/best-practices-for-reviewers">Guidelines for Reviewers:</a></strong></p><ul><li><p>Review PRs within 24 hours of submission.</p></li><li><p>Prioritize your review using a framework and quality attributes.</p></li><li><p>Prioritize your feedback.</p></li><li><p>Don&#8217;t make it personal! Review the code, not the author.</p></li><li><p>Learn to give better feedback. Ask, don&#8217;t tell!</p></li><li><p>Praise the good things.</p></li><li><p>When critical issues are resolved and code is &#8220;good enough&#8221; &#8594; Approve it.</p></li><li><p>Core reviews are part of your job.</p></li></ul></li></ul><p>Hope this was helpful.</p><p>See you next week!</p><p><strong>Today&#8217;s action step:</strong> Take a look at your code review process and highlight areas for improvement. Try to follow or incorporate one of the mentioned tips in your daily routine.</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 27.5K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Clean Code: 8 Tips to Write Clean Functions 🔥]]></title><description><![CDATA[Learn about eight practical tips on writing clean functions. (5 min)]]></description><link>https://thetshaped.dev/p/clean-code-8-practical-tips-to-write-clean-functions</link><guid isPermaLink="false">https://thetshaped.dev/p/clean-code-8-practical-tips-to-write-clean-functions</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Tue, 26 Aug 2025 11:19:32 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2ec4ef91-d637-4f28-b186-0ec93dc6b382_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 27,471+ engineers to receive one practical tip on JavaScript, React, Node, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p><strong>Clean Code</strong> is code that is easy to read, maintain, test, and understand.</p><p><strong>Clean Functions</strong> are the foundation of <strong>Clean Code</strong>.</p><p>Master clean functions and you&#8217;ll naturally write better software.</p><p>In today&#8217;s article, I&#8217;ll share 8 practical tips for writing clean functions that I follow daily in my projects and work.</p><p>Let&#8217;s dive in!</p><div><hr></div><h2><a href="https://coderabbit.link/petar">Cut Code Review Time &amp; Bugs in Half - Sponsor</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://coderabbit.link/petar" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eJXF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!eJXF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!eJXF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!eJXF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eJXF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:199568,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eJXF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!eJXF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!eJXF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!eJXF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ded051-9bf0-4732-8b76-f1bb9151bcda_1600x800.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://coderabbit.link/petar">CodeRabbit</a> is your AI-powered code review co-pilot.</p><p>It provides instant, contextual feedback on every PR, along with one-click fix suggestions. It has reviewed over 10 million PRs and is used in 1 million repositories.</p><p>Besides, it&#8217;s free to use for open-source repos; 70K+ open-source projects already use it.</p><p><a href="https://coderabbit.link/petar">CodeRabbit</a> lets you instantly spot:</p><ul><li><p>Logic &amp; syntax bugs</p></li><li><p>Security issues (XSS, SQL injection, CSRF)</p></li><li><p>Concurrency problems (deadlocks, race conditions)</p></li><li><p>Code smells &amp; readability concerns</p></li><li><p>Best practice violations (SOLID, DRY, KISS)</p></li><li><p>Weak test coverage &amp; performance bottlenecks</p></li></ul><p>Write clean, secure, and performant code with <a href="https://coderabbit.link/petar">CodeRabbit</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;text&quot;:&quot;Try CodeRabbit Now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://coderabbit.link/petar"><span>Try CodeRabbit Now</span></a></p><div><hr></div><h2>#1: Keep Your Functions Small And Focused</h2><p>Functions that do multiple things are hard to follow, understand, test, debug, and even reuse.</p><p>When something breaks, it&#8217;s very hard to pinpoint the exact part that failed.</p><p>When requirements change, and they do change regularly, you risk breaking the whole function and unrelated functionality.</p><p>In the <a href="https://www.goodreads.com/book/show/3735293-clean-code">Clean Code</a> book, Uncle Bob says:</p><blockquote><p><em>The first rule of functions is that they should be small.<br>The second rule of functions is that they should be smaller than that.</em></p></blockquote><p>So each function should have <strong>one clear responsibility</strong>.</p><p>Sometimes a function might be just 5 lines of code, while other times it might be 50 lines of code to fulfill a single responsibility.</p><p>If you can describe what your function does with &#8220;and&#8221;, it probably does too much.</p><p>There&#8217;s no universal rule to draw the line.</p><p>Trust your experience and your judgment based on the context you have.</p><blockquote><p><strong>Be pragmatic. Don&#8217;t be dogmatic.</strong></p></blockquote><div><hr></div><h2>#2: Name Functions to Reveal Intent</h2><p>Function names like <em>process()</em> or <em>handle()</em> force readers to examine the implementation to understand what the function does.</p><p>This slows down code reading and increases the cognitive load.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AyAv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AyAv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 424w, https://substackcdn.com/image/fetch/$s_!AyAv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 848w, https://substackcdn.com/image/fetch/$s_!AyAv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 1272w, https://substackcdn.com/image/fetch/$s_!AyAv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AyAv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png" width="428" height="305.7142857142857" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1040,&quot;width&quot;:1456,&quot;resizeWidth&quot;:428,&quot;bytes&quot;:181611,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AyAv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 424w, https://substackcdn.com/image/fetch/$s_!AyAv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 848w, https://substackcdn.com/image/fetch/$s_!AyAv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 1272w, https://substackcdn.com/image/fetch/$s_!AyAv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32e978c8-0bac-4cfe-8f1a-ad38278a276c_1780x1271.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Function names should clearly state what they do with action verbs.</p><p>A good function name should answer:<br><em>&#8220;<strong>What action does this perform?</strong>&#8221;</em> and <em>&#8220;<strong>What does it return?</strong>&#8221;</em></p><p>You can also follow these tips:</p><ul><li><p><strong>Use terms and language based on the specific domain</strong>, so your functions are more tailored to the business context.</p></li><li><p>Follow the already established <strong>naming conventions.</strong></p></li><li><p><strong>Use verbs and verb phrases for actions</strong> (<em>calculate</em>, <em>validate</em>, <em>send</em>).</p></li><li><p>Use <strong>question words for boolean functions</strong> (<em>is</em>, <em>has</em>, <em>can</em>).</p></li><li><p><strong>Be consistent</strong> with the naming, so you don&#8217;t use two words for the same thing.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tw8z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tw8z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 424w, https://substackcdn.com/image/fetch/$s_!tw8z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 848w, https://substackcdn.com/image/fetch/$s_!tw8z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 1272w, https://substackcdn.com/image/fetch/$s_!tw8z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tw8z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png" width="613" height="342.2864010989011" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:1456,&quot;resizeWidth&quot;:613,&quot;bytes&quot;:283364,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tw8z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 424w, https://substackcdn.com/image/fetch/$s_!tw8z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 848w, https://substackcdn.com/image/fetch/$s_!tw8z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 1272w, https://substackcdn.com/image/fetch/$s_!tw8z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee6d5a86-6acf-4ecd-a061-b31b885b3f09_2426x1355.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>#3: Return Early to Avoid Nesting</h2><p>Deeply nested functions create a &#8220;pyramid of doom&#8221;, which is hard to follow, debug, and understand.</p><p>Your brain has to track multiple logical branches simultaneously.</p><p>The main business logic gets &#8220;hidden&#8221;, making it hard to find.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KDV6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KDV6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 424w, https://substackcdn.com/image/fetch/$s_!KDV6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 848w, https://substackcdn.com/image/fetch/$s_!KDV6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 1272w, https://substackcdn.com/image/fetch/$s_!KDV6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KDV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png" width="480" height="337.9120879120879" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1025,&quot;width&quot;:1456,&quot;resizeWidth&quot;:480,&quot;bytes&quot;:248576,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KDV6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 424w, https://substackcdn.com/image/fetch/$s_!KDV6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 848w, https://substackcdn.com/image/fetch/$s_!KDV6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 1272w, https://substackcdn.com/image/fetch/$s_!KDV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd29dc29-d07a-49cb-9b2d-61932abaf32f_2282x1607.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>To fix this, you can use the early return principle.</p><p>You can handle edge cases and invalid inputs using guard clauses.</p><p>This removes the many levels of branches, keeping the &#8220;happy path&#8221; obvious, clear, and easy to follow.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4OZT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4OZT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 424w, https://substackcdn.com/image/fetch/$s_!4OZT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 848w, https://substackcdn.com/image/fetch/$s_!4OZT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 1272w, https://substackcdn.com/image/fetch/$s_!4OZT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4OZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png" width="444" height="417.4697802197802" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1369,&quot;width&quot;:1456,&quot;resizeWidth&quot;:444,&quot;bytes&quot;:247953,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4OZT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 424w, https://substackcdn.com/image/fetch/$s_!4OZT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 848w, https://substackcdn.com/image/fetch/$s_!4OZT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 1272w, https://substackcdn.com/image/fetch/$s_!4OZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F698cc6bd-dd6b-4650-9c43-51e7d5f8d2cb_2067x1943.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>#4: Limit Function Parameters</h2><p>Functions with many parameters are a cognitive load.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-U7F!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-U7F!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 424w, https://substackcdn.com/image/fetch/$s_!-U7F!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 848w, https://substackcdn.com/image/fetch/$s_!-U7F!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 1272w, https://substackcdn.com/image/fetch/$s_!-U7F!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-U7F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png" width="204" height="273.9230769230769" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1187,&quot;width&quot;:884,&quot;resizeWidth&quot;:204,&quot;bytes&quot;:114609,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-U7F!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 424w, https://substackcdn.com/image/fetch/$s_!-U7F!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 848w, https://substackcdn.com/image/fetch/$s_!-U7F!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 1272w, https://substackcdn.com/image/fetch/$s_!-U7F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F121dc9b4-127f-43ba-9390-f91ca5ebd457_884x1187.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can&#8217;t remember parameter order, and it&#8217;s easy to pass the wrong values.</p><p>To improve this, group related parameters into objects.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uBZZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uBZZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 424w, https://substackcdn.com/image/fetch/$s_!uBZZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 848w, https://substackcdn.com/image/fetch/$s_!uBZZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 1272w, https://substackcdn.com/image/fetch/$s_!uBZZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uBZZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png" width="385" height="292.9807692307692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1108,&quot;width&quot;:1456,&quot;resizeWidth&quot;:385,&quot;bytes&quot;:176507,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uBZZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 424w, https://substackcdn.com/image/fetch/$s_!uBZZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 848w, https://substackcdn.com/image/fetch/$s_!uBZZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 1272w, https://substackcdn.com/image/fetch/$s_!uBZZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b8bc463-5437-483b-ac6d-6b0b3e501e55_1780x1355.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This reduces cognitive load and makes parameter order irrelevant.</p><div><hr></div><h2>#5: Write Pure Functions When Possible</h2><p>Functions with side effects are unpredictable.</p><p>They might work differently based on a global state, making them hard to test and debug.</p><p>You can&#8217;t reason about them in isolation.</p><p>They also cause mysterious bugs in unrelated parts of the system.</p><p>To mitigate this problem, strive to write functions that depend only on their inputs and produce no side effects.</p><p>Pure functions are predictable, testable, and can be safely called from anywhere.</p><p>And we can also run them in parallel.</p><div><hr></div><h2>#6: Avoid Boolean Parameters</h2><p>Boolean parameters make function calls unclear and hard to extend.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hoZl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hoZl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 424w, https://substackcdn.com/image/fetch/$s_!hoZl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 848w, https://substackcdn.com/image/fetch/$s_!hoZl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 1272w, https://substackcdn.com/image/fetch/$s_!hoZl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hoZl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png" width="480" height="262.0879120879121" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:795,&quot;width&quot;:1456,&quot;resizeWidth&quot;:480,&quot;bytes&quot;:218280,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hoZl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 424w, https://substackcdn.com/image/fetch/$s_!hoZl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 848w, https://substackcdn.com/image/fetch/$s_!hoZl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 1272w, https://substackcdn.com/image/fetch/$s_!hoZl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20bd4ca1-0cea-4ff7-9238-9a31627eb773_2175x1187.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When you see <em>processOrder(order, true)</em>, you can&#8217;t tell what <em>true</em> means without checking the function definition.</p><p>Boolean flags also often indicate that a function is doing two different things.</p><p>A better approach is to use objects, enums, or separate functions instead of single boolean flags.</p><p>This makes your code self-documenting and easier to extend.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uQ2w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uQ2w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 424w, https://substackcdn.com/image/fetch/$s_!uQ2w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 848w, https://substackcdn.com/image/fetch/$s_!uQ2w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 1272w, https://substackcdn.com/image/fetch/$s_!uQ2w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uQ2w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png" width="542" height="346.93956043956047" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:932,&quot;width&quot;:1456,&quot;resizeWidth&quot;:542,&quot;bytes&quot;:361552,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uQ2w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 424w, https://substackcdn.com/image/fetch/$s_!uQ2w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 848w, https://substackcdn.com/image/fetch/$s_!uQ2w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 1272w, https://substackcdn.com/image/fetch/$s_!uQ2w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6df1a66-37d5-4309-b3a0-944a9c8b559e_2641x1691.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>#7: Return Results, Not Exceptions</h2><p>Using exceptions for expected failures makes error handling invisible and easy to forget.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Naxj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Naxj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 424w, https://substackcdn.com/image/fetch/$s_!Naxj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 848w, https://substackcdn.com/image/fetch/$s_!Naxj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 1272w, https://substackcdn.com/image/fetch/$s_!Naxj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Naxj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png" width="341" height="361.8440934065934" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1545,&quot;width&quot;:1456,&quot;resizeWidth&quot;:341,&quot;bytes&quot;:257827,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Naxj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 424w, https://substackcdn.com/image/fetch/$s_!Naxj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 848w, https://substackcdn.com/image/fetch/$s_!Naxj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 1272w, https://substackcdn.com/image/fetch/$s_!Naxj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31ec126f-2366-4531-8987-df7ca07b6d45_1673x1775.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Callers don&#8217;t know what can go wrong just by looking at the function signature.</p><p>This leads to unhandled edge cases and application crashes.</p><p>To fix this, apply the Result Pattern and <strong>make errors part of your return type</strong>.</p><p>This forces callers to handle error cases and makes your <strong>function&#8217;s behaviour predictable and explicit</strong>.</p><p>A good rule of thumb is:</p><blockquote><p><strong>Use Result Pattern for expected errors to make them explicit.</strong></p><p><strong>Use Exceptions for unexpected errors and exceptional situations.</strong></p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NvQu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NvQu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 424w, https://substackcdn.com/image/fetch/$s_!NvQu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 848w, https://substackcdn.com/image/fetch/$s_!NvQu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 1272w, https://substackcdn.com/image/fetch/$s_!NvQu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NvQu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png" width="510" height="602.8228021978022" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1721,&quot;width&quot;:1456,&quot;resizeWidth&quot;:510,&quot;bytes&quot;:501269,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NvQu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 424w, https://substackcdn.com/image/fetch/$s_!NvQu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 848w, https://substackcdn.com/image/fetch/$s_!NvQu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 1272w, https://substackcdn.com/image/fetch/$s_!NvQu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f445b2e-803d-4b48-b63f-45bfe8811a1d_2426x2867.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>#8: Replace Magic Numbers and Strings</h2><p>A common code smell is the use of magic numbers and strings.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Macx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Macx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 424w, https://substackcdn.com/image/fetch/$s_!Macx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 848w, https://substackcdn.com/image/fetch/$s_!Macx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 1272w, https://substackcdn.com/image/fetch/$s_!Macx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Macx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png" width="506" height="270.02884615384613" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:777,&quot;width&quot;:1456,&quot;resizeWidth&quot;:506,&quot;bytes&quot;:158432,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Macx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 424w, https://substackcdn.com/image/fetch/$s_!Macx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 848w, https://substackcdn.com/image/fetch/$s_!Macx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 1272w, https://substackcdn.com/image/fetch/$s_!Macx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faae53f4c-219c-4d13-946f-f4db13e8d11c_2067x1103.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These hardcoded values create a <strong>maintenance nightmare</strong>.</p><p>When business requirements and rules change, it&#8217;s very hard to find every occurrence of these numbers or strings.</p><p>Another big problem with these magic numbers and strings is the <strong>lack of meaning</strong>.</p><p>To fix this problem, extract the <strong>numbers into constants</strong> and the <strong>strings into enums</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K4VL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K4VL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 424w, https://substackcdn.com/image/fetch/$s_!K4VL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 848w, https://substackcdn.com/image/fetch/$s_!K4VL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 1272w, https://substackcdn.com/image/fetch/$s_!K4VL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K4VL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png" width="501" height="430.11675824175825" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1250,&quot;width&quot;:1456,&quot;resizeWidth&quot;:501,&quot;bytes&quot;:282861,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/171130447?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!K4VL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 424w, https://substackcdn.com/image/fetch/$s_!K4VL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 848w, https://substackcdn.com/image/fetch/$s_!K4VL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 1272w, https://substackcdn.com/image/fetch/$s_!K4VL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fbc21e3-2821-4414-b954-7039a25e3a93_2067x1775.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to get actionable JavaScript, React, Node, and Software Architecture tips straight into your inbox every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>&#128204; TL;DR</h2><p>That&#8217;s all for today, 8 tips to write <strong>clean functions</strong>:</p><ul><li><p><a href="https://thetshaped.dev/i/171130447/keep-your-functions-small-and-focused">#1: Keep Your Functions Small And Focused</a></p></li><li><p><a href="https://thetshaped.dev/i/171130447/name-functions-to-reveal-intent">#2: Name Functions to Reveal Intent</a></p></li><li><p><a href="https://thetshaped.dev/i/171130447/return-early-to-avoid-nesting">#3: Return Early to Avoid Nesting</a></p></li><li><p><a href="https://thetshaped.dev/i/171130447/limit-function-parameters">#4: Limit Function Parameters</a></p></li><li><p><a href="https://thetshaped.dev/i/171130447/write-pure-functions-when-possible">#5: Write Pure Functions When Possible</a></p></li><li><p><a href="https://thetshaped.dev/i/171130447/avoid-boolean-parameters">#6: Avoid Boolean Parameters</a></p></li><li><p><a href="https://thetshaped.dev/i/171130447/return-results-not-exceptions">#7: Return Results, Not Exceptions</a></p></li><li><p><a href="https://thetshaped.dev/i/171130447/replace-magic-numbers-and-strings">#8: Replace Magic Numbers and Strings</a></p></li></ul><p>Hope this was helpful.</p><p>See you next week!</p><p><strong>Today&#8217;s action step:</strong> Take a look at your project and see if you&#8217;re making some of the mistakes I highlighted here. Try to fix them using the clean code tips I shared with you.</p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 27.4K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Why You Can't Afford to Ignore TypeScript? 🌟]]></title><description><![CDATA[We ship faster when we break fewer things. TypeScript helps you do that. (4 min)]]></description><link>https://thetshaped.dev/p/why-you-cant-afford-to-ignore-typescript-long-term-benefits-code-quality</link><guid isPermaLink="false">https://thetshaped.dev/p/why-you-cant-afford-to-ignore-typescript-long-term-benefits-code-quality</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sun, 17 Aug 2025 10:14:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6d5e6157-6885-4585-8b2c-945833350755_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 27,331+ engineers to receive one practical tip on JavaScript, React, Node, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>When I see people who are not sold on <a href="https://www.typescriptlang.org/">TypeScript</a>, I show them code like this:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hLbT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hLbT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 424w, https://substackcdn.com/image/fetch/$s_!hLbT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 848w, https://substackcdn.com/image/fetch/$s_!hLbT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 1272w, https://substackcdn.com/image/fetch/$s_!hLbT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hLbT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png" width="476" height="135.01923076923077" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:413,&quot;width&quot;:1456,&quot;resizeWidth&quot;:476,&quot;bytes&quot;:76943,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/159533672?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hLbT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 424w, https://substackcdn.com/image/fetch/$s_!hLbT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 848w, https://substackcdn.com/image/fetch/$s_!hLbT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 1272w, https://substackcdn.com/image/fetch/$s_!hLbT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76003c2-fa3a-4539-9432-1ea1a4f059a7_1816x515.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>The moment you reference a property from an object, you are using a type.</p><p>You rely on the object to have a specific structure.</p><p>It&#8217;s better to make it obvious and describe it.</p><p>Yes, writing TypeScript takes a bit more effort, but that work pays off in the future, especially with the maturity of the project.</p><p><em>Remember:</em> <strong>We ship faster when we break fewer things. TypeScript helps you do that.</strong></p><p>In today&#8217;s article, I&#8217;d outline several benefits of why you have to use TypeScript in your projects.</p><div><hr></div><h2><a href="https://coderabbit.link/petar">CodeRabbit: Cut Code Review Time &amp; Bugs in Half - Sponsor</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l1iy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l1iy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 424w, https://substackcdn.com/image/fetch/$s_!l1iy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 848w, https://substackcdn.com/image/fetch/$s_!l1iy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 1272w, https://substackcdn.com/image/fetch/$s_!l1iy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l1iy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!l1iy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 424w, https://substackcdn.com/image/fetch/$s_!l1iy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 848w, https://substackcdn.com/image/fetch/$s_!l1iy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 1272w, https://substackcdn.com/image/fetch/$s_!l1iy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03128046-da85-4f5d-a9a1-38811710d63c_1600x800.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Code reviews are critical but time-consuming. <a href="https://coderabbit.link/petar">CodeRabbit</a> acts as your AI co-pilot, providing instant Code review comments and potential impacts of every pull request. </p><p>Beyond just flagging issues, <a href="https://coderabbit.link/petar">CodeRabbit</a> provides one-click fix suggestions and lets you define custom code quality rules using AST Grep patterns, catching subtle issues that traditional static analysis tools might miss.</p><p><a href="https://coderabbit.link/petar">CodeRabbit</a> has so far reviewed more than 10 million PRs, installed on 1 million repositories, and used by 70 thousand Open-source projects. <a href="https://coderabbit.link/petar">CodeRabbit</a> is <strong>free</strong> for all open-source repos.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://coderabbit.link/petar&quot;,&quot;text&quot;:&quot;Get Started Today&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://coderabbit.link/petar"><span>Get Started Today</span></a></p><div><hr></div><h2>1. Design Better Systems with Type-Driven Development</h2><p>A good way to use TypeScript is to start by defining your domain types, not implementation.</p><p>When you describe your data in your system clearly, you can see gaps in your understanding before writing any logic.</p><p>This is the so-called &#8220;type-driven development&#8221; where you start with the types, which makes the blueprint of the feature.</p><p>For example, imagine a <strong>Product</strong> type that requires at least one price.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!87U_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!87U_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 424w, https://substackcdn.com/image/fetch/$s_!87U_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 848w, https://substackcdn.com/image/fetch/$s_!87U_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 1272w, https://substackcdn.com/image/fetch/$s_!87U_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!87U_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png" width="545" height="313.67445054945057" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:838,&quot;width&quot;:1456,&quot;resizeWidth&quot;:545,&quot;bytes&quot;:207453,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/159533672?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!87U_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 424w, https://substackcdn.com/image/fetch/$s_!87U_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 848w, https://substackcdn.com/image/fetch/$s_!87U_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 1272w, https://substackcdn.com/image/fetch/$s_!87U_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff094ee04-b9c4-41e2-9e03-6a086a9f4543_2354x1355.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With this structure, you can&#8217;t create a <strong>Product</strong> without a price.</p><p>By outlining that with types, we make illegal states unrepresentable, removing an entire set of bugs.</p><p>Those types also serve as a <strong>living documentation</strong> and <strong>source of truth of the current system&#8217;s state</strong>.</p><div><hr></div><h2>2. Productivity Benefits: Auto-Completion &amp; Error Detection</h2><p>TypeScript&#8217;s compiler and IDE support give you <strong>immediate feedback</strong>.</p><p>If you mistype a property or call a method with the wrong type, the editor warns you before you hit &#8220;run&#8221;.</p><p>Optional properties and return types are checked too.</p><p>For example, if a function is supposed to return a <strong>string</strong> but may return <strong>undefined</strong>, the compiler points that out.</p><p>This kind of feedback reduces the time spent debugging and hunting down runtime errors.</p><p>Another great advantage is the <strong>auto-completion</strong>.</p><p>Because your editor knows the types of your variables, it can suggest valid methods and properties.</p><p>This significantly improves the Developer Experience, speeding up the coding process.</p><div><hr></div><h2>3. Long-Term Code Quality And Team Benefits</h2><p>Large codebases and growing teams amplify the cost of mistakes.</p><p>TypeScript acts as a safety net that scales with your organization.</p><p>When you change a contract, TypeScript highlights every place you need to update.</p><p>When LinkedIn evaluated TypeScript adoption, they found that even a small conversion would <strong>catch about a quarter of all the JavaScript errors in their apps</strong>.</p><p>TypeScript makes implicit contracts explicit:</p><ul><li><p>Function signatures document expected inputs and outputs</p></li><li><p>Interface changes highlight all affected code</p></li><li><p>Refactoring becomes mechanical rather than error-prone</p></li></ul><p>Clear type information makes code <strong>easier to understand, navigate, maintain, and debug</strong>.</p><p>This increases the capacity to add new features and fix bugs.</p><p><strong>In short, investing in types now pays off through faster development later.</strong></p><div><hr></div><h2>4. Trade-Offs And Downsides</h2><p>Using TypeScript does add complexity.</p><p>You have to learn the syntax, maintain type definitions, and configure a <strong>tsconfig</strong> file.</p><p>There are also some packages that lack good types.</p><p>In recent years, however, tooling and package support have improved tremendously.</p><p>Most developers can rely on type inference instead of writing complex generic types.</p><p><strong>You also don&#8217;t need 100% perfect types to get 99.9% of the value.</strong></p><p>There are escape hatches, such as using <strong>any</strong> or <strong>unknown</strong> in a limited scope.</p><p>As long as you are careful, you can retain almost all the benefits while avoiding diminishing returns.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Become a better Full-Stack JavaScript Engineer. Join 27,311 engineers who are improving their skills every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p><strong>TypeScript adds types to JavaScript</strong>, helping you <strong>catch mistakes</strong> before they reach your users.</p></li><li><p><strong>Embrace &#8220;type-driven development&#8221; by outlining your types and data structures before writing any logic.</strong> This helps to reveal blind spots and misunderstandings.</p></li><li><p><strong>TypeScript enables auto-completion and instant feedback</strong>, improving the Developer Experience and speeding up coding.</p></li><li><p>Better code quality and teamwork.</p></li><li><p><strong>If the type system gets in your way, cheat by using any or unknown. It&#8217;s not necessary to have 100% perfect types.</strong></p></li><li><p><strong>Using TypeScript may slow you down now, but the investment is worth it.</strong> It results in cleaner, more reliable software that can evolve without chaos.</p></li></ul><p>That's all for today. I hope this was helpful. &#9996;&#65039;</p><div><hr></div><h2><strong>How Can I Help You Further?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://consciousreact.com/" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png" width="528" height="297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:528,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:&quot;https://consciousreact.com/&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Learn how to build clean, maintainable, and testable React Applications! &#128640;</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://consciousreact.com/&quot;,&quot;text&quot;:&quot;Check the book out!&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://consciousreact.com/"><span>Check the book out!</span></a></p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 27.3K+ subscribers this week &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Nine VS Code (or Cursor) Extensions That Make My Daily Work Much Easier ]]></title><description><![CDATA[Learn how to improve your IDE and increase your coding speed with these extensions. (4 min)]]></description><link>https://thetshaped.dev/p/nine-vs-code-or-cursor-ide-extensions-code-editor</link><guid isPermaLink="false">https://thetshaped.dev/p/nine-vs-code-or-cursor-ide-extensions-code-editor</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sun, 03 Aug 2025 12:13:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ff5b1ee8-ac39-44ec-a658-11df9eed926c_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a Software Engineer, you read, update, and write code daily.</p><p>And most probably you&#8217;re doing it through an IDE.</p><p>In my case, I use <a href="https://code.visualstudio.com/">VS Code</a> or <a href="https://cursor.com/">Cursor</a>, which is a fork of VS Code.</p><p>It&#8217;s beneficial if your IDE works for you, not against you.</p><p>Tuning your IDE by adding helpful extensions can boost your productivity.</p><p>In today&#8217;s article, I&#8217;ll cover some of my favorite VS Code extensions I use daily to speed up my work.</p><p>PS. These extensions are general-purpose, regardless of the language.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 26,931+ engineers to receive one practical tip on JavaScript, React, Node, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>1. Code Spell Checker</h2><p>Code Spell Checker is a basic spell checker which works pretty well with code.</p><p>It helps to catch common spelling errors, typos, and mixing alphabets from different languages.</p><p>For example, imagine using `a` and `&#1072;`.</p><p>They look the same but the IDE and your code won&#8217;t treat them the same way.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rPBv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rPBv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 424w, https://substackcdn.com/image/fetch/$s_!rPBv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 848w, https://substackcdn.com/image/fetch/$s_!rPBv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 1272w, https://substackcdn.com/image/fetch/$s_!rPBv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rPBv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif" width="745" height="539" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:539,&quot;width&quot;:745,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:353729,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/168766462?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rPBv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 424w, https://substackcdn.com/image/fetch/$s_!rPBv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 848w, https://substackcdn.com/image/fetch/$s_!rPBv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 1272w, https://substackcdn.com/image/fetch/$s_!rPBv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b58dbb2-8dfa-4c0d-bc64-2a4efc496b02_745x539.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=streetsidesoftware.code-spell-checker">link</a>).</p><div><hr></div><h2>2. EditorConfig for VS Code</h2><p>This plugin attempts to override user/workspace settings with settings found in `.editorconfig` files.</p><p>It&#8217;s very helpful when you work on projects with different settings that are different than the ones you have by default in your IDE.</p><p>For example, in my personal projects, I use two spaces as indentation but as consultant I&#8217;ve worked on many legacy projects with four spaces as indentation.</p><p>Using the `.editorconfig` file in such projects made my life much easier.</p><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=EditorConfig.EditorConfig">link</a>).</p><div><hr></div><h2>3. GitLens &#8212; Git supercharged</h2><p>GitLens enhances your workflows with powerful Git functionality like in-editor blame annotations, hovers, CodeLens, and more&#8212;all fully customizable within VS Code.</p><p>It&#8217;s a must-have extensions if you&#8217;re using Git, in my opinion.</p><p>One of its coolest features is to see by whom a line was edited and directly jump to the Pull Request or Merge Request to further inspect it.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FHiT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FHiT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 424w, https://substackcdn.com/image/fetch/$s_!FHiT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 848w, https://substackcdn.com/image/fetch/$s_!FHiT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 1272w, https://substackcdn.com/image/fetch/$s_!FHiT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FHiT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png" width="610" height="216" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:216,&quot;width&quot;:610,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12765,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/168766462?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FHiT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 424w, https://substackcdn.com/image/fetch/$s_!FHiT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 848w, https://substackcdn.com/image/fetch/$s_!FHiT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 1272w, https://substackcdn.com/image/fetch/$s_!FHiT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7404e10-0263-4bfe-b2e4-f2d6e9eb7a80_610x216.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=eamodio.gitlens">link</a>).</p><div><hr></div><h2>4. VS Code Icons</h2><p>It brings real icons to your VS Code.</p><p>It makes it much clear what files and folders you have in your project and what are their types.</p><p>So navigation throughout the project becomes a bit easier.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CUQU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CUQU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 424w, https://substackcdn.com/image/fetch/$s_!CUQU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 848w, https://substackcdn.com/image/fetch/$s_!CUQU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!CUQU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CUQU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif" width="800" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2805662,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/168766462?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CUQU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 424w, https://substackcdn.com/image/fetch/$s_!CUQU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 848w, https://substackcdn.com/image/fetch/$s_!CUQU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!CUQU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9cc8ceef-f8d3-4d4b-89c2-ecad70afcb7b_800x600.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=usernamehw.errorlens">link</a>).</p><div><hr></div><h2>5. Error Lens</h2><p>ErrorLens turbo-charges language diagnostic features by making diagnostics stand out more prominently, highlighting the entire line wherever a diagnostic is generated by the language and also prints the message inline.</p><p>It&#8217;s really handy to see immediate clear feedback from your changes which speeds up the feedback loop and code iterations.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4ArK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4ArK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 424w, https://substackcdn.com/image/fetch/$s_!4ArK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 848w, https://substackcdn.com/image/fetch/$s_!4ArK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 1272w, https://substackcdn.com/image/fetch/$s_!4ArK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4ArK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png" width="910" height="105" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:105,&quot;width&quot;:910,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8650,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/168766462?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4ArK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 424w, https://substackcdn.com/image/fetch/$s_!4ArK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 848w, https://substackcdn.com/image/fetch/$s_!4ArK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 1272w, https://substackcdn.com/image/fetch/$s_!4ArK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e8c1847-2415-4904-ac3c-6dc2ca66b2e8_910x105.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=usernamehw.errorlens">link</a>).</p><div><hr></div><h2>6. Indent Rainbow</h2><p>It&#8217;s a simple extension to make indentation more readable.</p><p>This extension colorizes the indentation in front of your text, alternating four different colors on each step.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uyPn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uyPn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 424w, https://substackcdn.com/image/fetch/$s_!uyPn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 848w, https://substackcdn.com/image/fetch/$s_!uyPn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 1272w, https://substackcdn.com/image/fetch/$s_!uyPn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uyPn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png" width="525" height="271" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:271,&quot;width&quot;:525,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:125386,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/168766462?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uyPn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 424w, https://substackcdn.com/image/fetch/$s_!uyPn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 848w, https://substackcdn.com/image/fetch/$s_!uyPn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 1272w, https://substackcdn.com/image/fetch/$s_!uyPn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b735270-23c8-4492-b8e9-c6ce9af4d862_525x271.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=oderwat.indent-rainbow">link</a>).</p><div><hr></div><h2>7. MarkdownLint</h2><p>In my experience, I use markdown files in repositories for documentation.</p><p>Getting my markdown files correct is a must.</p><p>VS Code has basic Markdown support out-of-the-box (e.g, Markdown preview), please see the <a href="https://code.visualstudio.com/docs/languages/markdown">official documentation</a> for more information.</p><p>However, we don&#8217;t have a linting for the markdown files to ensure consistency and </p><p>MarkdownLint plugin helps with linting and style checking for your markdown files.</p><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint">link</a>).</p><div><hr></div><h2>8. Path Intellisense</h2><p>This plugin autocompletes filenames.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PzE5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PzE5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!PzE5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!PzE5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!PzE5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PzE5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif" width="480" height="270" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:270,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:87934,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/168766462?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PzE5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 424w, https://substackcdn.com/image/fetch/$s_!PzE5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 848w, https://substackcdn.com/image/fetch/$s_!PzE5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 1272w, https://substackcdn.com/image/fetch/$s_!PzE5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68c4ceef-935a-43ca-afc5-283d610c9ccd_480x270.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=christian-kohler.path-intellisense">link</a>).</p><div><hr></div><h2>9. GitHub Copilot Chat</h2><p>Using a LLM and a chatbot for coding has become the de facto standard.</p><p>So if you&#8217;re not using one already, you&#8217;re falling behind.</p><p>In VS Code, you can use <a href="https://code.visualstudio.com/docs/copilot/overview">GitHub Copilot</a> for <a href="https://docs.github.com/en/copilot/get-started/plans#comparing-copilot-plans">FREE</a>.</p><p>Of course, it has some limitations, but still you can take advantage of it.</p><p>You can find the extension both directly in the IDE Extensions Tab or in the Marketplace (<a href="https://marketplace.visualstudio.com/items/?itemName=GitHub.copilot-chat">link</a>).</p><p>If you&#8217;re using Cursor, you won&#8217;t need it, since it has its own autosuggestion and AI functionality.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Become a better Full-Stack JavaScript Engineer. Join 26,931 engineers who are improving their skills every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p>Code Spell Checker</p></li><li><p>EditorConfig for VS Code</p></li><li><p>GitLens &#8212; Git supercharged</p></li><li><p>VS Code Icons</p></li><li><p>Error Lens</p></li><li><p>Indent Rainbow</p></li><li><p>MarkdownLint</p></li><li><p>Path Intellisense</p></li><li><p>GitHub Copilot Chat</p></li></ul><p>That's all for today. I hope this was helpful. &#9996;&#65039;</p><div><hr></div><h2><strong>How I can help you further?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://consciousreact.com/" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png" width="528" height="297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:528,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:&quot;https://consciousreact.com/&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Learn how to build clean, maintainable, and testable React Applications! &#128640;</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://consciousreact.com/&quot;,&quot;text&quot;:&quot;Check the book out!&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://consciousreact.com/"><span>Check the book out!</span></a></p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 26.9K+ subscribers this week &#128591;</em></p><div><hr></div><p><em>You can also hit the like &#10084;&#65039; button at the bottom to help support me or share this with a friend. It helps me a lot! &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[GraphQL Schema Design 101]]></title><description><![CDATA[Learn proven best practices and key principles for designing robust GraphQL Schemas. (5 min)]]></description><link>https://thetshaped.dev/p/graphql-schema-design-101-best-practices-key-principles-flexible-maintainable-apis</link><guid isPermaLink="false">https://thetshaped.dev/p/graphql-schema-design-101-best-practices-key-principles-flexible-maintainable-apis</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sun, 13 Jul 2025 12:19:29 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2412a2a4-659e-4f6f-bb07-7d8be4cfe69b_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>GraphQL Schema is the contract between your server and your clients.</p><p>It defines what data your clients can request, how they will receive it, and how they can modify it.</p><p>Good schema design makes your API easy to use, predictable, and maintainable.</p><p>In the past, I&#8217;ve designed several production-ready GraphQL schemas that lasted in time.</p><p>I saw and learned what worked well and what didn&#8217;t.</p><p>In today&#8217;s article, I&#8217;ll discuss the key principles, rules, patterns, and design considerations that worked well for me in the past.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 26,831+ engineers to receive one practical tip on JavaScript, React, Node, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>1. General Principles</strong></h2><h3>1.1 YAGNI (You Aren&#8217;t Gonna Need It)</h3><p>Keep your API minimal.</p><p>Expose fields and use cases only when needed.</p><p>Deprecate the fields that are not being used anymore.</p><p>Fewer fields means less surface are for bugs, simpler documentation, and easier client development.</p><h3>1.2 Completeness</h3><p>Keep your schema minimal, yet complete.</p><p>Clients should be able to achieve their use cases completely.</p><p>A complete schema saves clients from multiple APIs, requests, and keeps data fetching efficient.</p><h3>1.3 Embed Domain Knowledge</h3><p>Encode as mush as possible and as clearly as possible the domain knowledge in the schema.</p><p>Your names should match the domain knowledge and language.</p><p>Domain-Driven schemas are much easier to deal with, especially for newer developers to understand the business domain.</p><h3>1.4 No Implementation Details</h3><p>The API should focus on the Domain and Client use cases.</p><p>Implementation details must be hidden.</p><div><hr></div><h2>2. Naming Conventions</h2><h3>2.1 camelCase For Fields &amp; Inputs</h3><p>Field names and inputs should use camelCase.</p><p>Same as we do in JavaScript.</p><pre><code>type User {  
  firstName: String!  
  lastName: String!  
}</code></pre><h3>2.2 PascalCase For Types &amp; Enums</h3><p>Type names should use pascalCase.</p><p>This matches how classes are defined in JavaScript.</p><pre><code>type OrderDetail { ... }  
enum PaymentMethod { CREDIT_CARD, PAYPAL }</code></pre><h3>2.3 ALL_CAPS For Enum Values</h3><p>Enum values should use ALL_CAPS, because they are similar to constants.</p><pre><code>enum Role { ADMIN, EDITOR, VIEWER }</code></pre><h3>2.4 Use Create/Update/Delete In Mutations</h3><p>Use Create/Update/Delete in mutations instead of they synonyms, unless you have a specific reason to use another verb.</p><pre><code>type Mutation {  
  createUser(input: CreateUserInput!): CreateUserPayload  
  deletePost(input: DeletePostInput!): DeletePostPayload  
}</code></pre><h3>2.5 Avoid Abbreviations</h3><p>Prefer to be explicit about names.</p><div><hr></div><h2>3. Fields And Mutations</h2><h3>3.1 Default Values</h3><p>Use default values to make an API more <strong>predictable and communicate intent</strong>.</p><pre><code>type Query {
  #<strong> &#9940; Bad</strong>
  products(first: Int!, <strong>orderBy: ProductsOrdering</strong>)

  #<strong> &#9989; Good</strong>
  products(first: Int!, <strong>orderBy: ProductsOrdering = CREATED_AT</strong>)
}</code></pre><h3>3.2 Explicit Side-Effects</h3><p>Avoid implicit and surprise side-effects in fields and mutations.</p><p><strong>The name should convey what it does at runtime.</strong></p><h3>3.3 Mutation  Naming: verbEntity</h3><p>Name mutations using <strong>verbEntity</strong> (and not entityVerb).</p><pre><code>#<strong> &#9940; Bad</strong>
userInvite

#<strong> &#9989; Good</strong>
inviteUser</code></pre><h3>3.4 Single-Purpose Fields</h3><p>Do one thing, and do it well.</p><p>Prefer specific solutions rather than overly clever and generic fields.</p><h3>3.5 Beyond CRUD</h3><p>Think beyond CRUD.</p><p>Use action or behavior specific fields and mutations to help clients use your API.</p><pre><code>#<strong> &#9940; Bad</strong>
<strong>updatePost</strong>(input: {..., <strong>archived: true }</strong>) {
  ... 
}

#<strong> &#9989; Good</strong>
<strong>archivePost</strong>(input: { <strong>postID: "abc"</strong> }) {
  ... 
}</code></pre><h3>3.6 Input &amp; Payload Types</h3><p>Use Input and Payload types for mutations.</p><p>Use specific object types for mutation inputs and outputs.</p><p>Use *Input suffix for input and *Payload suffix for the result.</p><pre><code>type Mutation {
  # <strong>&#9940; Bad</strong>
  createProduct(name: String!): Product

  # <strong>&#9989; Good</strong>
  createProduct(<strong>input: CreateProductInput!</strong>): <strong>CreateProductPayload</strong>
}</code></pre><h3>3.7 Don&#8217;t Reuse Types Across Mutations</h3><p>Don&#8217;t reuse input and payload types across multiple mutations.</p><p>This prevents accidental coupling.</p><h3>3.8 Use Non-Null With Care</h3><p>Use Non-Null mostly on scalar fields and use them with care on associations.</p><p>Non-Nullable mean that the field <strong>must</strong> never be null.</p><p>If it is null for any reason, GraphQL will return error without the data.</p><pre><code>type User {
  # <strong>Prefer nullable associations, especially if backed by external services</strong>
  profilePicture: ProfilePicture

  # <strong>Scalars are usually safer</strong>
  name: String!
}</code></pre><p>You can read more about nullability <a href="https://graphql.org/learn/schema-design/#nullability">here</a>.</p><h3>3.9 Prefer Required Arguments</h3><p>Prefer a strong schema rather than runtime checks.</p><p>Use more specific fields if needed.</p><pre><code>type Query {
  # <strong>&#9940; Bad</strong>
  userByNameOrID(<strong>id: ID</strong>, <strong>name: String</strong>): User

  # <strong>&#9989; Good</strong>
  userByName(<strong>name: String!</strong>): User
  userByID(<strong>id: ID!</strong>): User
}</code></pre><div><hr></div><h2>4. Error Handling</h2><h3>4.1 GraphQL Errors For Global Issues</h3><p>Use GraphQL Errors for developer-facing global errors.</p><p>Example where to use such errors: internal (unexpected) server errors, timeouts, auth, schema validation, etc.</p><h3>4.2 Error Extensions</h3><p>Use GraphQL Error extensions to encode additional information.</p><p>Always provide a unique &#8220;code&#8221;.</p><p>This helps the client to decide what to do based on the &#8220;code&#8221;, instead of the error message.</p><pre><code>{
  "errors": [
    {
      "message": "The current user does not have permissions for: ...",
      "<strong>extensions</strong>": { 
        <strong>"code": "UNAUTHORIZED"</strong>
      }
    }
  ]
}</code></pre><h3>4.3 User-Facing Errors in Schema</h3><p>Use user errors, or errors-in-schema, for user-facing errors.</p><p>Use the schema instead of top-level errors for errors that are meant to be displayed to the user.</p><pre><code>{
  "errors": [
    {
      "message": "Invalid input arguments.",
      <strong>"extensions": {</strong> 
        "code": "BAD_USER_INPUT",
        <strong>"errors": [
          { "field": "email", "message": "Email already registered" }
        ]</strong>
      <strong>}</strong>
    }
  ]
}</code></pre><div><hr></div><h2>5. Identification</h2><h3>5.1 Global IDs</h3><p>Every type that implements the Node interface must define a unique and global ID.</p><p>Those IDs are opaque so that it is clear they are not intended to be decoded on the client.</p><h3>5.2 Rich ID Encoding</h3><p>Encode enough information in IDs for global fetching.</p><p>Prefer encoding more that not enough for evolution.</p><p>This might mean including the parent object id, the shard key, etc.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Become a better Full-Stack JavaScript Engineer. Join 26,831 engineers who are improving their skills every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p><strong>General Principles</strong></p><ul><li><p>YAGNI (You Aren&#8217;t Gonna Need It)</p></li><li><p>Completeness</p></li><li><p>Embed Domain Knowledge</p></li><li><p>No Implementation Details</p></li></ul></li><li><p><strong>Naming Conventions</strong></p><ul><li><p>camelCase For Fields &amp; Inputs</p></li><li><p>PascalCase For Types &amp; Enums</p></li><li><p>ALL_CAPS For Enum Values</p></li><li><p>Use Create/Update/Delete In Mutations</p></li><li><p>Avoid Abbreviations</p></li></ul></li><li><p><strong>Fields And Mutations</strong></p><ul><li><p>Use Default Values</p></li><li><p>Prefer Explicit Side-Effects</p></li><li><p>Mutation Naming: verbEntity</p></li><li><p>Prefer Single-Purpose Fields</p></li><li><p>Think Beyond CRUD</p></li><li><p>Input &amp; Payload Types</p></li><li><p>Don&#8217;t Reuse Types Across Mutations</p></li><li><p>Use Non-Null With Care</p></li><li><p>Prefer Required Arguments</p></li></ul></li><li><p><strong>Error Handling</strong></p><ul><li><p>GraphQL Errors For Global Issues</p></li><li><p>Error Extensions</p></li><li><p>User-Facing Errors in Schema</p></li></ul></li><li><p><strong>Identification</strong></p><ul><li><p>Use Global IDs</p></li><li><p>Rich ID Encoding</p></li></ul></li></ul><p>That's all for today. I hope this was helpful. &#9996;&#65039;</p><div><hr></div><h2><strong>How I can help you further?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://consciousreact.com/" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png" width="528" height="297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:528,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:&quot;https://consciousreact.com/&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Learn how to build clean, maintainable, and testable React Applications! &#128640;</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://consciousreact.com/&quot;,&quot;text&quot;:&quot;Check the book out!&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://consciousreact.com/"><span>Check the book out!</span></a></p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 26.8K+ subscribers this week &#128591;</em></p><div><hr></div><p><em>You can also hit the like &#10084;&#65039; button at the bottom to help support me or share this with a friend. It helps me a lot! &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Anti Clean Code: The F.L.U.I.D. Trap ⚠️]]></title><description><![CDATA[Learn about the five key ways a code can go wrong and know what to be careful about. (6 minutes)]]></description><link>https://thetshaped.dev/p/anti-clean-code-the-fluid-trap-fragile-lax-untested-insecure-disorganized-code</link><guid isPermaLink="false">https://thetshaped.dev/p/anti-clean-code-the-fluid-trap-fragile-lax-untested-insecure-disorganized-code</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Sun, 29 Jun 2025 12:18:09 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9eb1947a-628f-4939-b46f-9bfac9963387_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every team wants to write clean, maintainable, scalable, and testable code.</p><p>We often read about SOLID principles, Clean Code, and other best practices.</p><p>These practices help us write code that is easy to change and extend.</p><p>Yet in real life, many projects and codebases fall into the opposite trap.</p><p>Let&#8217;s call this pattern the <strong>&#8220;F.L.U.I.D&#8221; code</strong>.</p><p>This code is <strong>Fragile</strong>, <strong>Lax</strong>, <strong>Untested</strong>, <strong>Insecure</strong>, and <strong>Disorganized</strong>.</p><p>Understanding these anti-patterns helps us identify problems early on and take corrective action to get the project back on track.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 26,544+ engineers to receive one practical tip on JavaScript, React, Node, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>What Is F.L.U.I.D. Code?</h2><p><strong>FLUID</strong> is an acronym for <strong>five key ways a code can go wrong</strong>.</p><ol><li><p><strong>Fragile</strong></p></li><li><p><strong>Lax</strong></p></li><li><p><strong>Untested</strong></p></li><li><p><strong>Insecure</strong></p></li><li><p><strong>Disorganized</strong></p></li></ol><p>When code exhibits one of these traits, it often drags in the others.</p><p>For example, a fragile module that breaks easily will also be hard to test and secure.</p><p>By recognizing the aspects of FLUID code teams can learn to spot bad traits of the code and change the trajectory.</p><div><hr></div><h2>Fragile Code</h2><p>Fragile code is code that is <strong>easily broken by unrelated changes or updates</strong>.</p><p>A small tweak in one module can trigger many bugs in other modules and features.</p><p>Fragile code <strong>breaks in unexpected ways</strong>.</p><p>When teams are dealing with fragile code, they start to <strong>lose confidence in the codebase</strong>.</p><p>They spend more time firefighting bugs and tracing problems, instead of building features and delivering value.</p><p>Teams become <strong>reluctant to touch or change a piece of code</strong> because of the <strong>fear of not breaking something else</strong>.</p><p>And this is contagious if not spotted on time and acted upon it.</p><p><strong>&#9940; Fragile Code might come from:</strong></p><ul><li><p>tight coupling between modules</p></li><li><p>large functions with many responsibilities</p></li><li><p>no clear boundaries or interfaces</p></li><li><p>lack of tests</p></li></ul><p><strong>&#9989; How to start fighting Fragile Code:</strong></p><ul><li><p>extract responsibilities into small, focused, and manageable functions</p></li><li><p>define clear interfaces and public methods</p></li><li><p>start writing tests (even simple ones) to prevent regressions</p></li></ul><div><hr></div><h2>Lax Coding Standards</h2><p>Inconsistent style across the codebase makes the <strong>code harder to read, follow, maintain, and even review</strong>.</p><p>When everyone has their own conventions and way of writing code, the <strong>codebase becomes a frankenstein</strong>.</p><p>It becomes a <strong>nightmare to onboard new team members </strong>and<strong> merge pieces of code and functionality</strong>.</p><p><strong>&#9940; Lax Coding Standards might come from:</strong></p><ul><li><p>no agreed upon style guide</p></li><li><p>lack of automated tooling (formatters, linters, etc)</p></li><li><p>weak or absent code review process</p></li></ul><p><strong>&#9989; How to start fighting Lax Coding Standards:</strong></p><ul><li><p>adopt a common style guide or create one for your team and company</p></li><li><p>enforce formatting with tools like ESLint, Prettier, etc.</p></li><li><p>include style check in your CI pipeline</p></li></ul><div><hr></div><h2>Untested Code</h2><p><strong>Without tests, you don&#8217;t know if a change breaks an existing behavior or not.</strong></p><p>You can&#8217;t be <strong>confident if product work as expected after your changes</strong>.</p><p>You might wait for customers to complain but this strategy might cost the company a lot - loosing existing customers and money.</p><p>There are also teams that apply &#8220;test in production&#8221; behavior but this strategy can&#8217;t give you strong confidence and could also lead to many outages.</p><p><strong>&#9940; Untested Code might come from:</strong></p><ul><li><p>tight deadlines and pressure to ship</p></li><li><p>no testing culture and rules or skills gap</p></li><li><p>legacy code without a testing framework</p></li></ul><p><strong>&#9989; How to start fighting Untested Code:</strong></p><ul><li><p>start small and simple - add a few tests to cover core flows and scenarios</p></li><li><p>integrate a testing framework (like Jest, Vitest, etc)</p></li><li><p>require tests for new features or bug fixes before merging</p></li></ul><div><hr></div><h2>Insecure Code</h2><p>Security flaws can let attackers <strong>steal data and shut down the whole system</strong>.</p><p>A <strong>single vulnerability inside the codebase might cost millions of dollars to the company</strong> - from legal fines to reputation damage and losing customers.</p><p>Imagine a login endpoint which fails to sanitize user input, allowing SQL injection.</p><p>This can let the attacker dumb the entire database in seconds.</p><p><strong>Investing in security early on saves time and money in the long term.</strong></p><p><strong>&#9940; Insecure Code might come from:</strong></p><ul><li><p>skipping input validation</p></li><li><p>implementing your own auth instead of using proven libraries</p></li><li><p>no static analysis or security audits</p></li></ul><p><strong>&#9989; How to start fighting Insecure Code:</strong></p><ul><li><p>validate and sanitize all input</p></li><li><p>use battle tested libraries for encryption and authentication</p></li><li><p>automate security scans (ex: Snyk)</p></li></ul><div><hr></div><h2>Disorganized Codebase</h2><p><strong>A messy project is hard to navigate and reason about.</strong></p><p><strong>Developers waste time searching for files and features or tracing down duplicate code.</strong></p><p>Then can even wonder where to put the new functionality.</p><p>Imagine a developer trying to build a new feature but can&#8217;t find whether an existing utility function is present or not.</p><p>So he decides to build his own, wasting time and effort.</p><p>This type of mindset can <strong>lead to enormous technical debt</strong> which will be very hard to pay down with the time going.</p><p>New hires might also get lost inside the codebase.</p><p>Clear and organized codebase improves the overall team efficiency and onboarding speed of new colleagues.</p><p><strong>&#9940; Disorganized Code might come from:</strong></p><ul><li><p>no agreed upon folder or module structure</p></li><li><p>large &#8220;god classes&#8221; with thousands of lines</p></li><li><p>copy-pasted code, instead of shared utility functions or modules</p></li></ul><p><strong>&#9989; How to start fighting Disorganized Code:</strong></p><ul><li><p>define a clear project layout (ex: Bounded Contexts, feature-based modules, page-based folders, etc)</p></li><li><p>enforce module boundaries and single responsibilities</p></li><li><p>regularly review and pay down tech debt, remove dead or duplicate code</p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Become a better Full-Stack JavaScript Engineer. Join 26,544 engineers who are improving their skills every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>The Vicious Cycle of F.L.U.I.D. Code</h2><p>Each FLUID trait in the code fuels the others.</p><p>Fragile code is hard to test, so it remains untested.</p><p>Untested code hides security holes, so it remains insecure.</p><p>Insecure code requires quick patches leading to lax coding standards.</p><p>And lax coding standards might lead to chaotic and disorganized codebase.</p><p>Over time, a once clean codebase becomes a FLUID trap.</p><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p><strong>FLUID</strong> - anti clean code pattern; <strong>F</strong>luid, <strong>L</strong>ax, <strong>U</strong>ntested, <strong>I</strong>nsecure, <strong>D</strong>isorganized.</p></li><li><p><strong>Fragile Code</strong> - small changes break other features, causing many bugs; teams start to fear making changes in the code.</p></li><li><p><strong>Lax Coding Standards</strong> - no shared style guide; poor code reviews and many merge conflicts.</p></li><li><p><strong>Untested Code</strong> - no automated tests; might lead to production regressions.</p></li><li><p><strong>Insecure Code</strong> - skips input validation and sanitization; security breaches.</p></li><li><p><strong>Disorganized Code</strong> - no clear project structure; duplicate code; confusion in team members.</p></li></ul><p>That's all for today. I hope this was helpful. &#9996;&#65039;</p><p><em>Credits to <a href="https://www.linkedin.com/in/kristijankralj/">Kristijan Kralj</a> who inspired me about FLUID code.</em></p><div><hr></div><h2><strong>How I can help you further?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://consciousreact.com/" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png" width="528" height="297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:528,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:&quot;https://consciousreact.com/&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Learn how to build clean, maintainable, and testable React Applications! &#128640;</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://consciousreact.com/&quot;,&quot;text&quot;:&quot;Check the book out!&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://consciousreact.com/"><span>Check the book out!</span></a></p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 26.5K+ subscribers this week &#128591;</em></p><div><hr></div><p><em>You can also hit the like &#10084;&#65039; button at the bottom to help support me or share this with a friend. It helps me a lot! &#128591;</em></p>]]></content:encoded></item><item><title><![CDATA[Ace Your Next JavaScript Interview: `this`, `new`, Prototypes, Classes (Part 3) ✨]]></title><description><![CDATA[Learn the deeper concepts in JavaScript, such as `this`, `new`, Prototypes, and Classes (7 minutes)]]></description><link>https://thetshaped.dev/p/ace-your-next-javascript-interview-this-new-keywords-prototypes-classes</link><guid isPermaLink="false">https://thetshaped.dev/p/ace-your-next-javascript-interview-this-new-keywords-prototypes-classes</guid><dc:creator><![CDATA[Petar Ivanov]]></dc:creator><pubDate>Wed, 18 Jun 2025 13:22:20 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d10ac4c5-d303-453e-b169-409174170eaa_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Just arriving? Join 26,331+ engineers to receive one practical tip on JavaScript, React, Node, and Software Architecture every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>This is part 3 of the <strong>&#8220;Ace Your Next JavaScript Interview&#8221;</strong> series where I cover the fundamentals of JavaScript, sharing my notes which I use to review and prepare for interviews.</p><p>In today&#8217;s article, I&#8217;ll cover other JavaScript concepts, such as `this`, `new`, Prototypes, and Classes.</p><p>If you missed the previous articles, you can check <a href="https://thetshaped.dev/p/ace-your-next-javascript-interview-scope-hoisting-closures-simplified">part 1</a> and <a href="https://thetshaped.dev/p/ace-your-next-javascript-interview-values-references-coercion-equality">part 2</a>:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a12c203c-0907-4977-b7a6-3bca6490a6ae&quot;,&quot;caption&quot;:&quot;Some time ago, I had an interview, which I almost failed.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Ace Your Next JavaScript Interview: Scope, Hoisting &amp; Closures (Part 1)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:10269058,&quot;name&quot;:&quot;Petar Ivanov&quot;,&quot;bio&quot;:&quot;Senior Software Engineer | Practical React, Node, and Software Architecture Tips &#128293; | Author of &#8220;The Conscious React&#8221; book &#9883;&#65039;&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b236a7ab-735e-49d2-bbe8-98b1f901b169_500x500.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-02-02T15:03:22.962Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b2752b1-9a34-4151-8614-b752e2e16554_1456x1048.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://thetshaped.dev/p/ace-your-next-javascript-interview-scope-hoisting-closures-simplified&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:156291937,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:51,&quot;comment_count&quot;:6,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;The T-Shaped Dev&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f66bb7c-c96f-4c71-ba2d-d561152c83a2_600x600.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;52770ffb-77d8-41de-997c-f3be9eec5545&quot;,&quot;caption&quot;:&quot;Just arriving? Join 24,381+ engineers to receive one practical tip on React, Node, and Software Architecture every week.&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Ace Your Next JavaScript Interview: Values, References, Coercion &amp; Equality (Part 2) &#10024;&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:10269058,&quot;name&quot;:&quot;Petar Ivanov&quot;,&quot;bio&quot;:&quot;Senior Software Engineer | Practical React, Node, and Software Architecture Tips &#128293; | Author of &#8220;The Conscious React&#8221; book &#9883;&#65039;&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b236a7ab-735e-49d2-bbe8-98b1f901b169_500x500.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2025-06-03T12:03:18.523Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/542e2cb0-f2ff-4459-b6cd-dd0e269c4237_1456x1048.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://thetshaped.dev/p/ace-your-next-javascript-interview-values-references-coercion-equality&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:163905266,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:16,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;The T-Shaped Dev&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f66bb7c-c96f-4c71-ba2d-d561152c83a2_600x600.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><h2><strong><a href="https://tiny.outlier.ai/42faetja">Outlier (powered by Scale AI) - Sponsor</a></strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://tiny.outlier.ai/42faetja" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QyY2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 424w, https://substackcdn.com/image/fetch/$s_!QyY2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 848w, https://substackcdn.com/image/fetch/$s_!QyY2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 1272w, https://substackcdn.com/image/fetch/$s_!QyY2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QyY2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png" width="600" height="500" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:500,&quot;width&quot;:600,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:34648,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:&quot;https://tiny.outlier.ai/42faetja&quot;,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://thetshaped.dev/i/166062904?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QyY2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 424w, https://substackcdn.com/image/fetch/$s_!QyY2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 848w, https://substackcdn.com/image/fetch/$s_!QyY2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 1272w, https://substackcdn.com/image/fetch/$s_!QyY2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68649840-a30b-46a7-b939-ee8c4c6ea6ef_600x500.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong><a href="https://tiny.outlier.ai/42faetja">Outlier</a></strong> provides premium freelance coding opportunities for frontend developers.</p><ul><li><p>up to <strong>$50 per hour (USD)</strong> based on expertise and location</p><ul><li><p>some other countries it is up to $30 per hour (USD) due to location</p></li></ul></li><li><p><strong>weekly payouts</strong> via PayPal &amp; AirTM&#8212;no waiting weeks to get paid</p></li><li><p>performance <strong>bonuses</strong> available on select projects</p></li></ul><p>Explore how frontend developers are shaping AI's future (and getting paid for it).</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://tiny.outlier.ai/42faetja&quot;,&quot;text&quot;:&quot;Explore Outlier&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://tiny.outlier.ai/42faetja"><span>Explore Outlier</span></a></p><div><hr></div><h2>The `this` Keyword</h2><p>In object-oriented languages like C# or Java, the <strong>`this`</strong> keyword refers to the current object of a method or a constructor.</p><p>So each time you use <strong>`this`</strong> inside a method of a object, it will always refer to the same object.</p><p>However, in JavaScript, the <strong>`this`</strong> keyword implementation is slightly different, which sometimes causes many problems and bugs, if not understood well.</p><p>Let explore some examples.</p><h3><strong>Example 1: Method Call</strong></h3><pre><code>const hero = {
  name: 'Aria',
  greet() {
    console.log(`${this.name} says hi`);
  }
};

hero.greet(); // Aria says hi</code></pre><p>In this case, everything works as expected.</p><p>However, the value of <strong>`this`</strong> is not determined by the function that uses it.</p><h3><strong>Example 2: Detached Method</strong></h3><pre><code>const { greet } = hero;

greet(); //  says hi</code></pre><p>In this case, we get an empty value for <strong>`this.name`</strong> because the value of <strong>`this`</strong> depends on the call-site.</p><p>It doesn&#8217;t refer to the function in which it&#8217;s used or to it&#8217;s scope.</p><p>It refers to the object on which the function is being executed.</p><p>In the example above, I&#8217;ve run the code inside the browser, where <strong>`this`</strong> refers to the <strong>`window`</strong> object and it doesn&#8217;t have a <strong>`name`</strong> property.</p><blockquote><p><strong>&#128161; Pro tip:</strong> Always ask: <strong>&#8220;What object sits on the left side of the dot when the function is being called?&#8221;</strong></p></blockquote><p>We can say that <strong>`this</strong>` is not an author-time binding but a runtime binding.</p><p>It is contextual based on the conditions of the function&#8217;s invocation.</p><p>Apart from the mentioned example from above, there&#8217;re some other ways of how to manipulate the value of <strong>`this`</strong>.</p><p>Let&#8217;s explore them as well just for completeness.</p><h3>Example 3: Arrow Functions</h3><p>Arrow functions don&#8217;t get their own this.</p><p>Instead, they capture it from the surrounding scope.</p><pre><code>const knight = {
  name: 'Lancelot',
  salute: () =&gt; console.log(this.name)
};

knight.salute(); // undefined</code></pre><h3>Example 4: Explicit Binding</h3><p>We can explicitly set the value of <strong>`this`</strong> when we call a method.</p><p>This is called <strong>`binding`</strong> because we bind a specific value to <strong>`this`</strong>.</p><pre><code>function introduce() {
  console.log(`I am ${this.name}`);
}

const elf = { name: 'Legolas' };

introduce.call(elf); // I am Legolas</code></pre><p>As you see, in JavaScript, we can use <strong>`this`</strong> inside functions, not only classes.</p><div><hr></div><h2>The `new` Keyword</h2><p>In object-oriented languages like C# or Java, the <strong>`new`</strong> keyword is used to create a new instance of class.</p><p>However, in JavaScript, the behavior of the <strong>`new`</strong> keyword is slightly different, no matter there&#8217;re classes in the language.</p><p>In OO languages, using the <strong>`new`</strong> keyword will result in calling the constructor method of the class.</p><p>In JavaScript, we can simply use a function to create a new object.</p><pre><code>function Hero(name) {
    this.name = name;
}

const hero = new Hero("Gandalf");

console.log(hero.name); // "Gandalf"</code></pre><p>When we use the <strong>`new`</strong> keyword before a function, it will create a new object and bind the <strong>`this`</strong> inside the function to the newly created object.</p><p>Then, it will return the new object, if the function doesn&#8217;t return anything.</p><p>If the function returns an object, the above is not valid.</p><pre><code>function Person(name) {
  this.name = name;
  return { nickname: `The ${this.name}` };
}

const p = new Person("T-Shaped Dev");

console.log(p.nickname); // "The T-Shaped Dev"
console.log(p.name); // undefined</code></pre><p><strong>Note:</strong> Arrow functions can&#8217;t be used as constructors. They throw if you use <strong>`new`</strong>.</p><div><hr></div><h2>Note On Using `this` And `new`</h2><p>If you don&#8217;t want the headache of using <strong>`this`</strong> and <strong>`new`</strong>, you might prefer a more functional approach.</p><p>You can use closures to deal with <strong>`this`</strong> and factory functions to deal with <strong>`new`</strong>.</p><p>For instance:</p><pre><code>// Functional factory + Closure approach
function createCounter(start = 0) {
  let count = start;

  function increment() {
    count += 1;
    console.log(count);
  }

  function reset() {
    count = 0;
    console.log(count);
  }

  return { increment, reset };
}

const c2 = createCounter(5);

c2.increment(); // 6
c2.reset();     // 0</code></pre><div><hr></div><h2>Prototypes</h2><p>Objects in JavaScript have a <strong>`prototype`</strong> property which references another object.</p><p>So in JavaScript, we can build an <strong>inheritance object hierarchy</strong> through using Prototypes.</p><p>The other way of building such hierarchies is through Classes which are a syntax sugar over Prototypes.</p><p>Whenever you read a property of an object, it will first try to find it in the object itself.</p><p>If not found inside the object, it will look for it into the <strong>`prototype`</strong>.</p><p>If it&#8217;s not found there as well, it will check the <code>prototype</code>&#8217;s <code>prototype</code> and so on until it reaches the <code>Object.prototype</code>.</p><pre><code><code>const hero = {
  salute: () =&gt; console.log('Salute!')
};

const knight = {
  name: 'Knight',
  __proto__: hero
};

knight.salute();</code></code></pre><p>In this case, we set the <strong>`__proto__`</strong> property explicitly for the specific object.</p><p>To set up the inheritance chain, we can do it in the constructor function so every created object has the correct prototype.</p><pre><code>function Hero(name) {
    this.name = name;
    this.salute = function () {
        console.log(`${this.name}, Salute!`);
    }
}

function Knight(name) {
    this.name = name;
}

// create a reference for the prototype
Knight.prototype = new Hero();

const knight = new Knight("Lancelot");

knight.salute(); // Lancelot, Salute!</code></pre><p>By setting the <strong>`prototype`</strong> object to the constructor function, we ensure that all objects created through the <strong>`new`</strong> keyword will set up properly.</p><p><strong>Note:</strong> There are some other quirks around Prototypes in JavaScript, but I&#8217;ve found the shared notes above to be fundamental.</p><div><hr></div><h2>Classes</h2><p>ES6 introduced Classes which are a syntax sugar over Prototypes.</p><p>Nowadays, using Prototypes is discouraged because of the high complexity around setting up big inheritance hierarchies.</p><p>It&#8217;s most common to use Classes also because of the familiarity of people with other OO languages.</p><pre><code>class Hero {
  constructor(name) {
    this.name = name;
    this.salute = function () {
      console.log(`${this.name}, Salute!`);
    };
  }
}

class Knight extends Hero {
  constructor(name) {
    super(name)
  }
}

const knight = new Knight("Lancelot");

knight.salute(); // Lancelot, Salute!</code></pre><div><hr></div><h2>Composition</h2><p>Inheritance is a powerful tool to extend entities and create more complex object but it&#8217;s not ideal for all use cases.</p><p>Creating complex inheritance hierarchies is not trivial and most of the time we might end up with unnecessary complexity.</p><p>Personally, I think that the best way to create complex objects in JavaScript is through composition.</p><p>This way, we create objects with only what they need, they combine them to create a more complex ones.</p><pre><code>function canAttack(state) {
  return {
    attack: () =&gt; console.log(`${state.name} slashes!`)
  };
}

function canHeal(state) {
  return {
    heal: () =&gt; console.log(`${state.name} heals!`)
  };
}

function createPaladin(name) {
  const state = { name };
  return {
    ...canAttack(state),
    ...canHeal(state),
    name
  };
}

const paladin = createPaladin('Theron');

paladin.attack(); // Theron slashes!
paladin.heal();   // Theron heals!</code></pre><div><hr></div><h2>Performance Considerations About Inheritance</h2><p>It&#8217;s important to mention that if performance is critical to the app then defining a function to the prototype might be a better option, instead of creating a fresh new copy every time.</p><p>This means that the function will be created once and will leave on the shared prototype.</p><pre><code>function FastFighter(name) {
  this.name = name;

  // per-instance method
  this.attack = () =&gt; console.log(`${this.name} strikes fast!`);
}

// vs.

FastFighter.prototype.attack = function() {
  console.log(`${this.name} strikes fast!`);
};</code></pre><p>This can be helpful in some scenarios but might lead to problems if not used properly because we deal with references, instead of actual copies.</p><div><hr></div><h2><strong>&#128204; TL;DR</strong></h2><ul><li><p><strong>`this`</strong> is set by the call-site, not where a function lives.</p></li><li><p><strong>`new`</strong> creates a fresh new object, binds `this`, and returns it.</p></li><li><p><strong>Prototypes</strong> forms a chain, so objects can inherit missing properties.</p></li><li><p><strong>Classes</strong> are a syntax sugar over Prototypes.</p></li><li><p>Prefer <strong>composition to mix small behaviors</strong>, instead of deep and large hierarchies.</p></li><li><p>We can share code through using <strong>prototype methods</strong>, boosting performance.</p></li></ul><p>That's all for today. I hope this was helpful. &#9996;&#65039;</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://thetshaped.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Become a better Full-Stack JavaScript Engineer. Join 26,331 engineers who are improving their skills every week.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2><strong>How I can help you further?</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g6L_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png" width="528" height="297" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:528,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!g6L_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!g6L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F301ccf10-6eb8-4283-ba33-3399ec964f64_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><em><strong>Become a better and more skilled React Engineer! &#128640;</strong></em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://petarivanovv9.gumroad.com/l/jqcuh&quot;,&quot;text&quot;:&quot;Check the book out!&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://petarivanovv9.gumroad.com/l/jqcuh"><span>Check the book out!</span></a></p><div><hr></div><h2><strong>&#128075; Let&#8217;s connect</strong></h2><p>You can find me on <strong><a href="https://www.linkedin.com/in/petarivanovv9/">LinkedIn</a></strong>, <strong><a href="https://x.com/petarivanovv9">Twitter(X)</a></strong>,<strong> <a href="https://bsky.app/profile/petarivanovv9.bsky.social">Bluesky</a></strong>, or <strong><a href="https://www.threads.net/@petarivanovv9">Threads</a></strong>.</p><p>I share daily practical tips to level up your skills and become a better engineer.</p><p><em>Thank you for being a great supporter, reader, and for your help in growing to 26.3K+ subscribers this week &#128591;</em></p><div><hr></div><p><em>You can also hit the like &#10084;&#65039; button at the bottom to help support me or share this with a friend. It helps me a lot! &#128591;</em></p>]]></content:encoded></item></channel></rss>